You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by kn...@apache.org on 2001/07/24 20:33:47 UTC
cvs commit: xml-xerces/c/src/validators/schema XercesGroupInfo.cpp XercesGroupInfo.hpp ComplexTypeInfo.cpp ComplexTypeInfo.hpp SchemaElementDecl.cpp SchemaElementDecl.hpp SchemaGrammar.cpp SchemaGrammar.hpp TraverseSchema.cpp TraverseSchema.hpp
knoaman 01/07/24 11:33:47
Modified: c/src/validators/schema ComplexTypeInfo.cpp
ComplexTypeInfo.hpp SchemaElementDecl.cpp
SchemaElementDecl.hpp SchemaGrammar.cpp
SchemaGrammar.hpp TraverseSchema.cpp
TraverseSchema.hpp
Added: c/src/validators/schema XercesGroupInfo.cpp
XercesGroupInfo.hpp
Log:
Added support for <group> + extra constraint checking for complexType
Revision Changes Path
1.7 +5 -0 xml-xerces/c/src/validators/schema/ComplexTypeInfo.cpp
Index: ComplexTypeInfo.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/schema/ComplexTypeInfo.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- ComplexTypeInfo.cpp 2001/06/05 13:59:53 1.6
+++ ComplexTypeInfo.cpp 2001/07/24 18:33:46 1.7
@@ -56,6 +56,9 @@
/*
* $Log: ComplexTypeInfo.cpp,v $
+ * Revision 1.7 2001/07/24 18:33:46 knoaman
+ * Added support for <group> + extra constraint checking for complexType
+ *
* Revision 1.6 2001/06/05 13:59:53 knoaman
* Fixes to include and import.
*
@@ -101,6 +104,7 @@
, fContentSpec(0)
, fAttDefs(0)
, fAttList(0)
+ , fElements(0)
{
}
@@ -116,6 +120,7 @@
delete fAttDefs;
delete fAttList;
+ delete fElements;
}
// ---------------------------------------------------------------------------
1.5 +47 -1 xml-xerces/c/src/validators/schema/ComplexTypeInfo.hpp
Index: ComplexTypeInfo.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/schema/ComplexTypeInfo.hpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- ComplexTypeInfo.hpp 2001/07/17 14:51:54 1.4
+++ ComplexTypeInfo.hpp 2001/07/24 18:33:46 1.5
@@ -55,7 +55,7 @@
*/
/*
- * $Id: ComplexTypeInfo.hpp,v 1.4 2001/07/17 14:51:54 knoaman Exp $
+ * $Id: ComplexTypeInfo.hpp,v 1.5 2001/07/24 18:33:46 knoaman Exp $
*/
#if !defined(COMPLEXTYPEINFO_HPP)
@@ -73,6 +73,7 @@
// ---------------------------------------------------------------------------
#include <util/XMLString.hpp>
#include <util/RefHash2KeysTableOf.hpp>
+#include <util/RefVectorOf.hpp>
#include <framework/XMLElementDecl.hpp>
#include <validators/schema/SchemaAttDef.hpp>
@@ -83,6 +84,7 @@
class DatatypeValidator;
class ContentSpecNode;
class SchemaAttDefList;
+class SchemaElementDecl;
class VALIDATORS_EXPORT ComplexTypeInfo
@@ -105,6 +107,7 @@
int getScopeDefined() const;
unsigned int getElementId() const;
int getContentType() const;
+ unsigned int elementCount() const;
XMLCh* getTypeName() const;
DatatypeValidator* getBaseDatatypeValidator() const;
DatatypeValidator* getDatatypeValidator() const;
@@ -115,6 +118,9 @@
SchemaAttDef* getAttDef(const XMLCh* const baseName,
const int uriId);
XMLAttDefList& getAttDefList() const;
+ const SchemaElementDecl* elementAt(const unsigned int index) const;
+ SchemaElementDecl* elementAt(const unsigned int index);
+
// -----------------------------------------------------------------------
// Setter methods
@@ -133,6 +139,7 @@
void setBaseComplexTypeInfo(ComplexTypeInfo* const typeInfo);
void setContentSpec(ContentSpecNode* const toAdopt);
void addAttDef(SchemaAttDef* const toAdd);
+ void addElement(SchemaElementDecl* const toAdd);
// -----------------------------------------------------------------------
// Helper methods
@@ -182,6 +189,7 @@
ContentSpecNode* fContentSpec;
RefHash2KeysTableOf<SchemaAttDef>* fAttDefs;
SchemaAttDefList* fAttList;
+ RefVectorOf<SchemaElementDecl>* fElements;
};
// ---------------------------------------------------------------------------
@@ -227,6 +235,15 @@
return fContentType;
}
+inline unsigned int ComplexTypeInfo::elementCount() const {
+
+ if (fElements) {
+ return fElements->size();
+ }
+
+ return 0;
+}
+
inline XMLCh* ComplexTypeInfo::getTypeName() const {
return fTypeName;
@@ -272,6 +289,26 @@
return fAttDefs->get(baseName, uriId);
}
+inline SchemaElementDecl*
+ComplexTypeInfo::elementAt(const unsigned int index) {
+
+ if (!fElements) {
+ return 0; // REVISIT - need to throw an exception
+ }
+
+ return fElements->elementAt(index);
+}
+
+inline const SchemaElementDecl*
+ComplexTypeInfo::elementAt(const unsigned int index) const {
+
+ if (!fElements) {
+ return 0; // REVISIT - need to throw an exception
+ }
+
+ return fElements->elementAt(index);
+}
+
// ---------------------------------------------------------------------------
// ComplexTypeInfo: Setter methods
// ---------------------------------------------------------------------------
@@ -341,6 +378,15 @@
ComplexTypeInfo::setBaseComplexTypeInfo(ComplexTypeInfo* const typeInfo) {
fBaseComplexTypeInfo = typeInfo;
+}
+
+inline void ComplexTypeInfo::addElement(SchemaElementDecl* const elem) {
+
+ if (!fElements) {
+ fElements = new RefVectorOf<SchemaElementDecl>(8, false);
+ }
+
+ fElements->addElement(elem);
}
// ---------------------------------------------------------------------------
1.11 +5 -1 xml-xerces/c/src/validators/schema/SchemaElementDecl.cpp
Index: SchemaElementDecl.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/schema/SchemaElementDecl.cpp,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- SchemaElementDecl.cpp 2001/07/09 15:22:43 1.10
+++ SchemaElementDecl.cpp 2001/07/24 18:33:46 1.11
@@ -56,6 +56,9 @@
/*
* $Log: SchemaElementDecl.cpp,v $
+ * Revision 1.11 2001/07/24 18:33:46 knoaman
+ * Added support for <group> + extra constraint checking for complexType
+ *
* Revision 1.10 2001/07/09 15:22:43 knoaman
* complete <any> declaration.
*
@@ -142,7 +145,7 @@
setElementName(prefix, localPart, uriId);
}
-SchemaElementDecl::SchemaElementDecl(QName* const elementName
+SchemaElementDecl::SchemaElementDecl(const QName* const elementName
, const SchemaElementDecl::ModelTypes type
, const int enclosingScope
) :
@@ -165,6 +168,7 @@
{
delete [] fDefaultValue;
delete [] fSubstitutionGroupName;
+ delete [] fTypeFromAnotherSchemaURI;
delete fAttDefs;
}
1.9 +4 -1 xml-xerces/c/src/validators/schema/SchemaElementDecl.hpp
Index: SchemaElementDecl.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/schema/SchemaElementDecl.hpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- SchemaElementDecl.hpp 2001/06/13 20:51:15 1.8
+++ SchemaElementDecl.hpp 2001/07/24 18:33:46 1.9
@@ -56,6 +56,9 @@
/*
* $Log: SchemaElementDecl.hpp,v $
+ * Revision 1.9 2001/07/24 18:33:46 knoaman
+ * Added support for <group> + extra constraint checking for complexType
+ *
* Revision 1.8 2001/06/13 20:51:15 peiyongz
* fIsMixed: to handle mixed Content Model
*
@@ -136,7 +139,7 @@
SchemaElementDecl
(
- QName* const elementName
+ const QName* const elementName
, const ModelTypes modelType = Any
, const int enclosingScope = Grammar::TOP_LEVEL_SCOPE
);
1.5 +38 -1 xml-xerces/c/src/validators/schema/SchemaGrammar.cpp
Index: SchemaGrammar.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/schema/SchemaGrammar.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- SchemaGrammar.cpp 2001/06/25 12:51:56 1.4
+++ SchemaGrammar.cpp 2001/07/24 18:33:46 1.5
@@ -56,6 +56,9 @@
/*
* $Log: SchemaGrammar.cpp,v $
+ * Revision 1.5 2001/07/24 18:33:46 knoaman
+ * Added support for <group> + extra constraint checking for complexType
+ *
* Revision 1.4 2001/06/25 12:51:56 knoaman
* Add constraint checking on elements in complex types to prevent same
* element names from having different definitions - use substitueGroups.
@@ -78,12 +81,17 @@
#include <validators/schema/SchemaGrammar.hpp>
#include <validators/schema/NamespaceScope.hpp>
#include <validators/schema/ComplexTypeInfo.hpp>
+#include <validators/schema/SchemaSymbols.hpp>
+
// ---------------------------------------------------------------------------
// SchemaGrammar: Constructors and Destructor
// ---------------------------------------------------------------------------
SchemaGrammar::SchemaGrammar() :
- fElemDeclPool(0)
+ fElementDefaultQualified(false)
+ , fAttributeDefaultQualified(false)
+ , fElemDeclPool(0)
+ , fGroupElemDeclPool(0)
, fNotationDeclPool(0)
, fTargetNamespace(0)
, fAttributeDeclRegistry(0)
@@ -91,6 +99,7 @@
, fDatatypeRegistry(0)
, fNamespaceScope(0)
, fValidSubstitutionGroups(0)
+ , fGlobalGroups(0)
{
//
// Init all the pool members.
@@ -99,6 +108,7 @@
// pools.
//
fElemDeclPool = new RefHash3KeysIdPool<SchemaElementDecl>(109);
+ fGroupElemDeclPool = new RefHash3KeysIdPool<SchemaElementDecl>(109, false);
fNotationDeclPool = new NameIdPool<XMLNotationDecl>(109);
//
@@ -112,10 +122,12 @@
SchemaGrammar::~SchemaGrammar()
{
delete fElemDeclPool;
+ delete fGroupElemDeclPool;
delete fNotationDeclPool;
delete fTargetNamespace;
delete fAttributeDeclRegistry;
delete fComplexTypeRegistry;
+ delete fGlobalGroups;
delete fNamespaceScope;
delete fValidSubstitutionGroups;
}
@@ -136,6 +148,10 @@
// See it it exists
SchemaElementDecl* retVal = fElemDeclPool->getByKey(baseName, uriId, scope);
+ if (!retVal) {
+ retVal = fGroupElemDeclPool->getByKey(baseName, uriId, scope);
+ }
+
// if not, then add this in
if (!retVal)
{
@@ -157,5 +173,25 @@
// We need to reset all of the pools.
//
fElemDeclPool->removeAll();
+ fGroupElemDeclPool->removeAll();
fNotationDeclPool->removeAll();
+}
+
+DOM_Element SchemaGrammar::getGroupElement(const XMLCh* const name) {
+
+ if (fGlobalGroups) {
+
+ unsigned int groupSize = fGlobalGroups->size();
+
+ for (unsigned int i=0; i< groupSize; i++) {
+
+ DOM_Element elem = fGlobalGroups->elementAt(i);
+
+ if (elem.getAttribute(SchemaSymbols::fgATT_NAME).equals(name)) {
+ return elem;
+ }
+ }
+ }
+
+ return DOM_Element();
}
1.7 +110 -8 xml-xerces/c/src/validators/schema/SchemaGrammar.hpp
Index: SchemaGrammar.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/schema/SchemaGrammar.hpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- SchemaGrammar.hpp 2001/06/25 12:51:57 1.6
+++ SchemaGrammar.hpp 2001/07/24 18:33:46 1.7
@@ -56,6 +56,9 @@
/*
* $Log: SchemaGrammar.hpp,v $
+ * Revision 1.7 2001/07/24 18:33:46 knoaman
+ * Added support for <group> + extra constraint checking for complexType
+ *
* Revision 1.6 2001/06/25 12:51:57 knoaman
* Add constraint checking on elements in complex types to prevent same
* element names from having different definitions - use substitueGroups.
@@ -82,14 +85,14 @@
#if !defined(SCHEMAGRAMMAR_HPP)
#define SCHEMAGRAMMAR_HPP
-#include <dom/DOM_Document.hpp>
+#include <dom/DOM_Element.hpp>
#include <framework/XMLNotationDecl.hpp>
#include <util/RefHash3KeysIdPool.hpp>
#include <util/NameIdPool.hpp>
#include <util/StringPool.hpp>
#include <validators/common/Grammar.hpp>
#include <validators/schema/SchemaElementDecl.hpp>
-
+#include <util/ValueVectorOf.hpp>
//
// This class stores the Schema information
@@ -197,23 +200,39 @@
// -----------------------------------------------------------------------
// Getter methods
// -----------------------------------------------------------------------
+ bool getElementDefaultQualified() const;
+ bool getAttributeDefaultQualified() const;
RefHash3KeysIdPoolEnumerator<SchemaElementDecl> getElemEnumerator() const;
RefHashTableOf<XMLAttDef>* getAttributeDeclRegistry() const;
RefHashTableOf<ComplexTypeInfo>* getComplexTypeRegistry() const;
DatatypeValidatorFactory* getDatatypeRegistry() const;
NamespaceScope* getNamespaceScope() const;
RefHash2KeysTableOf<ElemVector>* getValidSubstitutionGroups() const;
+ DOM_Element getGroupElement(const XMLCh* const name);
// -----------------------------------------------------------------------
// Setter methods
// -----------------------------------------------------------------------
+ void setElementDefaultQualified(const bool toSet);
+ void setAttributeDefaultQualified(const bool toSet);
void setTargetNamespace(const XMLCh* const targetNamespace);
void setAttributeDeclRegistry(RefHashTableOf<XMLAttDef>* const attReg);
void setComplexTypeRegistry(RefHashTableOf<ComplexTypeInfo>* const other);
void setDatatypeRegistry(DatatypeValidatorFactory* const dvRegistry);
void setNamespaceScope(NamespaceScope* const nsScope);
void setValidSubstitutionGroups(RefHash2KeysTableOf<ElemVector>* const);
+ void addGlobalGroup(const DOM_Element& groupElem);
+ // -----------------------------------------------------------------------
+ // Helper methods
+ // -----------------------------------------------------------------------
+ unsigned int putGroupElemDecl
+ (
+ XMLElementDecl* const elemDecl
+ ) const;
+
+ void releaseGroupElement(unsigned int index);
+
private:
// -----------------------------------------------------------------------
@@ -225,6 +244,11 @@
// non-validating mode, its just populated as new elements are seen
// and they are given default characteristics.
//
+ // fGroupElemDeclPool
+ // This is the element decl pool for elements in a group that are
+ // referenced in different scope. It contains all of the elements
+ // declared in the Schema (and their associated attributes.)
+ //
// fNotationDeclPool
// This is a pool of NotationDecl objects, which contains all of the
// notations declared in the Schema.
@@ -247,7 +271,10 @@
// fValidSubstitutionGroups
// Valid list of elements that can substitute a given element
// -----------------------------------------------------------------------
+ bool fElementDefaultQualified;
+ bool fAttributeDefaultQualified;
RefHash3KeysIdPool<SchemaElementDecl>* fElemDeclPool;
+ RefHash3KeysIdPool<SchemaElementDecl>* fGroupElemDeclPool;
NameIdPool<XMLNotationDecl>* fNotationDeclPool;
XMLCh* fTargetNamespace;
RefHashTableOf<XMLAttDef>* fAttributeDeclRegistry;
@@ -255,12 +282,23 @@
DatatypeValidatorFactory* fDatatypeRegistry;
NamespaceScope* fNamespaceScope;
RefHash2KeysTableOf<ElemVector>* fValidSubstitutionGroups;
+ ValueVectorOf<DOM_Element>* fGlobalGroups;
};
// ---------------------------------------------------------------------------
// SchemaGrammar: Getter methods
// ---------------------------------------------------------------------------
+inline bool SchemaGrammar::getElementDefaultQualified() const {
+
+ return fElementDefaultQualified;
+}
+
+inline bool SchemaGrammar::getAttributeDefaultQualified() const {
+
+ return fAttributeDefaultQualified;
+}
+
inline RefHash3KeysIdPoolEnumerator<SchemaElementDecl>
SchemaGrammar::getElemEnumerator() const
{
@@ -297,6 +335,16 @@
// -----------------------------------------------------------------------
// Setter methods
// -----------------------------------------------------------------------
+inline void SchemaGrammar::setElementDefaultQualified(const bool toSet) {
+
+ fElementDefaultQualified = toSet;
+}
+
+inline void SchemaGrammar::setAttributeDefaultQualified(const bool toSet) {
+
+ fAttributeDefaultQualified = toSet;
+}
+
inline void SchemaGrammar::setTargetNamespace(const XMLCh* const targetNamespace) {
fTargetNamespace = XMLString::replicate(targetNamespace);
}
@@ -330,6 +378,29 @@
fValidSubstitutionGroups = other;
}
+inline void
+SchemaGrammar::addGlobalGroup(const DOM_Element& groupElem) {
+
+ if (!fGlobalGroups) {
+ fGlobalGroups = new ValueVectorOf<DOM_Element>(8);
+ }
+
+ fGlobalGroups->addElement(groupElem);
+}
+
+
+// ---------------------------------------------------------------------------
+// SchemaGrammar: Helper methods
+// ---------------------------------------------------------------------------
+inline void SchemaGrammar::releaseGroupElement(unsigned int index) {
+
+ if (!fGlobalGroups || index < 0 || fGlobalGroups->size() <= index) {
+ return;
+ }
+
+ fGlobalGroups->setElementAt(DOM_Element(), index);
+}
+
// ---------------------------------------------------------------------------
// SchemaGrammar: Virtual methods
// ---------------------------------------------------------------------------
@@ -352,8 +423,13 @@
// map it to the official not found value if we don't find it.
//
const SchemaElementDecl* decl = fElemDeclPool->getByKey(baseName, uriId, scope);
- if (!decl)
- return XMLElementDecl::fgInvalidElemId;
+ if (!decl) {
+
+ decl = fGroupElemDeclPool->getByKey(baseName, uriId, scope);
+
+ if (!decl)
+ return XMLElementDecl::fgInvalidElemId;
+ }
return decl->getId();
}
@@ -362,7 +438,12 @@
, const XMLCh* const qName
, unsigned int scope ) const
{
- return fElemDeclPool->getByKey(baseName, uriId, scope);
+ const SchemaElementDecl* decl = fElemDeclPool->getByKey(baseName, uriId, scope);
+
+ if (!decl)
+ decl = fGroupElemDeclPool->getByKey(baseName, uriId, scope);
+
+ return decl;
}
inline XMLElementDecl* SchemaGrammar::getElemDecl (const unsigned int uriId
@@ -370,24 +451,44 @@
, const XMLCh* const qName
, unsigned int scope )
{
- return fElemDeclPool->getByKey(baseName, uriId, scope);
+ SchemaElementDecl* decl = fElemDeclPool->getByKey(baseName, uriId, scope);
+
+ if (!decl)
+ decl = fGroupElemDeclPool->getByKey(baseName, uriId, scope);
+
+ return decl;
}
inline const XMLElementDecl* SchemaGrammar::getElemDecl(const unsigned int elemId) const
{
// Look up this element decl by id
- return fElemDeclPool->getById(elemId);
+ const SchemaElementDecl* decl = fElemDeclPool->getById(elemId);
+
+ if (!decl)
+ decl = fGroupElemDeclPool->getById(elemId);
+
+ return decl;
}
inline XMLElementDecl* SchemaGrammar::getElemDecl(const unsigned int elemId)
{
// Look up this element decl by id
- return fElemDeclPool->getById(elemId);
+ SchemaElementDecl* decl = fElemDeclPool->getById(elemId);
+
+ if (!decl)
+ decl = fGroupElemDeclPool->getById(elemId);
+
+ return decl;
}
inline unsigned int SchemaGrammar::putElemDecl (XMLElementDecl* const elemDecl) const
{
return fElemDeclPool->put(elemDecl->getBaseName(), elemDecl->getURI(), ((SchemaElementDecl* )elemDecl)->getEnclosingScope(), (SchemaElementDecl*) elemDecl);
+}
+
+inline unsigned int SchemaGrammar::putGroupElemDecl (XMLElementDecl* const elemDecl) const
+{
+ return fGroupElemDeclPool->put(elemDecl->getBaseName(), elemDecl->getURI(), ((SchemaElementDecl* )elemDecl)->getEnclosingScope(), (SchemaElementDecl*) elemDecl);
}
// Notation Decl
1.32 +833 -237 xml-xerces/c/src/validators/schema/TraverseSchema.cpp
Index: TraverseSchema.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/schema/TraverseSchema.cpp,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- TraverseSchema.cpp 2001/07/18 13:30:14 1.31
+++ TraverseSchema.cpp 2001/07/24 18:33:46 1.32
@@ -55,105 +55,7 @@
*/
/*
- * $Log: TraverseSchema.cpp,v $
- * Revision 1.31 2001/07/18 13:30:14 knoaman
- * no message
- *
- * Revision 1.30 2001/07/12 15:32:57 knoaman
- * Added constraint checking for simple types (list/union).
- *
- * Revision 1.29 2001/07/10 18:12:53 knoaman
- * Modified the 'throw' in complexType processing.
- *
- * Revision 1.28 2001/07/09 20:07:49 knoaman
- * Added <element> constraint checking.
- *
- * Revision 1.27 2001/07/09 15:22:45 knoaman
- * complete <any> declaration.
- *
- * Revision 1.26 2001/07/09 14:29:44 knoaman
- * Fixes for import/include declarations
- *
- * Revision 1.25 2001/06/25 12:51:58 knoaman
- * Add constraint checking on elements in complex types to prevent same
- * element names from having different definitions - use substitueGroups.
- *
- * Revision 1.24 2001/06/20 15:07:04 knoaman
- * Fix for 'fixed' attribute on facets - wrong string comparison.
- *
- * Revision 1.23 2001/06/18 19:52:18 knoaman
- * Add support for 'fixed' facet.
- *
- * Revision 1.22 2001/06/15 22:55:53 knoaman
- * Added constraint checking for ref on elements.
- *
- * Revision 1.21 2001/06/14 21:03:48 knoaman
- * Changed ref on elements to traverse the actual element decl, instead of just returning the qname.
- *
- * Revision 1.20 2001/06/11 15:17:22 knoaman
- * StringTokenizer renamed to XMLStringTokenizer.
- *
- * Revision 1.19 2001/06/07 14:38:02 knoaman
- * Bypass for now generating an error message in case of ID/IDREF/Entity(s)
- * datatype validators is not found. Currently taken care of by the validator.
- *
- * Revision 1.18 2001/06/06 21:16:13 knoaman
- * Display error when 'whiteSpace' facet value is not collapse.
- *
- * Revision 1.17 2001/06/05 15:21:15 knoaman
- * Display error when attribute type is not found.
- *
- * Revision 1.16 2001/06/05 13:59:54 knoaman
- * Fixes to include and import.
- *
- * Revision 1.15 2001/05/30 21:13:50 knoaman
- * Typo fix
- *
- * Revision 1.14 2001/05/30 17:38:28 knoaman
- * o Reset fScopeCount after traversing complexType.
- * o Fix problem of deleting ContentSpecNode prematurely
- * when composing final content model of a child complex type.
- *
- * Revision 1.13 2001/05/29 19:37:37 knoaman
- * Added substitution group constraint checking.
- *
- * Revision 1.12 2001/05/28 21:11:21 tng
- * Schema: Various DatatypeValidator fix. By Pei Yong Zhang
- *
- * Revision 1.11 2001/05/22 19:22:45 knoaman
- * Added checking for element declaration value constraint (default/fixed).
- *
- * Revision 1.10 2001/05/18 17:04:45 knoaman
- * Typo fix.
- *
- * Revision 1.9 2001/05/18 16:51:39 knoaman
- * Added circular check for complexType + more error messages.
- *
- * Revision 1.8 2001/05/17 21:15:08 knoaman
- * Added circular checking for simple types.
- *
- * Revision 1.7 2001/05/17 18:11:18 knoaman
- * More constraint and attribute checking.
- *
- * Revision 1.6 2001/05/15 21:59:39 knoaman
- * TraverseSchema: add attribute checking + some fixes + more error messages.
- * More attribute cheking to come.
- *
- * Revision 1.5 2001/05/11 21:51:19 knoaman
- * Schema updates and fixes.
- *
- * Revision 1.4 2001/05/11 13:27:38 tng
- * Copyright update.
- *
- * Revision 1.3 2001/05/10 17:49:44 tng
- * Schema: SchemaValidator fixes
- *
- * Revision 1.2 2001/05/10 16:33:17 knoaman
- * Traverse Schema Part III + error messages.
- *
- * Revision 1.1 2001/05/03 19:18:06 knoaman
- * TraverseSchema Part II.
- *
+ * $Id: TraverseSchema.cpp,v 1.32 2001/07/24 18:33:46 knoaman Exp $
*/
// ---------------------------------------------------------------------------
@@ -192,6 +94,7 @@
#include <validators/datatype/InvalidDatatypeValueException.hpp>
#include <validators/datatype/InvalidDatatypeFacetException.hpp>
#include <validators/schema/GeneralAttributeCheck.hpp>
+#include <validators/schema/XercesGroupInfo.hpp>
// ---------------------------------------------------------------------------
// TraverseSchema: Local declaration
@@ -204,6 +107,7 @@
// ---------------------------------------------------------------------------
XMLStringPool TraverseSchema::fStringPool;
+
// ---------------------------------------------------------------------------
// TraverseSchema: Local const data
// ---------------------------------------------------------------------------
@@ -248,6 +152,11 @@
chDigit_1, chNull
};
+const XMLCh fgValueZero[] =
+{
+ chDigit_0, chNull
+};
+
// ---------------------------------------------------------------------------
// TraverseSchema: Constructors and Destructor
// ---------------------------------------------------------------------------
@@ -277,6 +186,7 @@
, fDatatypeRegistry(0)
, fGrammarResolver(grammarResolver)
, fSchemaGrammar(schemaGrammar)
+ , fRefSchemaGrammar(0)
, fEntityResolver(entityResolver)
, fErrorHandler(errorHandler)
, fURIStringPool(uriStringPool)
@@ -285,13 +195,18 @@
, fNamespaceScope(0)
, fAttributeDeclRegistry(0)
, fComplexTypeRegistry(0)
+ , fGroupRegistry(0)
, fSchemaInfoRoot(0)
, fCurrentSchemaInfo(0)
+ , fCurrentGroupInfo(0)
+ , fCurrentComplexType(0)
, fImportLocations(importLocations)
, fIncludeLocations(0)
, fCurrentTypeNameStack(0)
+ , fCurrentGroupStack(0)
, fAttributeCheck(0)
, fGlobalTypes(0)
+ , fGlobalGroups(0)
, fSubstitutionGroups(0)
, fValidSubstitutionGroups(0)
, fRefElements(0)
@@ -340,10 +255,13 @@
fIncludeLocations->addElement(schemaURLId);
fAttributeCheck = GeneralAttributeCheck::instance();
fCurrentTypeNameStack = new ValueVectorOf<unsigned int>(8);
+ fCurrentGroupStack = new ValueVectorOf<unsigned int>(8);
fGlobalTypes = new RefHash2KeysTableOf<XMLCh>(29, false);
+ fGlobalGroups = new RefHash2KeysTableOf<XMLCh>(29, false);
fSubstitutionGroups = new RefHash2KeysTableOf<SchemaElementDecl>(29, false);
fRefElements = new RefVectorOf<SchemaElementDecl>(32, false);
fRefElemScope = new ValueVectorOf<int>(32);
+ fGroupRegistry = new RefHashTableOf<XercesGroupInfo>(29);
//Make sure namespace binding is defaulted
DOMString rootPrefix = fSchemaRootElement.getPrefix();
@@ -452,6 +370,9 @@
fAttributeDefaultQualified =
fSchemaRootElement.getAttribute(SchemaSymbols::fgATT_ATTRIBUTEFORMDEFAULT).equals(SchemaSymbols::fgATTVAL_QUALIFIED);
+ fSchemaGrammar->setElementDefaultQualified(fElementDefaultQualified);
+ fSchemaGrammar->setAttributeDefaultQualified(fAttributeDefaultQualified);
+
// Get finalDefault/blockDefault values
const XMLCh* defaultVal = getElementAttValue(fSchemaRootElement,
SchemaSymbols::fgATT_BLOCKDEFAULT);
@@ -666,13 +587,13 @@
}
SchemaGrammar* importedGrammar = 0;
-
+
if (nameSpace) {
- importedGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(nameSpace);
+ importedGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(nameSpace);
if (importedGrammar) {
- return;
+ return;
}
}
@@ -747,7 +668,7 @@
if (XMLString::compareString(targetNSURIString, nameSpace) != 0) {
reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ImportNamespaceDifference,
- schemaLocation, targetNSURIString, nameSpace);
+ schemaLocation, targetNSURIString, nameSpace);
}
else {
@@ -784,7 +705,8 @@
*/
ContentSpecNode*
TraverseSchema::traverseChoiceSequence(const DOM_Element& elem,
- const int modelGroupType)
+ const int modelGroupType,
+ bool& toAdoptSpecNode)
{
// ------------------------------------------------------------------
@@ -800,11 +722,15 @@
ContentSpecNode* left = 0;
ContentSpecNode* right = 0;
bool hadContent = false;
+ bool toAdoptLeft = true;
+ bool toAdoptRight = true;
for (; child != 0; child = XUtil::getNextSiblingElement(child)) {
ContentSpecNode* contentSpecNode = 0;
+ ContentSpecNode* expandedSpecNode = 0;
bool seeParticle = false;
+ bool adoptSpecNode = true;
DOMString childName = child.getLocalName();
hadContent = true;
@@ -823,22 +749,33 @@
}
else if (childName.equals(SchemaSymbols::fgELT_GROUP)) {
- contentSpecNode = 0/*traverseGroupDecl(child)*/;
+ XercesGroupInfo* grpInfo = traverseGroupDecl(child, adoptSpecNode);
- if (contentSpecNode == 0)
- continue;
+ if (grpInfo) {
+
+ contentSpecNode = grpInfo->getContentSpec();
+
+ if (contentSpecNode == 0)
+ continue;
+ if (hasAllContent(contentSpecNode)) {
+
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AllContentLimited);
+ continue;
+ }
+ }
+
seeParticle = true;
}
else if (childName.equals(SchemaSymbols::fgELT_CHOICE)) {
contentSpecNode =
- traverseChoiceSequence(child,ContentSpecNode::Choice);
+ traverseChoiceSequence(child,ContentSpecNode::Choice, adoptSpecNode);
seeParticle = true;
}
else if (childName.equals(SchemaSymbols::fgELT_SEQUENCE)) {
contentSpecNode =
- traverseChoiceSequence(child,ContentSpecNode::Sequence);
+ traverseChoiceSequence(child,ContentSpecNode::Sequence, adoptSpecNode);
seeParticle = true;
}
else if (childName.equals(SchemaSymbols::fgELT_ANY)) {
@@ -853,27 +790,42 @@
}
if (seeParticle) {
- contentSpecNode = expandContentModel(contentSpecNode, child);
+
+ expandedSpecNode = expandContentModel(contentSpecNode, child,
+ Not_All_Context, adoptSpecNode);
+
+ if (expandedSpecNode != contentSpecNode) {
+ adoptSpecNode = true;
+ }
}
+ else {
+ expandedSpecNode = contentSpecNode;
+ }
if (left == 0) {
- left = contentSpecNode;
+ left = expandedSpecNode;
+ toAdoptLeft = adoptSpecNode;
}
else if (right == 0) {
- right = contentSpecNode;
+ right = expandedSpecNode;
+ toAdoptRight = adoptSpecNode;
}
else {
left = new ContentSpecNode((ContentSpecNode::NodeTypes) modelGroupType,
- left, right);
- right = contentSpecNode;
+ left, right, toAdoptLeft, toAdoptRight);
+ right = expandedSpecNode;
+ toAdoptLeft = true;
+ toAdoptRight = adoptSpecNode;
}
}
if (hadContent && right != 0) {
- left = new ContentSpecNode((ContentSpecNode::NodeTypes) modelGroupType,
- left, right);
+ left = new ContentSpecNode((ContentSpecNode::NodeTypes) modelGroupType,
+ left, right, toAdoptLeft, toAdoptRight);
+ toAdoptLeft = true;
}
+ toAdoptSpecNode = toAdoptLeft;
return left;
}
@@ -1043,20 +995,20 @@
fBuffer.append(chComma);
fBuffer.append(name);
+ XMLCh* fullName = fBuffer.getRawBuffer();
if (topLevel) {
- ComplexTypeInfo* temp = fComplexTypeRegistry->get(fBuffer.getRawBuffer());
+ ComplexTypeInfo* temp = fComplexTypeRegistry->get(fullName);
if (temp != 0 ) {
- return fStringPool.addOrFind(fBuffer.getRawBuffer());
+ return fStringPool.addOrFind(fullName);
}
}
ComplexTypeInfo* typeInfo = new ComplexTypeInfo();
- int typeNameIndex = fStringPool.addOrFind(fBuffer.getRawBuffer());
- int scopeDefined = fScopeCount++;
+ int typeNameIndex = fStringPool.addOrFind(fullName);
int previousScope = fCurrentScope;
- fCurrentScope = scopeDefined;
+ fCurrentScope = fScopeCount++;
// ------------------------------------------------------------------
// First, handle any ANNOTATION declaration and get next child
@@ -1070,10 +1022,17 @@
// Register the type first, so that in case of a recursive element type
// declaration, we can retrieve the complexType info (though the rest of
// complex type information has not been added).
- fComplexTypeRegistry->put((void*) fStringPool.getValueForId(typeNameIndex),
+ RefHashTableOf<ComplexTypeInfo>* complexTypeRegistry =
+ (topLevel || !fRefSchemaGrammar) ? fComplexTypeRegistry
+ : fRefSchemaGrammar->getComplexTypeRegistry();
+
+ complexTypeRegistry->put((void*) fStringPool.getValueForId(typeNameIndex),
typeInfo);
- typeInfo->setTypeName(fBuffer.getRawBuffer());
- fCurrentTypeNameStack->addElement(fStringPool.addOrFind(name));
+ typeInfo->setTypeName(fullName);
+ typeInfo->setScopeDefined(fCurrentScope);
+ fCurrentTypeNameStack->addElement(typeNameIndex);
+ ComplexTypeInfo* saveTypeInfo = fCurrentComplexType;
+ fCurrentComplexType = typeInfo;
// ------------------------------------------------------------------
// Process the content of the complex type declaration
@@ -1089,8 +1048,9 @@
const XMLCh* mixedVal = getElementAttValue(elem,SchemaSymbols::fgATT_MIXED);
bool isMixed = false;
- if (XMLString::stringLen(mixedVal) != 0
- && XMLString::compareString(SchemaSymbols::fgATTVAL_TRUE, mixedVal) == 0) {
+ if (XMLString::stringLen(mixedVal)
+ && (!XMLString::compareString(SchemaSymbols::fgATTVAL_TRUE, mixedVal)
+ || !XMLString::compareString(fgValueOne, mixedVal))) {
isMixed = true;
}
@@ -1135,10 +1095,10 @@
typeInfo->setBlockSet(blockSet);
typeInfo->setFinalSet(finalSet);
- typeInfo->setScopeDefined(scopeDefined);
- if (XMLString::stringLen(abstractAttVal) != 0
- && XMLString::compareString(abstractAttVal, SchemaSymbols::fgATTVAL_TRUE) == 0) {
+ if (XMLString::stringLen(abstractAttVal)
+ && (!XMLString::compareString(abstractAttVal, SchemaSymbols::fgATTVAL_TRUE)
+ || !XMLString::compareString(abstractAttVal, fgValueOne))) {
typeInfo->setAbstract(true);
}
else {
@@ -1149,19 +1109,289 @@
// Before exiting, restore the scope, mainly for nested anonymous types
// ------------------------------------------------------------------
fCurrentScope = previousScope;
+ fCurrentComplexType = saveTypeInfo;
resetCurrentTypeNameStack(0);
return typeNameIndex;
}
-ContentSpecNode*
-TraverseSchema::traverseGroupDecl(const DOM_Element& childElem) {
+/**
+ * Traverse Group Declaration.
+ *
+ * <group
+ * id = ID
+ * maxOccurs = string
+ * minOccurs = nonNegativeInteger
+ * name = NCName
+ * ref = QName>
+ * Content: (annotation? , (all | choice | sequence)?)
+ * <group/>
+ *
+ */
+XercesGroupInfo*
+TraverseSchema::traverseGroupDecl(const DOM_Element& elem,
+ bool& toAdoptSpecNode) {
- // TO DO
- return 0;
+ bool topLevel = isTopLevelComponent(elem);
+ const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME);
+ const XMLCh* ref = getElementAttValue(elem, SchemaSymbols::fgATT_REF);
+ bool nameEmpty = (XMLString::stringLen(name) == 0) ? true : false;
+ bool refEmpty = (XMLString::stringLen(ref) == 0) ? true : false;
+
+ if (nameEmpty && topLevel) {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoNameGlobalElement,
+ SchemaSymbols::fgELT_GROUP);
+ return 0;
+ }
+
+ if (nameEmpty && refEmpty) {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoNameRefGroup);
+ return 0;
+ }
+
+ // ------------------------------------------------------------------
+ // Check attributes
+ // ------------------------------------------------------------------
+ unsigned short scope = (topLevel) ? GeneralAttributeCheck::GlobalContext
+ : GeneralAttributeCheck::LocalContext;
+ fAttributeCheck->checkAttributes(elem, scope, this);
+
+ // ------------------------------------------------------------------
+ // Check for annotations
+ // ------------------------------------------------------------------
+ DOM_Element content = checkContent(elem, XUtil::getFirstChildElement(elem),
+ true);
+
+ // ------------------------------------------------------------------
+ // Handle "ref="
+ // ------------------------------------------------------------------
+ if (nameEmpty || (!refEmpty && !topLevel)) {
+
+ if (!nameEmpty) {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::GroupWithNameRef, name);
+ }
+
+ return processGroupRef(elem, ref, toAdoptSpecNode);
+ }
+
+ // ------------------------------------------------------------------
+ // Process contents of global groups
+ // ------------------------------------------------------------------
+ // name must be a valid NCName
+ if (!XMLString::isValidNCName(name)) {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidGroupName, name);
+ return 0;
+ }
+
+ fBuffer.set(fTargetNSURIString);
+ fBuffer.append(chComma);
+ fBuffer.append(name);
+
+ unsigned int fullNameIndex = fStringPool.addOrFind(fBuffer.getRawBuffer());
+ const XMLCh* fullName = fStringPool.getValueForId(fullNameIndex);
+ ContentSpecNode* specNode = 0;
+ XercesGroupInfo* saveGroupInfo = fCurrentGroupInfo;
+ XercesGroupInfo* groupInfo = new XercesGroupInfo();
+
+ fCurrentGroupStack->addElement(fullNameIndex);
+ fCurrentGroupInfo = groupInfo;
+ fCurrentGroupInfo->setScope(fCurrentScope);
+
+ if (content == 0) {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::GroupContentError, name);
+ }
+ else {
+
+ if (elem.getAttributeNode(SchemaSymbols::fgATT_MINOCCURS) != 0
+ || elem.getAttributeNode(SchemaSymbols::fgATT_MAXOCCURS) != 0) {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::MinMaxOnGroupChild);
+ }
+
+ bool illegalChild = false;
+ bool adoptSpecNode = true;
+ DOMString childName = content.getLocalName();
+
+ if (childName.equals(SchemaSymbols::fgELT_SEQUENCE)) {
+ specNode = traverseChoiceSequence(content, ContentSpecNode::Sequence, adoptSpecNode);
+ }
+ else if (childName.equals(SchemaSymbols::fgELT_CHOICE)) {
+ specNode = traverseChoiceSequence(content, ContentSpecNode::Choice, adoptSpecNode);
+ }
+ else if (childName.equals(SchemaSymbols::fgELT_ALL)) {
+ // TO DO
+ }
+ else {
+ illegalChild = true;
+ }
+
+ if (illegalChild || XUtil::getNextSiblingElement(content) != 0) {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::GroupContentError, name);
+ }
+
+ toAdoptSpecNode = adoptSpecNode;
+ }
+
+ // ------------------------------------------------------------------
+ // Set groupInfo and pop group name from stack
+ // ------------------------------------------------------------------
+ unsigned int stackSize = fCurrentGroupStack->size();
+
+ if (stackSize != 0) {
+ fCurrentGroupStack->removeElementAt(stackSize - 1);
+ }
+
+ fCurrentGroupInfo->setContentSpec(specNode);
+ fGroupRegistry->put((void*) fullName, fCurrentGroupInfo);
+ fCurrentGroupInfo = saveGroupInfo;
+
+ return groupInfo;
+}
+
+XercesGroupInfo*
+TraverseSchema::traverseGroupDeclNS(const XMLCh* const uriStr,
+ const XMLCh* const groupName,
+ bool& toAdoptSpecNode) {
+
+ // ------------------------------------------------------------------
+ // Get grammar information
+ // ------------------------------------------------------------------
+ SchemaGrammar* aGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(uriStr);
+
+ if (!aGrammar || aGrammar->getGrammarType() != Grammar::SchemaGrammarType) {
+
+ reportSchemaError(XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, uriStr);
+ return 0;
+ }
+
+ // ------------------------------------------------------------------
+ // Save current grammar
+ // ------------------------------------------------------------------
+ bool saveElemDefaultQualified = fElementDefaultQualified;
+ bool saveAttrDefaultQualified = fAttributeDefaultQualified;
+ int saveTargetNSURI = fTargetNSURI;
+ SchemaGrammar* saveSchemaGrammar = fSchemaGrammar;
+ SchemaGrammar* saveRefSchemaGrammar = fRefSchemaGrammar;
+ NamespaceScope* saveNamespaceScope = fNamespaceScope;
+ RefHashTableOf<XMLAttDef>* saveAttDeclRegistry = fAttributeDeclRegistry;
+ RefHashTableOf<ComplexTypeInfo>* saveComplexTypeRegistry = fComplexTypeRegistry;
+ XMLCh* saveTargetNSURIString = fTargetNSURIString;
+ ArrayJanitor<XMLCh> janNSURIStr(saveTargetNSURIString);
+
+ // ------------------------------------------------------------------
+ // Switch grammar info
+ // ------------------------------------------------------------------
+ if (!fRefSchemaGrammar) {
+ fRefSchemaGrammar = fSchemaGrammar;
+ }
+
+ fSchemaGrammar = aGrammar;
+ fElementDefaultQualified = aGrammar->getElementDefaultQualified();
+ fAttributeDefaultQualified = aGrammar->getAttributeDefaultQualified();
+ fNamespaceScope = aGrammar->getNamespaceScope();
+ fAttributeDeclRegistry = aGrammar->getAttributeDeclRegistry();
+ fComplexTypeRegistry = aGrammar->getComplexTypeRegistry();
+ fTargetNSURIString = XMLString::replicate(aGrammar->getTargetNamespace());
+ fTargetNSURI = fURIStringPool->addOrFind(fTargetNSURIString);
+
+ // ------------------------------------------------------------------
+ // Get element info
+ // ------------------------------------------------------------------
+ DOM_Element elem = aGrammar->getGroupElement(groupName);
+
+ if (elem == 0) {
+ return 0;
+ }
+
+ // ------------------------------------------------------------------
+ // Create group info
+ // ------------------------------------------------------------------
+ fBuffer.set(uriStr);
+ fBuffer.append(chComma);
+ fBuffer.append(groupName);
+
+ unsigned int fullNameIndex = fStringPool.addOrFind(fBuffer.getRawBuffer());
+ const XMLCh* fullName = fStringPool.getValueForId(fullNameIndex);
+ ContentSpecNode* specNode = 0;
+ XercesGroupInfo* saveGroupInfo = fCurrentGroupInfo;
+ XercesGroupInfo* groupInfo = new XercesGroupInfo();
+
+ fCurrentGroupStack->addElement(fullNameIndex);
+ fCurrentGroupInfo = groupInfo;
+ fCurrentGroupInfo->setScope(fCurrentScope);
+
+ // ------------------------------------------------------------------
+ // Check for annotations
+ // ------------------------------------------------------------------
+ DOM_Element content = checkContent(elem, XUtil::getFirstChildElement(elem),
+ true);
+
+ if (content == 0) {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::GroupContentError, groupName);
+ }
+ else {
+
+ if (elem.getAttributeNode(SchemaSymbols::fgATT_MINOCCURS) != 0
+ || elem.getAttributeNode(SchemaSymbols::fgATT_MAXOCCURS) != 0) {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::MinMaxOnGroupChild);
+ }
+
+ bool illegalChild = false;
+ bool adoptSpecNode = true;
+ DOMString childName = content.getLocalName();
+
+ if (childName.equals(SchemaSymbols::fgELT_SEQUENCE)) {
+ specNode = traverseChoiceSequence(content, ContentSpecNode::Sequence, adoptSpecNode);
+ }
+ else if (childName.equals(SchemaSymbols::fgELT_CHOICE)) {
+ specNode = traverseChoiceSequence(content, ContentSpecNode::Choice, adoptSpecNode);
+ }
+ else if (childName.equals(SchemaSymbols::fgELT_ALL)) {
+ // TO DO
+ }
+ else {
+ illegalChild = true;
+ }
+
+ if (illegalChild || XUtil::getNextSiblingElement(content) != 0) {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::GroupContentError, groupName);
+ }
+
+ toAdoptSpecNode = adoptSpecNode;
+ }
+
+
+ // ------------------------------------------------------------------
+ // Restore grammar info
+ // ------------------------------------------------------------------
+ delete [] fTargetNSURIString;
+ fElementDefaultQualified = saveElemDefaultQualified;
+ fAttributeDefaultQualified = saveAttrDefaultQualified;
+ fTargetNSURI = saveTargetNSURI;
+ fSchemaGrammar = saveSchemaGrammar;
+ fRefSchemaGrammar = saveRefSchemaGrammar;
+ fNamespaceScope = saveNamespaceScope;
+ fAttributeDeclRegistry = saveAttDeclRegistry;
+ fComplexTypeRegistry = saveComplexTypeRegistry;
+ fTargetNSURIString = janNSURIStr.release();
+
+ // ------------------------------------------------------------------
+ // Set groupInfo and pop group name from stack
+ // ------------------------------------------------------------------
+ unsigned int stackSize = fCurrentGroupStack->size();
+
+ if (stackSize != 0) {
+ fCurrentGroupStack->removeElementAt(stackSize - 1);
+ }
+
+ fCurrentGroupInfo->setContentSpec(specNode);
+ fGroupRegistry->put((void*) fullName, fCurrentGroupInfo);
+ fCurrentGroupInfo = saveGroupInfo;
+
+ return groupInfo;
}
+
/**
* Traverse Any declaration
*
@@ -1662,9 +1892,17 @@
try {
dv->validate(valueToCheck);
}
+ catch(const InvalidDatatypeValueException& idve) {
+ reportSchemaError(XMLUni::fgValidityDomain,
+ XMLValid::DisplayErrorMessage, idve.getMessage());
+ }
+ catch (const InvalidDatatypeFacetException& idfe) {
+ reportSchemaError(XMLUni::fgValidityDomain,
+ XMLValid::DisplayErrorMessage, idfe.getMessage());
+ }
catch(...) {
- reportSchemaError(XMLUni::fgXMLErrDomain,
- XMLErrs::DatatypeValidationFailure, valueToCheck);
+ reportSchemaError(XMLUni::fgValidityDomain,
+ XMLValid::DatatypeValidationFailure, valueToCheck);
}
}
@@ -1818,7 +2056,23 @@
}
if (!isDuplicate) {
- fSchemaGrammar->putElemDecl(elemDecl);
+
+ if (topLevel || !fRefSchemaGrammar) {
+ fSchemaGrammar->putElemDecl(elemDecl);
+ }
+ else {
+ fRefSchemaGrammar->putElemDecl(elemDecl);
+ }
+
+ if (fCurrentGroupInfo &&
+ elemDecl->getEnclosingScope() == fCurrentGroupInfo->getScope()) {
+ fCurrentGroupInfo->addElement(elemDecl);
+ }
+
+ if (fCurrentComplexType &&
+ elemDecl->getEnclosingScope() == fCurrentComplexType->getScopeDefined()) {
+ fCurrentComplexType->addElement(elemDecl);
+ }
}
// Resolve the type for the element
@@ -2026,11 +2280,18 @@
validator->validate(deflt);
}
}
+ catch(const InvalidDatatypeValueException& idve) {
+ reportSchemaError(XMLUni::fgValidityDomain,
+ XMLValid::DisplayErrorMessage, idve.getMessage());
+ }
+ catch (const InvalidDatatypeFacetException& idfe) {
+ reportSchemaError(XMLUni::fgValidityDomain,
+ XMLValid::DisplayErrorMessage, idfe.getMessage());
+ }
catch(...) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DatatypeValidationFailure, deflt);
+ reportSchemaError(XMLUni::fgValidityDomain, XMLValid::DatatypeValidationFailure, deflt);
}
-
if(typeInfo != 0 &&
typeInfo->getContentType() != SchemaElementDecl::Simple &&
typeInfo->getContentType() != SchemaElementDecl::Mixed) {
@@ -2577,24 +2838,38 @@
const XMLCh* uri = resolvePrefixToURI(prefix);
DatatypeValidator* baseValidator = getDatatypeValidator(uri, localPart);
- if (baseValidator != 0
- && ((baseValidator->getFinalSet()
- & SchemaSymbols::EXTENSION) == typeInfo->getDerivedBy())) {
+ if (baseValidator != 0) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DisallowedSimpleTypeExtension,
- baseName, typeName);
- throw 0;
- }
+ // check that the simpleType does not preclude derivation by extension
+ if ((baseValidator->getFinalSet() & SchemaSymbols::EXTENSION) == typeInfo->getDerivedBy()) {
- processBaseTypeInfo(baseName, localPart, uri, typeInfo);
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DisallowedSimpleTypeExtension,
+ baseName, typeName);
+ throw 0;
+ }
+ typeInfo->setBaseComplexTypeInfo(0);
+ typeInfo->setBaseDatatypeValidator(baseValidator);
+ }
+ else {
+ processBaseTypeInfo(baseName, localPart, uri, typeInfo);
+ }
+
// check that the base isn't a complex type with complex content
+ // and that derivation method is not included in 'final'
ComplexTypeInfo* baseTypeInfo = typeInfo->getBaseComplexTypeInfo();
- if (baseTypeInfo != 0 && baseTypeInfo->getContentSpec() != 0) {
+ if (baseTypeInfo) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidSimpleContentBase, baseName);
- throw 0;
+ if (baseTypeInfo->getContentType() != SchemaElementDecl::Simple) {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidSimpleContentBase, baseName);
+ throw 0;
+ }
+
+ if ((baseTypeInfo->getFinalSet() & typeInfo->getDerivedBy()) != 0) {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ForbiddenDerivation, baseName);
+ throw 0;
+ }
}
// -----------------------------------------------------------------------
@@ -2613,8 +2888,7 @@
throw 0;
}
else {
- typeInfo->setBaseDatatypeValidator(
- typeInfo->getBaseComplexTypeInfo()->getDatatypeValidator());
+ typeInfo->setBaseDatatypeValidator(baseTypeInfo->getDatatypeValidator());
}
if (content != 0) {
@@ -2629,10 +2903,21 @@
int simpleTypeNameIndex = traverseSimpleTypeDecl(content);
if (simpleTypeNameIndex !=-1) {
+
+ DatatypeValidator* simpleTypeDV =
+ fDatatypeRegistry->getDatatypeValidator(fStringPool.getValueForId(simpleTypeNameIndex));
+
+ // Check that the simpleType validator is validly derived
+ // from base
+ DatatypeValidator* baseDV = typeInfo->getBaseDatatypeValidator();
- typeInfo->setBaseDatatypeValidator(fDatatypeRegistry->getDatatypeValidator(
- fStringPool.getValueForId(simpleTypeNameIndex)));
+ if (baseDV && !baseDV->isSubstitutableBy(simpleTypeDV)) {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidContentRestriction);
+ throw 0;
+ }
+
+ typeInfo->setBaseDatatypeValidator(simpleTypeDV);
content = XUtil::getNextSiblingElement(content);
}
else {
@@ -2780,6 +3065,7 @@
ComplexTypeInfo* baseTypeInfo = typeInfo->getBaseComplexTypeInfo();
if (baseTypeInfo!= 0) {
+
typeInfo->setBaseDatatypeValidator(baseTypeInfo->getDatatypeValidator());
}
@@ -2847,11 +3133,15 @@
bool mixedContent = isMixed;
- if (XMLString::compareString(mixed, SchemaSymbols::fgATTVAL_TRUE) == 0) {
- mixedContent = true;
- }
- else if (XMLString::compareString(mixed, SchemaSymbols::fgATTVAL_FALSE) == 0) {
- mixedContent = false;
+ if (mixed) {
+ if (!XMLString::compareString(mixed, SchemaSymbols::fgATTVAL_TRUE)
+ || !XMLString::compareString(mixed, fgValueOne)) {
+ mixedContent = true;
+ }
+ else if (!XMLString::compareString(mixed, SchemaSymbols::fgATTVAL_FALSE)
+ || !XMLString::compareString(mixed, fgValueZero)) {
+ mixedContent = false;
+ }
}
// -----------------------------------------------------------------------
@@ -3103,12 +3393,28 @@
void TraverseSchema::extractTopLevel3Components(const DOM_Element& rootElem) {
- // REVISIT - if necessary build list
+ for (DOM_Element child = XUtil::getFirstChildElement(rootElem);
+ child != 0;
+ child = XUtil::getNextSiblingElement(child)) {
+
+ DOMString name = child.getLocalName();
+ const XMLCh* typeName = getElementAttValue(child, SchemaSymbols::fgATT_NAME);
+
+ if (name.equals(SchemaSymbols::fgELT_GROUP)) {
+
+ if (fSchemaGrammar->getGroupElement(typeName) == 0) {
+ fSchemaGrammar->addGlobalGroup(child);
+ }
+ }
+ }
}
void TraverseSchema::processChildren(const DOM_Element& root) {
+ // extract global components and store them in the grammar
+ extractTopLevel3Components(root);
+
// process <redefine>, <include> and <import> info items.
DOM_Element child = XUtil::getFirstChildElement(root);
@@ -3188,7 +3494,17 @@
traverseAttributeDecl( child, 0);
}
else if (name.equals(SchemaSymbols::fgELT_GROUP)) {
- traverseGroupDecl(child);
+
+ if (XMLString::stringLen(typeName)) {
+ if (fGlobalGroups->containsKey(typeName, fTargetNSURI)) {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalType,
+ SchemaSymbols::fgELT_GROUP, typeName, SchemaSymbols::fgELT_COMPLEXTYPE);
+ continue;
+ }
+ else {
+ fGlobalGroups->put((void*) typeName, fTargetNSURI, 0);
+ }
+ }
}
else if (name.equals(SchemaSymbols::fgELT_NOTATION)) {
traverseNotationDecl(child); //TO DO
@@ -3212,7 +3528,7 @@
}
return 0;
- }
+ }
if (content.getLocalName().equals(SchemaSymbols::fgELT_ANNOTATION)) {
@@ -4108,42 +4424,24 @@
ContentSpecNode*
TraverseSchema::expandContentModel(ContentSpecNode* const specNode,
- const DOM_Element& elem) {
+ const DOM_Element& elem,
+ const int allContextFlag,
+ const bool toAdoptSpecNode) {
unsigned int minOccurs = 0;
unsigned int maxOccurs = 0;
- DOMString nOccurs = elem.getAttribute(SchemaSymbols::fgATT_MINOCCURS);
+ const XMLCh* minOccursStr =
+ getElementAttValue(elem, SchemaSymbols::fgATT_MINOCCURS, true);
+ const XMLCh* maxOccursStr =
+ getElementAttValue(elem, SchemaSymbols::fgATT_MAXOCCURS, true);
- if (nOccurs.length() > 0) {
-
- fBuffer.set(nOccurs.rawBuffer(), nOccurs.length());
- XMLString::trim(fBuffer.getRawBuffer());
- }
- else {
- fBuffer.reset();
- }
-
- if (XMLString::stringLen(fBuffer.getRawBuffer()) == 0) {
+ if (XMLString::stringLen(minOccursStr) == 0) {
minOccurs = 1;
}
else {
- XMLString::textToBin(fBuffer.getRawBuffer(), minOccurs);
+ XMLString::textToBin(minOccursStr, minOccurs);
}
- nOccurs = elem.getAttribute(SchemaSymbols::fgATT_MAXOCCURS);
-
- if (nOccurs.length() > 0) {
- fBuffer.set(nOccurs.rawBuffer(), nOccurs.length());
- }
- else {
- fBuffer.reset();
- }
-
- XMLCh* maxOccursStr = XMLString::replicate(fBuffer.getRawBuffer());
- ArrayJanitor<XMLCh> janMaxOccur(maxOccursStr);
-
- XMLString::trim(maxOccursStr);
-
bool isMaxUnbounded =
(XMLString::compareString(maxOccursStr, fgUnbounded) == 0);
@@ -4173,34 +4471,59 @@
}
else if (maxOccurs < minOccurs) {
- fBuffer.set(nOccurs.rawBuffer(), nOccurs.length());
reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidMin2MaxOccurs,
tmpMinStr, tmpMaxStr);
}
}
+ // Constraint checking for 'all' content
+ bool isAllElement = (allContextFlag == All_Element);
+ bool isAllGroup = (allContextFlag == All_Group);
+ bool isGroupRefAll = (allContextFlag == Group_Ref_With_All);
+
+ if (isAllElement || isAllGroup || isGroupRefAll) {
+
+ if (maxOccurs != 1
+ || ((isAllGroup || isGroupRefAll || minOccurs != 0)
+ && minOccurs != 1)) {
+
+ if (isAllElement) {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadMinMaxAllElem);
+ }
+ else {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadMinMaxAllCT);
+ }
+
+ return specNode;
+ }
+ }
+
+ if (!specNode) {
+ return 0;
+ }
+
ContentSpecNode* saveNode = specNode;
ContentSpecNode* retNode = specNode;
if (minOccurs == 1 && maxOccurs == 1) {
}
else if (minOccurs == 0 && maxOccurs == 1) {
-
+
retNode = new ContentSpecNode(ContentSpecNode::ZeroOrOne,
- retNode, 0);
+ retNode, 0, toAdoptSpecNode);
}
else if (minOccurs == 0 && isMaxUnbounded) {
retNode = new ContentSpecNode(ContentSpecNode::ZeroOrMore,
- retNode, 0);
+ retNode, 0, toAdoptSpecNode);
}
else if (minOccurs == 1 && isMaxUnbounded) {
retNode = new ContentSpecNode(ContentSpecNode::OneOrMore,
- retNode, 0);
+ retNode, 0, toAdoptSpecNode);
}
else if (isMaxUnbounded) {
retNode = new ContentSpecNode(ContentSpecNode::OneOrMore,
- retNode, 0);
+ retNode, 0, toAdoptSpecNode);
for (int i=0; i < (int)(minOccurs-1); i++) {
retNode = new ContentSpecNode(ContentSpecNode::Sequence,
@@ -4212,7 +4535,7 @@
if (minOccurs == 0) {
ContentSpecNode* optional =
- new ContentSpecNode(ContentSpecNode::ZeroOrOne, saveNode, 0);
+ new ContentSpecNode(ContentSpecNode::ZeroOrOne, saveNode, 0, toAdoptSpecNode);
retNode = optional;
@@ -4222,20 +4545,37 @@
}
}
else {
+
+ bool isAdopted = toAdoptSpecNode;
- for (int i=0; i < (int)(minOccurs-1); i++) {
+ if (minOccurs > 1) {
+
retNode = new ContentSpecNode(ContentSpecNode::Sequence,
- retNode, saveNode, true, false);
+ retNode, saveNode, isAdopted, false);
+
+ for (int i=1; i < (int)(minOccurs-1); i++) {
+ retNode = new ContentSpecNode(ContentSpecNode::Sequence,
+ retNode, saveNode, true, false);
+ }
+
+ isAdopted = true;
}
ContentSpecNode* optional =
new ContentSpecNode(ContentSpecNode::ZeroOrOne, saveNode, 0, false);
+
+ int counter = maxOccurs-minOccurs;
- for (int j=0; j < (int)(maxOccurs-minOccurs); j++) {
+ if (counter > 0) {
- bool toAdopt = (j == 0) ? true : false;
retNode = new ContentSpecNode(ContentSpecNode::Sequence,
- retNode, optional, true, toAdopt);
+ retNode, optional, isAdopted, true);
+
+ for (int j=1; j < counter; j++) {
+
+ retNode = new ContentSpecNode(ContentSpecNode::Sequence,
+ retNode, optional, true, false);
+ }
}
}
}
@@ -4254,6 +4594,50 @@
ContentSpecNode* specNode = 0;
DOM_Element attrNode;
+ int typeDerivedBy = SchemaSymbols::EMPTY_SET;
+ bool adoptSpecNode = true;
+ ComplexTypeInfo* baseTypeInfo = typeInfo->getBaseComplexTypeInfo();
+
+ if (baseTypeInfo) {
+
+ if (typeInfo->getDerivedBy() == SchemaSymbols::RESTRICTION) {
+
+ typeDerivedBy = SchemaSymbols::RESTRICTION;
+
+ // check to see if the baseType permits derivation by restriction
+ if((baseTypeInfo->getFinalSet() & typeDerivedBy) != 0) {
+
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ForbiddenDerivationByRestriction,
+ baseLocalPart);
+ throw 0;
+ }
+ }
+ else {
+
+ typeDerivedBy = SchemaSymbols::EXTENSION;
+
+ // check to see if the baseType permits derivation by extension
+ if((baseTypeInfo->getFinalSet() & typeDerivedBy) != 0) {
+
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ForbiddenDerivationByExtension, baseLocalPart);
+ throw 0; // REVISIT - should we continue
+ }
+
+ // Check for derivation valid (extension) - 1.4.2.2
+ int baseContentType = baseTypeInfo->getContentType();
+
+ if (baseContentType != SchemaElementDecl::Empty) {
+ if ((isMixed && baseContentType == SchemaElementDecl::Children)
+ || (!isMixed && baseContentType == SchemaElementDecl::Mixed)) {
+
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::MixedOrElementOnly, baseLocalPart, typeName);
+ throw 0; //REVISIT - should we continue
+ }
+ }
+
+ processElements(baseTypeInfo, typeInfo);
+ }
+ }
if (childElem != 0) {
@@ -4262,33 +4646,40 @@
// Note that it's possible that only attributes are specified.
// --------------------------------------------------------------------
DOMString childName = childElem.getLocalName();
+ ContentSpecNode* tmpSpecNode = 0;
if (childName.equals(SchemaSymbols::fgELT_GROUP)) {
-// specNode = expandContentModel(traverseGroupDecl(childElem),
-// childElem);
+ bool adoptSpecNode = true;
+ XercesGroupInfo* grpInfo = traverseGroupDecl(childElem, adoptSpecNode);
+
+ if (grpInfo) {
+
+ tmpSpecNode = grpInfo->getContentSpec();
+ int contentContext = hasAllContent(specNode) ? Group_Ref_With_All : Not_All_Context;
+ specNode = expandContentModel(specNode, childElem,
+ contentContext, adoptSpecNode);
+ }
+
attrNode = XUtil::getNextSiblingElement(childElem);
+
}
else if (childName.equals(SchemaSymbols::fgELT_SEQUENCE)) {
- specNode = expandContentModel(traverseChoiceSequence(childElem,
- ContentSpecNode::Sequence),
- childElem);
+ tmpSpecNode = traverseChoiceSequence(childElem, ContentSpecNode::Sequence, adoptSpecNode);
+ specNode = expandContentModel(tmpSpecNode, childElem, Not_All_Context, adoptSpecNode);
attrNode = XUtil::getNextSiblingElement(childElem);
}
else if (childName.equals(SchemaSymbols::fgELT_CHOICE)) {
- specNode = expandContentModel(traverseChoiceSequence(childElem,
- ContentSpecNode::Choice),
- childElem);
+ tmpSpecNode = traverseChoiceSequence(childElem, ContentSpecNode::Choice, adoptSpecNode);
+ specNode = expandContentModel(tmpSpecNode, childElem, Not_All_Context, adoptSpecNode);
attrNode = XUtil::getNextSiblingElement(childElem);
}
else if (childName.equals(SchemaSymbols::fgELT_ALL)) {
- specNode = expandContentModel(traverseAll(childElem), childElem);
+ //specNode = expandContentModel(traverseAll(childElem), childElem);
attrNode = XUtil::getNextSiblingElement(childElem);
- //TO DO: REVISIT
- //check that minOccurs = 1 and maxOccurs = 1
}
else if (isAttrOrAttrGroup(childElem)) {
// reset the contentType
@@ -4301,13 +4692,14 @@
reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInComplexType,
fBuffer.getRawBuffer());
}
+
+ if (tmpSpecNode != specNode) {
+ adoptSpecNode = true;
+ }
}
if (isMixed) {
- // TODO - check to see if we MUST have an element. What if only attributes
- // were specified??
-
// add #PCDATA leaf
QName* tmpName = new QName(XMLUni::fgZeroLenString, XMLUni::fgZeroLenString, XMLElementDecl::fgPCDataElemId);
Janitor<QName> janQName(tmpName);
@@ -4317,45 +4709,44 @@
// the element
if (specNode != 0) {
specNode = new ContentSpecNode(ContentSpecNode::Choice,
- pcdataNode, specNode);
+ pcdataNode, specNode, true, adoptSpecNode);
}
else {
specNode = pcdataNode;
}
+
+ adoptSpecNode = true;
}
typeInfo->setContentSpec(specNode);
+ typeInfo->setAdoptContentSpec(adoptSpecNode);
// -----------------------------------------------------------------------
// Merge in information from base, if it exists
// -----------------------------------------------------------------------
- ComplexTypeInfo* baseTypeInfo = typeInfo->getBaseComplexTypeInfo();
if (baseTypeInfo != 0) {
ContentSpecNode* baseSpecNode = baseTypeInfo->getContentSpec();
- if (typeInfo->getDerivedBy() == SchemaSymbols::RESTRICTION) {
+ if (typeDerivedBy == SchemaSymbols::RESTRICTION) {
- // check to see if the baseType permits derivation by restriction
- if((baseTypeInfo->getFinalSet() & SchemaSymbols::RESTRICTION) != 0) {
+ //check derivation valid - content type is empty (5.2)
+ if (!typeInfo->getContentSpec()) {
+ int baseContentType = baseTypeInfo->getContentType();
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ForbiddenDerivationByRestriction,
- baseLocalPart);
- throw 0;
+ if (baseContentType != SchemaElementDecl::Empty
+ && ((baseContentType != SchemaElementDecl::Children
+ && baseContentType != SchemaElementDecl::Mixed)
+ || !emptiableParticle(baseSpecNode))) {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::EmptyComplexRestrictionDerivation);
+ }
}
- //REVISIT: !!!really hairy stuff to check the particle derivation OK in 5.10
-
+ // Delay particle constraint checking (5.3) until we have processed
+ // the whole schema.
}
else {
-
- // check to see if the baseType permits derivation by extension
- if((baseTypeInfo->getFinalSet() & SchemaSymbols::EXTENSION) != 0) {
-
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ForbiddenDerivationByExtension, baseLocalPart);
- throw 0;
- }
-
+
// Compose the final content model by concatenating the base and
// the current in sequence
if (!specNode) {
@@ -4453,13 +4844,14 @@
fBuffer.append(localPart);
// assume the base is a complexType and try to locate the base type first
- baseComplexTypeInfo = fComplexTypeRegistry->get(fBuffer.getRawBuffer());
+ const XMLCh* fullBaseName = fBuffer.getRawBuffer();
+ baseComplexTypeInfo = fComplexTypeRegistry->get(fullBaseName);
// Circular check
if (baseComplexTypeInfo &&
- locationsContain(fCurrentTypeNameStack, fStringPool.addOrFind(localPart))) {
+ locationsContain(fCurrentTypeNameStack, fStringPool.addOrFind(fullBaseName))) {
- reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, localPart);
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, fullBaseName);
throw 0;
}
@@ -4787,6 +5179,8 @@
fBlockDefault = fCurrentSchemaInfo->getBlockDefault();
fFinalDefault = fCurrentSchemaInfo->getFinalDefault();
fSchemaRootElement = fCurrentSchemaInfo->getRoot();
+ fSchemaGrammar->setElementDefaultQualified(fElementDefaultQualified);
+ fSchemaGrammar->setAttributeDefaultQualified(fAttributeDefaultQualified);
}
@@ -4858,10 +5252,6 @@
return SchemaSymbols::UNBOUNDED;
}
- if (specNode->getElement()->getURI() == XMLElementDecl::fgPCDataElemId) {
- return 0;
- }
-
const ContentSpecNode* first = 0;
const ContentSpecNode* second = 0;
int max = 1;
@@ -5044,6 +5434,206 @@
}
}
+XercesGroupInfo* TraverseSchema::processGroupRef(const DOM_Element& elem,
+ const XMLCh* const refName,
+ bool& toAdoptSpecNode) {
+
+ if (XUtil::getFirstChildElement(elem) != 0) {
+ reportSchemaError(XMLUni::fgValidityDomain, XMLValid::NoContentForRef);
+ }
+
+ const XMLCh* prefix = getPrefix(refName);
+ const XMLCh* localPart = getLocalPart(refName);
+ const XMLCh* uriStr = resolvePrefixToURI(prefix);
+
+ fBuffer.set(uriStr);
+ fBuffer.append(chComma);
+ fBuffer.append(localPart);
+
+ unsigned int nameIndex = fStringPool.addOrFind(fBuffer.getRawBuffer());
+
+ if (locationsContain(fCurrentGroupStack, nameIndex)) {
+
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, localPart);
+ return 0;
+ }
+
+ XercesGroupInfo* groupInfo = fGroupRegistry->get(fBuffer.getRawBuffer());
+
+ if (groupInfo) {
+
+ toAdoptSpecNode = false;
+
+ // create element declarations in complexType
+ if (groupInfo->getScope() != fCurrentScope) {
+ createGroupElements(groupInfo, fSchemaGrammar);
+ }
+ }
+ else {
+
+ //if from another schema
+ if (XMLString::compareString(uriStr, fTargetNSURIString) != 0) {
+ groupInfo = traverseGroupDeclNS(uriStr, localPart, toAdoptSpecNode);
+ }
+ else {
+
+ DOM_Element groupElem =
+ getTopLevelComponentByName(SchemaSymbols::fgELT_GROUP, localPart);
+
+ if (groupElem != 0) {
+ groupInfo = traverseGroupDecl(groupElem, toAdoptSpecNode);
+ }
+ else {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::GroupNotFound, localPart);
+ }
+ }
+ }
+
+ // copy ref'd group elements
+ if (fCurrentGroupInfo
+ && groupInfo->getScope() == fCurrentGroupInfo->getScope()) {
+ copyGroupElements(fCurrentGroupInfo, groupInfo);
+ }
+
+ return groupInfo;
+}
+
+void TraverseSchema::createGroupElements(XercesGroupInfo* const groupInfo,
+ const SchemaGrammar* const schemaGrammar) {
+
+ unsigned int elemCount = groupInfo->elementCount();
+
+ if (elemCount) {
+
+ int schemaURI = fURIStringPool->addOrFind(SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
+ int emptyURI = fURIStringPool->addOrFind(XMLUni::fgZeroLenString);
+
+ for (unsigned int i=0; i < elemCount; i++) {
+
+ const SchemaGrammar* aGrammar = schemaGrammar;
+ SchemaElementDecl* elemDecl = groupInfo->elementAt(i);
+ int elemURI = elemDecl->getURI();
+
+ if (elemURI != fTargetNSURI && elemURI != schemaURI && elemURI != emptyURI) {
+
+ Grammar* aGrammar =
+ fGrammarResolver->getGrammar(fURIStringPool->getValueForId(elemURI));
+
+ if (!aGrammar || aGrammar->getGrammarType() != Grammar::SchemaGrammarType) {
+ continue; // REVISIT - error message
+ }
+ }
+
+ const XMLCh* localPart = elemDecl->getBaseName();
+ const SchemaElementDecl* other = (SchemaElementDecl*)
+ aGrammar->getElemDecl(elemURI, localPart, 0, fCurrentScope);
+
+ if (other) {
+
+ if (elemDecl->getComplexTypeInfo() != other->getComplexTypeInfo()
+ || elemDecl->getDatatypeValidator() != other->getDatatypeValidator()) {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, localPart);
+ }
+ }
+ else {
+
+ int elemScope = elemDecl->getEnclosingScope();
+
+ fCurrentComplexType->addElement(elemDecl);
+ elemDecl->setEnclosingScope(fCurrentScope);
+ ((SchemaGrammar*) aGrammar)->putGroupElemDecl(elemDecl);
+ elemDecl->setEnclosingScope(elemScope);
+ }
+ }
+ }
+}
+
+bool TraverseSchema::hasAllContent(const ContentSpecNode* const specNode) {
+
+ if (specNode) {
+
+ const ContentSpecNode* tmpSpecNode = specNode;
+
+ if (specNode->getType() == ContentSpecNode::ZeroOrOne) {
+ tmpSpecNode = specNode->getFirst();
+ }
+
+ return (tmpSpecNode->getType() == ContentSpecNode::All);
+ }
+
+ return false;
+}
+
+void TraverseSchema::processElements(ComplexTypeInfo* const baseTypeInfo,
+ ComplexTypeInfo* const newTypeInfo) {
+
+ unsigned int elemCount = baseTypeInfo->elementCount();
+
+ if (elemCount) {
+
+ int newTypeScope = newTypeInfo->getScopeDefined();
+ int schemaURI = fURIStringPool->addOrFind(SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
+ int emptyURI = fURIStringPool->addOrFind(XMLUni::fgZeroLenString);
+
+ for (unsigned int i=0; i < elemCount; i++) {
+
+ SchemaGrammar* aGrammar = fSchemaGrammar;
+ SchemaElementDecl* elemDecl = baseTypeInfo->elementAt(i);
+
+ if (!elemDecl) {
+ continue;
+ }
+
+ int elemURI = elemDecl->getURI();
+
+ if (elemURI != fTargetNSURI && elemURI != schemaURI && elemURI != emptyURI) {
+
+ Grammar* aGrammar =
+ fGrammarResolver->getGrammar(fURIStringPool->getValueForId(elemURI));
+
+ if (!aGrammar || aGrammar->getGrammarType() != Grammar::SchemaGrammarType) {
+ continue; // REVISIT - error message
+ }
+ }
+
+ const XMLCh* localPart = elemDecl->getBaseName();
+ const SchemaElementDecl* other = (SchemaElementDecl*)
+ aGrammar->getElemDecl(elemURI, localPart, 0, newTypeScope);
+
+ if (other) {
+
+ if (elemDecl->getComplexTypeInfo() != other->getComplexTypeInfo()
+ || elemDecl->getDatatypeValidator() != other->getDatatypeValidator()) {
+ reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, localPart);
+ }
+ }
+ else {
+
+ int elemScope = elemDecl->getEnclosingScope();
+
+ newTypeInfo->addElement(elemDecl);
+ elemDecl->setEnclosingScope(newTypeScope);
+ ((SchemaGrammar*) aGrammar)->putGroupElemDecl(elemDecl);
+ elemDecl->setEnclosingScope(elemScope);
+ }
+ }
+ }
+}
+
+
+void TraverseSchema::copyGroupElements(XercesGroupInfo* const toGroup,
+ XercesGroupInfo* const fromGroup) {
+
+ if (toGroup && fromGroup) {
+
+ unsigned int fromSize = fromGroup->elementCount();
+
+ for (unsigned int i=0; i< fromSize; i++) {
+ toGroup->addElement(fromGroup->elementAt(i));
+ }
+ }
+}
+
// ---------------------------------------------------------------------------
// TraverseSchema: Error reporting methods
// ---------------------------------------------------------------------------
@@ -5085,10 +5675,13 @@
delete fSchemaInfoRoot;
delete fIncludeLocations;
delete fCurrentTypeNameStack;
+ delete fCurrentGroupStack;
delete fGlobalTypes;
+ delete fGlobalGroups;
delete fSubstitutionGroups;
delete fRefElements;
- delete fRefElemScope;
+ delete fRefElemScope;
+ delete fGroupRegistry;
if (fAdoptImportLocations) {
delete fImportLocations;
1.16 +65 -7 xml-xerces/c/src/validators/schema/TraverseSchema.hpp
Index: TraverseSchema.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/validators/schema/TraverseSchema.hpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- TraverseSchema.hpp 2001/07/12 15:33:00 1.15
+++ TraverseSchema.hpp 2001/07/24 18:33:46 1.16
@@ -55,7 +55,7 @@
*/
/*
- * $Id: TraverseSchema.hpp,v 1.15 2001/07/12 15:33:00 knoaman Exp $
+ * $Id: TraverseSchema.hpp,v 1.16 2001/07/24 18:33:46 knoaman Exp $
*/
#if !defined(TRAVERSESCHEMA_HPP)
@@ -97,6 +97,7 @@
class InputSource;
class ErrorHandler;
class GeneralAttributeCheck;
+class XercesGroupInfo;
class VALIDATORS_EXPORT TraverseSchema
@@ -178,10 +179,15 @@
QName* traverseElementDecl(const DOM_Element& childElem);
XMLCh* traverseNotationDecl(const DOM_Element& childElem);
ContentSpecNode* traverseChoiceSequence(const DOM_Element& elemDecl,
- const int modelGroupType);
+ const int modelGroupType,
+ bool& toAdoptSpecNode);
ContentSpecNode* traverseAny(const DOM_Element& anyDecl);
- ContentSpecNode* traverseGroupDecl(const DOM_Element& childElem);
ContentSpecNode* traverseAll(const DOM_Element& allElem);
+ XercesGroupInfo* traverseGroupDecl(const DOM_Element& childElem,
+ bool& toAdoptSpecNode);
+ XercesGroupInfo* traverseGroupDeclNS(const XMLCh* const uriStr,
+ const XMLCh* const groupName,
+ bool& toAdoptSpecNode);
SchemaAttDef* traverseAnyAttribute(const DOM_Element& elem);
// -----------------------------------------------------------------------
@@ -321,6 +327,13 @@
const XMLCh* const useVal);
/**
+ * Process a 'ref' on a group
+ */
+ XercesGroupInfo* processGroupRef(const DOM_Element& elem,
+ const XMLCh* const refName,
+ bool& toAdoptScpecNode);
+
+ /**
* Parse block & final items
*/
int parseBlockSet(const XMLCh* const blockStr, const int blockType);
@@ -396,10 +409,13 @@
* Return the value of a given attribute name from an element node
*/
const XMLCh* getElementAttValue(const DOM_Element& elem,
- const XMLCh* const attName);
+ const XMLCh* const attName,
+ const bool toTrim = false);
ContentSpecNode* expandContentModel(ContentSpecNode* const specNode,
- const DOM_Element& elem);
+ const DOM_Element& elem,
+ const int allContext = Not_All_Context,
+ const bool toAdoptSpecNode = true);
/**
* Process complex content for a complexType
@@ -497,6 +513,17 @@
void checkEnumerationRequiredNotation(const XMLCh* const name,
const XMLCh* const typeStr);
+ void createGroupElements(XercesGroupInfo* const groupInfo,
+ const SchemaGrammar* const schemaGrammar);
+
+ bool hasAllContent(const ContentSpecNode* const specNode);
+
+ void processElements(ComplexTypeInfo* const baseTypeInfo,
+ ComplexTypeInfo* const newTypeInfo);
+
+ void copyGroupElements(XercesGroupInfo* const toGroup,
+ XercesGroupInfo* const fromGroup);
+
// -----------------------------------------------------------------------
// Private constants
// -----------------------------------------------------------------------
@@ -508,6 +535,20 @@
, ECS_Final
};
+ // Flags indicate any special restrictions on minOccurs and maxOccurs
+ // relating to "all".
+ // Not_All_Context - not processing an <all>
+ // All_Element - processing an <element> in an <all>
+ // Group_Ref_With_All - processing <group> reference that contained <all>
+ // All_Group - processing an <all> group itself
+ enum
+ {
+ Not_All_Context = 0
+ , All_Element = 1
+ , Group_Ref_With_All = 2
+ , All_Group = 4
+ };
+
// -----------------------------------------------------------------------
// Private data members
// -----------------------------------------------------------------------
@@ -527,6 +568,7 @@
DatatypeValidatorFactory* fDatatypeRegistry;
GrammarResolver* fGrammarResolver;
SchemaGrammar* fSchemaGrammar;
+ SchemaGrammar* fRefSchemaGrammar;
EntityResolver* fEntityResolver;
ErrorHandler* fErrorHandler;
XMLStringPool* fURIStringPool;
@@ -536,13 +578,18 @@
NamespaceScope* fNamespaceScope;
RefHashTableOf<XMLAttDef>* fAttributeDeclRegistry;
RefHashTableOf<ComplexTypeInfo>* fComplexTypeRegistry;
+ RefHashTableOf<XercesGroupInfo>* fGroupRegistry;
SchemaInfo* fSchemaInfoRoot;
SchemaInfo* fCurrentSchemaInfo;
+ XercesGroupInfo* fCurrentGroupInfo;
+ ComplexTypeInfo* fCurrentComplexType;
ValueVectorOf<unsigned int>* fImportLocations;
ValueVectorOf<unsigned int>* fIncludeLocations;
ValueVectorOf<unsigned int>* fCurrentTypeNameStack;
+ ValueVectorOf<unsigned int>* fCurrentGroupStack;
GeneralAttributeCheck* fAttributeCheck;
RefHash2KeysTableOf<XMLCh>* fGlobalTypes;
+ RefHash2KeysTableOf<XMLCh>* fGlobalGroups;
RefHash2KeysTableOf<SchemaElementDecl>* fSubstitutionGroups;
RefHash2KeysTableOf<ElemVector>* fValidSubstitutionGroups;
RefVectorOf<SchemaElementDecl>* fRefElements;
@@ -620,15 +667,26 @@
inline
const XMLCh* TraverseSchema::getElementAttValue(const DOM_Element& elem,
- const XMLCh* const attName) {
+ const XMLCh* const attName,
+ const bool toTrim) {
DOMString attValue = elem.getAttribute(attName);
if (attValue.length() > 0) {
fBuffer.set(attValue.rawBuffer(), attValue.length());
- unsigned int elemId = fStringPool.addOrFind(fBuffer.getRawBuffer());
+ XMLCh* bufValue = fBuffer.getRawBuffer();
+
+ if (toTrim) {
+
+ XMLString::trim(bufValue);
+
+ if (!XMLString::stringLen(bufValue)) {
+ return 0;
+ }
+ }
+ unsigned int elemId = fStringPool.addOrFind(bufValue);
return fStringPool.getValueForId(elemId);
}
1.1 xml-xerces/c/src/validators/schema/XercesGroupInfo.cpp
Index: XercesGroupInfo.cpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: XercesGroupInfo.cpp,v $
* Revision 1.1 2001/07/24 18:33:46 knoaman
* Added support for <group> + extra constraint checking for complexType
*
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <validators/schema/XercesGroupInfo.hpp>
// ---------------------------------------------------------------------------
// XercesGroupInfo: Constructors and Destructor
// ---------------------------------------------------------------------------
XercesGroupInfo::XercesGroupInfo()
: fScope(-1)
, fContentSpec(0)
, fElements(0)
{
fElements = new RefVectorOf<SchemaElementDecl>(4, false);
}
XercesGroupInfo::~XercesGroupInfo()
{
delete fElements;
}
/**
* End of file XercesGroupInfo.cpp
*/
1.1 xml-xerces/c/src/validators/schema/XercesGroupInfo.hpp
Index: XercesGroupInfo.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 2001, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Id: XercesGroupInfo.hpp,v 1.1 2001/07/24 18:33:46 knoaman Exp $
*/
#if !defined(XERCESGROUPINFO_HPP)
#define XERCESGROUPINFO_HPP
/**
* The class act as a place holder to store group information.
*
* The class is intended for internal use.
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <util/RefVectorOf.hpp>
#include <validators/schema/SchemaElementDecl.hpp>
// ---------------------------------------------------------------------------
// Forward Declarations
// ---------------------------------------------------------------------------
class ContentSpecNode;
class VALIDATORS_EXPORT XercesGroupInfo
{
public:
// -----------------------------------------------------------------------
// Public Constructors/Destructor
// -----------------------------------------------------------------------
XercesGroupInfo();
~XercesGroupInfo();
// -----------------------------------------------------------------------
// Getter methods
// -----------------------------------------------------------------------
bool getAdoptContentSpec() const;
int getScope() const;
unsigned int elementCount() const;
ContentSpecNode* getContentSpec() const;
SchemaElementDecl* elementAt(const unsigned int index);
const SchemaElementDecl* elementAt(const unsigned int index) const;
// -----------------------------------------------------------------------
// Setter methods
// -----------------------------------------------------------------------
void setScope(const int other);
void setContentSpec(ContentSpecNode* const other);
void setAdoptContentSpec(const bool toAdopt);
void addElement(SchemaElementDecl* const toAdd);
private:
// -----------------------------------------------------------------------
// Unimplemented contstructors and operators
// -----------------------------------------------------------------------
XercesGroupInfo(const XercesGroupInfo& elemInfo);
XercesGroupInfo& operator= (const XercesGroupInfo& other);
// -----------------------------------------------------------------------
// Private data members
// -----------------------------------------------------------------------
int fScope;
ContentSpecNode* fContentSpec;
RefVectorOf<SchemaElementDecl>* fElements;
};
// ---------------------------------------------------------------------------
// XercesGroupInfo: Getter methods
// ---------------------------------------------------------------------------
inline int XercesGroupInfo::getScope() const {
return fScope;
}
inline unsigned int XercesGroupInfo::elementCount() const {
return fElements->size();
}
inline ContentSpecNode* XercesGroupInfo::getContentSpec() const {
return fContentSpec;
}
inline SchemaElementDecl*
XercesGroupInfo::elementAt(const unsigned int index) {
return fElements->elementAt(index);
}
inline const SchemaElementDecl*
XercesGroupInfo::elementAt(const unsigned int index) const {
return fElements->elementAt(index);
}
// ---------------------------------------------------------------------------
// XercesGroupInfo: Setter methods
// ---------------------------------------------------------------------------}
inline void XercesGroupInfo::setScope(const int other) {
fScope = other;
}
inline void XercesGroupInfo::setContentSpec(ContentSpecNode* const other) {
fContentSpec = other;
}
inline void XercesGroupInfo::addElement(SchemaElementDecl* const elem) {
fElements->addElement(elem);
}
#endif
/**
* End of file XercesGroupInfo.hpp
*/
---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org