You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by ne...@apache.org on 2003/10/05 04:09:37 UTC
cvs commit: xml-xerces/c/src/xercesc/validators/schema SchemaValidator.cpp SchemaValidator.hpp
neilg 2003/10/04 19:09:37
Modified: c/src/xercesc/validators/schema SchemaValidator.cpp
SchemaValidator.hpp
Log:
the validator now keeps track of the current complex and simple type (including if this is an xsi:type). This allows both the validator and the scanner to know what the current type is, without the need to modify the element declaration each time an xsi:type is seen
Revision Changes Path
1.39 +53 -50 xml-xerces/c/src/xercesc/validators/schema/SchemaValidator.cpp
Index: SchemaValidator.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/validators/schema/SchemaValidator.cpp,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -r1.38 -r1.39
--- SchemaValidator.cpp 1 Oct 2003 16:32:42 -0000 1.38
+++ SchemaValidator.cpp 5 Oct 2003 02:09:37 -0000 1.39
@@ -56,6 +56,9 @@
/*
* $Log$
+ * Revision 1.39 2003/10/05 02:09:37 neilg
+ * the validator now keeps track of the current complex and simple type (including if this is an xsi:type). This allows both the validator and the scanner to know what the current type is, without the need to modify the element declaration each time an xsi:type is seen
+ *
* Revision 1.38 2003/10/01 16:32:42 neilg
* improve handling of out of memory conditions, bug #23415. Thanks to David Cargill.
*
@@ -294,7 +297,7 @@
, fTrailing(false)
, fSeenId(false)
, fXsiType(0)
- , fXsiTypeValidator(0)
+ , fCurrentDatatypeValidator(0)
, fNotationBuf(0)
, fDatatypeBuffer(1023, manager)
, fNil(false)
@@ -328,13 +331,18 @@
if (!elemDecl)
ThrowXML(RuntimeException, XMLExcepts::Val_InvalidElemId);
- ((SchemaElementDecl*) elemDecl)->setXsiComplexTypeInfo(fTypeStack->pop());
-
//
// Get the content spec type of this element. This will tell us what
// to do to validate it.
//
- const SchemaElementDecl::ModelTypes modelType = ((SchemaElementDecl*) elemDecl)->getModelType();
+
+ // the top of the type stack always knows best...
+ ComplexTypeInfo* currType = fTypeStack->pop();
+ ((SchemaElementDecl*) elemDecl)->setXsiComplexTypeInfo(currType);
+
+ const SchemaElementDecl::ModelTypes modelType = (currType)
+ ? (SchemaElementDecl::ModelTypes)(currType->getContentType())
+ : ((SchemaElementDecl*)elemDecl)->getModelType();
if (modelType == SchemaElementDecl::Empty)
{
@@ -365,7 +373,7 @@
}
else {
// Get the element's content model or fault it in
- XMLContentModel* elemCM = elemDecl->getContentModel();
+ XMLContentModel* elemCM = currType->getContentModel();
// Ask it to validate and return its return
unsigned int emptyNS = getScanner()->getEmptyNamespaceId();
@@ -375,7 +383,7 @@
, childCount
, emptyNS
, fGrammarResolver
- , getScanner()->getURIStringPool());
+ , fGrammarResolver->getStringPool());
}
if(result != -1) {
@@ -396,19 +404,7 @@
valid = false;
} else {
try {
- DatatypeValidator* fCurrentDV = 0;
- bool hasXsiType = false;
-
- if (modelType == SchemaElementDecl::Simple)
- fCurrentDV = ((SchemaElementDecl*)elemDecl)->getDatatypeValidator();
-
- // If there is xsi:type validator, substitute it.
- if (fXsiTypeValidator) {
- hasXsiType = true;
- fCurrentDV = fXsiTypeValidator;
- fXsiTypeValidator = 0;
- }
- if (!fCurrentDV) {
+ if (!fCurrentDatatypeValidator) {
if (modelType == SchemaElementDecl::Simple) {
emitError(XMLValid::NoDatatypeValidatorForSimpleType, elemDecl->getFullName());
valid = false;
@@ -417,12 +413,12 @@
XMLCh* value = fDatatypeBuffer.getRawBuffer();
XMLCh* elemDefaultValue = ((SchemaElementDecl*) elemDecl)->getDefaultValue();
- DatatypeValidator::ValidatorType eleDefDVType = fCurrentDV->getType();
+ DatatypeValidator::ValidatorType eleDefDVType = fCurrentDatatypeValidator->getType();
// set up the entitydeclpool in ENTITYDatatypeValidator
// and the idreflist in ID/IDREFDatatypeValidator
if (eleDefDVType == DatatypeValidator::List) {
- DatatypeValidator* itemDTV = ((ListDatatypeValidator*)fCurrentDV)->getItemTypeDTV();
+ DatatypeValidator* itemDTV = ((ListDatatypeValidator*)fCurrentDatatypeValidator)->getItemTypeDTV();
DatatypeValidator::ValidatorType itemDTVType = itemDTV->getType();
if (itemDTVType == DatatypeValidator::ENTITY)
((ENTITYDatatypeValidator*)itemDTV)->setEntityDeclPool(getScanner()->getEntityDeclPool());
@@ -448,7 +444,7 @@
}
}
else if (eleDefDVType == DatatypeValidator::Union) {
- RefVectorOf<DatatypeValidator>* memberDTV = ((UnionDatatypeValidator*)fCurrentDV)->getMemberTypeValidators();
+ RefVectorOf<DatatypeValidator>* memberDTV = ((UnionDatatypeValidator*)fCurrentDatatypeValidator)->getMemberTypeValidators();
unsigned int memberTypeNumber = memberDTV->size();
for ( unsigned int memberIndex = 0; memberIndex < memberTypeNumber; ++memberIndex)
{
@@ -474,11 +470,11 @@
}
}
else if (eleDefDVType == DatatypeValidator::ENTITY)
- ((ENTITYDatatypeValidator*)fCurrentDV)->setEntityDeclPool(getScanner()->getEntityDeclPool());
+ ((ENTITYDatatypeValidator*)fCurrentDatatypeValidator)->setEntityDeclPool(getScanner()->getEntityDeclPool());
else if (eleDefDVType == DatatypeValidator::ID)
- ((IDDatatypeValidator*)fCurrentDV)->setIDRefList(getScanner()->getIDRefList());
+ ((IDDatatypeValidator*)fCurrentDatatypeValidator)->setIDRefList(getScanner()->getIDRefList());
else if (eleDefDVType == DatatypeValidator::IDREF) {
- ((IDREFDatatypeValidator*)fCurrentDV)->setIDRefList(getScanner()->getIDRefList());
+ ((IDREFDatatypeValidator*)fCurrentDatatypeValidator)->setIDRefList(getScanner()->getIDRefList());
}
else if (eleDefDVType == DatatypeValidator::NOTATION)
{
@@ -517,15 +513,19 @@
// Normally for default value, it has been validated already during TraverseSchema
// But if there was a xsi:type and this validator is fXsiTypeValidator,
// need to validate again
- if (hasXsiType)
- fCurrentDV->validate(elemDefaultValue);
+ // we determine this if the current content dataype validator
+ // is neither the one in the element nor the one in the current
+ // complex type (if any)
+ if ((fCurrentDatatypeValidator != ((SchemaElementDecl*)elemDecl)->getDatatypeValidator())
+ && (!fTypeStack->peek() || (fCurrentDatatypeValidator != fTypeStack->peek()->getDatatypeValidator())))
+ fCurrentDatatypeValidator->validate(elemDefaultValue);
}
else {
// this element has specified some value
// if the flag is FIXED, then this value must be same as default value
if ((((SchemaElementDecl*)elemDecl)->getMiscFlags() & SchemaSymbols::XSD_FIXED) != 0) {
- if (fCurrentDV->compare(value, elemDefaultValue) != 0 ) {
+ if (fCurrentDatatypeValidator->compare(value, elemDefaultValue) != 0 ) {
emitError(XMLValid::FixedDifferentFromActual, elemDecl->getFullName());
valid = false;
}
@@ -537,21 +537,21 @@
valid = false;
}
else
- fCurrentDV->validate(value);
+ fCurrentDatatypeValidator->validate(value);
}
}
else {
// no default value, then check nillable
if (XMLString::equals(value, XMLUni::fgZeroLenString)) {
if ((((SchemaElementDecl*)elemDecl)->getMiscFlags() & SchemaSymbols::XSD_NILLABLE) == 0)
- fCurrentDV->validate(value);
+ fCurrentDatatypeValidator->validate(value);
}
else if (fNil) {
emitError(XMLValid::NilAttrNotEmpty, elemDecl->getFullName());
valid = false;
}
else
- fCurrentDV->validate(value);
+ fCurrentDatatypeValidator->validate(value);
}
}
}
@@ -613,7 +613,7 @@
fSeenId = false;
delete fXsiType;
fXsiType = 0;
- fXsiTypeValidator = 0;
+ fCurrentDatatypeValidator = 0;
fNil = false;
fDatatypeBuffer.reset();
}
@@ -799,11 +799,15 @@
{
ComplexTypeInfo* elemTypeInfo = ((SchemaElementDecl*)elemDef)->getComplexTypeInfo();
fTypeStack->push(elemTypeInfo);
+ fCurrentDatatypeValidator = (elemTypeInfo)
+ ? elemTypeInfo->getDatatypeValidator()
+ : ((SchemaElementDecl*)elemDef)->getDatatypeValidator();
bool valid = true;
if (fXsiType) {
// handle "xsi:type" right here
+ DatatypeValidator *xsiTypeDV = 0;
unsigned int uri = fXsiType->getURI();
const XMLCh* localPart = fXsiType->getLocalPart();
@@ -820,17 +824,17 @@
// Check built-in simple types
if (XMLString::equals(uriStr, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) {
- fXsiTypeValidator = fGrammarResolver->getDatatypeValidator(uriStr, localPart);
+ xsiTypeDV = fGrammarResolver->getDatatypeValidator(uriStr, localPart);
- if (!fXsiTypeValidator) {
+ if (!xsiTypeDV) {
emitError(XMLValid::BadXsiType, fXsiType->getRawName());
valid = false;
}
else {
- ((SchemaElementDecl*)elemDef)->setXsiSimpleTypeInfo(fXsiTypeValidator);
+ ((SchemaElementDecl*)elemDef)->setXsiSimpleTypeInfo(xsiTypeDV);
- DatatypeValidator* ancestorValidator = ((SchemaElementDecl*)elemDef)->getDatatypeValidator();
- if (ancestorValidator && !ancestorValidator->isSubstitutableBy(fXsiTypeValidator)) {
+ if (elemTypeInfo || (fCurrentDatatypeValidator
+ && !fCurrentDatatypeValidator->isSubstitutableBy(xsiTypeDV))) {
// the type is not derived from ancestor
emitError(XMLValid::NonDerivedXsiType, fXsiType->getRawName(), elemDef->getFullName());
valid = false;
@@ -847,6 +851,7 @@
valid = false;
}
}
+ fCurrentDatatypeValidator = xsiTypeDV;
}
}
else {
@@ -885,11 +890,10 @@
error = true;
}
- ComplexTypeInfo* destType = ((SchemaElementDecl*)elemDef)->getComplexTypeInfo();
ComplexTypeInfo* tempType = typeInfo;
- if (destType) {
+ if (elemTypeInfo) {
while (tempType) {
- if (XMLString::equals(tempType->getTypeName(), destType->getTypeName()))
+ if (tempType == elemTypeInfo)
break;
tempType = tempType->getBaseComplexTypeInfo();
}
@@ -907,8 +911,7 @@
}
else {
// if the original type is a simple type, check derivation ok.
- DatatypeValidator* ancestorValidator = ((SchemaElementDecl*)elemDef)->getDatatypeValidator();
- if (ancestorValidator && !ancestorValidator->isSubstitutableBy(fXsiTypeValidator)) {
+ if (fCurrentDatatypeValidator && !fCurrentDatatypeValidator->isSubstitutableBy(typeInfo->getDatatypeValidator())) {
// the type is not derived from ancestor
emitError(XMLValid::NonDerivedXsiType, fXsiType->getRawName(), elemDef->getFullName());
error = true;
@@ -919,22 +922,21 @@
((SchemaElementDecl*)elemDef)->setXsiComplexTypeInfo(typeInfo);
fTypeStack->pop();
fTypeStack->push(typeInfo);
+ fCurrentDatatypeValidator = typeInfo->getDatatypeValidator();
}
valid = !error;
}
else {
// typeInfo not found
- fXsiTypeValidator = fGrammarResolver->getDatatypeValidator(uriStr, localPart);
+ xsiTypeDV = fGrammarResolver->getDatatypeValidator(uriStr, localPart);
- if (!fXsiTypeValidator) {
+ if (!xsiTypeDV) {
emitError(XMLValid::BadXsiType, fXsiType->getRawName());
valid = false;
}
else {
-
- ((SchemaElementDecl*)elemDef)->setXsiSimpleTypeInfo(fXsiTypeValidator);
- DatatypeValidator* ancestorValidator = ((SchemaElementDecl*)elemDef)->getDatatypeValidator();
- if (ancestorValidator && !ancestorValidator->isSubstitutableBy(fXsiTypeValidator)) {
+ ((SchemaElementDecl*)elemDef)->setXsiSimpleTypeInfo(xsiTypeDV);
+ if (fCurrentDatatypeValidator && !fCurrentDatatypeValidator->isSubstitutableBy(xsiTypeDV)) {
// the type is not derived from ancestor
emitError(XMLValid::NonDerivedXsiType, fXsiType->getRawName(), elemDef->getFullName());
valid = false;
@@ -952,6 +954,7 @@
valid = false;
}
}
+ fCurrentDatatypeValidator = xsiTypeDV;
}
}
@@ -1170,7 +1173,7 @@
while (complexTypeEnum.hasMoreElements())
{
ComplexTypeInfo& curTypeInfo = complexTypeEnum.nextElement();
- curTypeInfo.checkUniqueParticleAttribution(&sGrammar, fGrammarResolver, getScanner()->getURIStringPool(), this);
+ curTypeInfo.checkUniqueParticleAttribution(&sGrammar, fGrammarResolver, fGrammarResolver->getStringPool(), this);
checkParticleDerivation(&sGrammar, &curTypeInfo);
checkRefElementConsistency(&sGrammar, &curTypeInfo);
}
@@ -1702,7 +1705,7 @@
}
SchemaGrammar* aGrammar = currentGrammar;
- const XMLCh* schemaURI = getScanner()->getURIStringPool()->getValueForId(derivedURI);
+ const XMLCh* schemaURI = fGrammarResolver->getStringPool()->getValueForId(derivedURI);
if (derivedURI != getScanner()->getEmptyNamespaceId()) {
aGrammar= (SchemaGrammar*) fGrammarResolver->getGrammar(schemaURI);
1.19 +13 -3 xml-xerces/c/src/xercesc/validators/schema/SchemaValidator.hpp
Index: SchemaValidator.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/validators/schema/SchemaValidator.hpp,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- SchemaValidator.hpp 14 Aug 2003 03:01:04 -0000 1.18
+++ SchemaValidator.hpp 5 Oct 2003 02:09:37 -0000 1.19
@@ -56,6 +56,9 @@
/*
* $Log$
+ * Revision 1.19 2003/10/05 02:09:37 neilg
+ * the validator now keeps track of the current complex and simple type (including if this is an xsi:type). This allows both the validator and the scanner to know what the current type is, without the need to modify the element declaration each time an xsi:type is seen
+ *
* Revision 1.18 2003/08/14 03:01:04 knoaman
* Code refactoring to improve performance of validation.
*
@@ -256,6 +259,7 @@
// Getter methods
// -----------------------------------------------------------------------
ComplexTypeInfo* getCurrentTypeInfo() const;
+ DatatypeValidator *getCurrentDatatypeValidator() const;
private:
// -----------------------------------------------------------------------
@@ -369,8 +373,9 @@
// -----------------------------------------------------------------------
// The following used internally in the validator
//
- // fXsiTypeValidator
- // The validator used for xsi type validation
+ // fCurrentDatatypeValidator
+ // The validator used for validating the content of elements
+ // with simple types
//
// fDatatypeBuffer
// Buffer for simple type element string content
@@ -392,7 +397,7 @@
GrammarResolver* fGrammarResolver;
QName* fXsiType;
bool fNil;
- DatatypeValidator* fXsiTypeValidator;
+ DatatypeValidator* fCurrentDatatypeValidator;
XMLBuffer* fNotationBuf;
XMLBuffer fDatatypeBuffer;
bool fTrailing;
@@ -438,6 +443,11 @@
if (fTypeStack->empty())
return 0;
return fTypeStack->peek();
+}
+
+inline DatatypeValidator * SchemaValidator::getCurrentDatatypeValidator() const
+{
+ return fCurrentDatatypeValidator;
}
// ---------------------------------------------------------------------------
---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org