TraverseSchema.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:302k
- if (!typeInfo) {
- validator = getElementTypeValidator(elem, typeStr, noErrorFound, anotherSchemaURI);
- }
- }
- }
- }
- // Set element declararion type information
- if (!isDuplicate) {
- elemDecl->setDatatypeValidator(validator);
- elemDecl->setComplexTypeInfo(typeInfo);
- }
- if (topLevel) {
- // Handle the substitutionGroup
- const XMLCh* subsGroupName = getElementAttValue(elem, SchemaSymbols::fgATT_SUBSTITUTIONGROUP);
- if (subsGroupName && *subsGroupName) {
- SchemaElementDecl* subsElemDecl = getSubstituteGroupElemDecl
- (
- elem
- , subsGroupName
- , noErrorFound
- );
- if (subsElemDecl) {
- if (isSubstitutionGroupCircular(elemDecl, subsElemDecl)) {
- reportSchemaError
- (
- elem
- , XMLUni::fgXMLErrDomain
- , XMLErrs::CircularSubsGroup
- , name
- );
- }
- else {
- // Check for substitution validity constraint
- // Substitution allowed (block and blockDefault) && same type
- if (isSubstitutionGroupValid(elem, subsElemDecl,typeInfo,validator,name)) {
- if (typeInfo == 0 && validator == 0 && noErrorFound) {
- typeInfo = subsElemDecl->getComplexTypeInfo();
- validator = subsElemDecl->getDatatypeValidator();
- }
- if (!isDuplicate) {
- XMLCh* elemBaseName = elemDecl->getBaseName();
- XMLCh* subsElemBaseName = subsElemDecl->getBaseName();
- int elemURI = elemDecl->getURI();
- int subsElemURI = subsElemDecl->getURI();
- elemDecl->setSubstitutionGroupElem(subsElemDecl);
- ValueVectorOf<SchemaElementDecl*>* subsElements =
- fValidSubstitutionGroups->get(subsElemBaseName, subsElemURI);
- if (!subsElements && fTargetNSURI != subsElemURI) {
- SchemaGrammar* aGrammar = (SchemaGrammar*)
- fGrammarResolver->getGrammar(fURIStringPool->getValueForId(subsElemURI));
- if (aGrammar) {
- subsElements = aGrammar->getValidSubstitutionGroups()->get(subsElemBaseName, subsElemURI);
- if (subsElements) {
- subsElements = new (fMemoryManager) ValueVectorOf<SchemaElementDecl*>(*subsElements);
- fValidSubstitutionGroups->put(subsElemBaseName, subsElemURI, subsElements);
- }
- else if (fSchemaInfo->circularImportExist(subsElemURI)) {
- aGrammar->getValidSubstitutionGroups()->put(
- subsElemBaseName, subsElemURI, new (fMemoryManager) ValueVectorOf<SchemaElementDecl*>(8, fMemoryManager));
- }
- }
- }
- if (!subsElements) {
- subsElements = new (fMemoryManager) ValueVectorOf<SchemaElementDecl*>(8, fMemoryManager);
- fValidSubstitutionGroups->put(subsElemBaseName, subsElemURI, subsElements);
- }
- subsElements->addElement(elemDecl);
- // update related subs. info in case of circular import
- BaseRefVectorEnumerator<SchemaInfo> importingEnum = fSchemaInfo->getImportingListEnumerator();
- while (importingEnum.hasMoreElements()) {
- const SchemaInfo& curRef = importingEnum.nextElement();
- SchemaGrammar* aGrammar = (SchemaGrammar*)
- fGrammarResolver->getGrammar(curRef.getTargetNSURIString());
- ValueVectorOf<SchemaElementDecl*>* subsElemList =
- aGrammar->getValidSubstitutionGroups()->get(subsElemBaseName, subsElemURI);
- if (subsElemList && !subsElemList->containsElement(elemDecl))
- subsElemList->addElement(elemDecl);
- }
- buildValidSubstitutionListB(elem, elemDecl, subsElemDecl);
- buildValidSubstitutionListF(elem, elemDecl, subsElemDecl);
- }
- }
- else {
- noErrorFound = false;
- }
- }
- }
- }
- }
- bool isAnyType = false;
- if (typeInfo == 0 && validator == 0) {
- if (noErrorFound) { // ur type
- contentSpecType = SchemaElementDecl::Any;
- isAnyType = true;
- }
- else {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::UntypedElement, name);
- }
- }
- // if element belongs to a compelx type
- if (typeInfo != 0) {
- contentSpecNode = typeInfo->getContentSpec();
- contentSpecType = (SchemaElementDecl::ModelTypes) typeInfo->getContentType();
- scopeDefined = typeInfo->getScopeDefined();
- validator = typeInfo->getDatatypeValidator();
- }
- // if element belongs to a simple type
- if (validator != 0) {
- contentSpecType = SchemaElementDecl::Simple;
- }
- // Now we can handle validation etc. of default and fixed attributes,
- // since we finally have all the type information.
- if(fixed && *fixed) {
- deflt = fixed;
- }
- if(deflt && *deflt) {
- try {
- if(validator == 0) { // in this case validate according to xs:string
- fDatatypeRegistry->getDatatypeValidator(SchemaSymbols::fgDT_STRING)->validate(deflt);
- } else {
- validator->validate(deflt);
- }
- }
- catch (const XMLException& excep) {
- reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
- }
- catch(...) {
- reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::DatatypeValidationFailure, deflt);
- }
- if(typeInfo != 0 &&
- contentSpecType != SchemaElementDecl::Simple &&
- contentSpecType != SchemaElementDecl::Mixed_Simple &&
- contentSpecType != SchemaElementDecl::Mixed_Complex) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NotSimpleOrMixedElement, name);
- }
- if(typeInfo != 0 &&
- ((contentSpecType == SchemaElementDecl::Mixed_Complex
- || contentSpecType == SchemaElementDecl::Mixed_Simple)
- && !emptiableParticle(contentSpecNode))) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::EmptiableMixedContent, name);
- }
- if (validator && (validator->getType() == DatatypeValidator::ID)) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::ElemIDValueConstraint, name, deflt);
- }
- }
- // set element information, but first check for duplicate elements with
- // different types.
- if (isDuplicate) {
- DatatypeValidator* eltDV = elemDecl->getDatatypeValidator();
- ComplexTypeInfo* eltTypeInfo = elemDecl->getComplexTypeInfo();
- if ( (eltTypeInfo != typeInfo) || (eltDV != validator)) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, name);
- }
- }
- else {
- elemDecl->setDatatypeValidator(validator);
- elemDecl->setComplexTypeInfo(typeInfo);
- elemDecl->setDefaultValue(deflt);
- elemDecl->setModelType(contentSpecType);
- elemDecl->setContentSpec(contentSpecNode);
- if (isAnyType) {
- elemDecl->setAttWildCard(new (fMemoryManager) SchemaAttDef(XMLUni::fgZeroLenString,
- XMLUni::fgZeroLenString,
- fEmptyNamespaceURI, XMLAttDef::Any_Any,
- XMLAttDef::ProcessContents_Lax,
- fMemoryManager));
- }
- // key/keyref/unique processing
- DOMElement* ic = XUtil::getFirstChildElementNS(elem, fgIdentityConstraints,
- SchemaSymbols::fgURI_SCHEMAFORSCHEMA, 3);
- ValueVectorOf<DOMElement*>* icNodes = 0;
- while (ic != 0) {
- if (XMLString::equals(ic->getLocalName(), SchemaSymbols::fgELT_KEY)) {
- traverseKey(ic, elemDecl);
- }
- else if (XMLString::equals(ic->getLocalName(), SchemaSymbols::fgELT_UNIQUE)) {
- traverseUnique(ic, elemDecl);
- }
- else {
- if (!icNodes) {
- icNodes = new (fMemoryManager) ValueVectorOf<DOMElement*>(8, fMemoryManager);
- }
- icNodes->addElement(ic);
- }
- ic = XUtil::getNextSiblingElementNS(ic, fgIdentityConstraints,
- SchemaSymbols::fgURI_SCHEMAFORSCHEMA, 3);
- }
- if (icNodes) {
- if (!fIC_ElementsNS) {
- fIC_ElementsNS = new (fMemoryManager) RefHashTableOf<ElemVector>(13, fMemoryManager);
- fIC_NamespaceDepthNS = new (fMemoryManager) RefHashTableOf<ValueVectorOf<unsigned int> >(13, fMemoryManager);
- fIC_NodeListNS = new (fMemoryManager) RefHashTableOf<ValueVectorOf<DOMElement*> >(29, true, new (fMemoryManager) HashPtr(), fMemoryManager);
- }
- if (fIC_ElementsNS->containsKey(fTargetNSURIString)) {
- fIC_Elements = fIC_ElementsNS->get(fTargetNSURIString);
- fIC_NamespaceDepth = fIC_NamespaceDepthNS->get(fTargetNSURIString);
- }
- if (!fIC_Elements) {
- fIC_Elements = new (fMemoryManager) ValueVectorOf<SchemaElementDecl*>(8, fMemoryManager);
- fIC_NamespaceDepth = new (fMemoryManager) ValueVectorOf<unsigned int>(8, fMemoryManager);
- fIC_ElementsNS->put((void*) fTargetNSURIString, fIC_Elements);
- fIC_NamespaceDepthNS->put((void*) fTargetNSURIString, fIC_NamespaceDepth);
- }
- fIC_NodeListNS->put(elemDecl, icNodes);
- fIC_Elements->addElement(elemDecl);
- fIC_NamespaceDepth->addElement(fSchemaInfo->getNamespaceScopeLevel());
- }
- }
- return new (fMemoryManager) QName(*elemDecl->getElementName());
- }
- const XMLCh* TraverseSchema::traverseNotationDecl(const DOMElement* const elem) {
- // ------------------------------------------------------------------
- // Check attributes
- // ------------------------------------------------------------------
- fAttributeCheck.checkAttributes(elem, GeneralAttributeCheck::E_Notation, this, true);
- // ------------------------------------------------------------------
- // Process notation attributes/elements
- // ------------------------------------------------------------------
- const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME);
- bool nameEmpty = (!name || !*name) ? true : false;
- if (nameEmpty) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoNameGlobalElement,
- SchemaSymbols::fgELT_NOTATION);
- return 0;
- }
- if (fNotationRegistry->containsKey(name, fTargetNSURI)) {
- return name;
- }
- const XMLCh* publicId = getElementAttValue(elem, SchemaSymbols::fgATT_PUBLIC);
- const XMLCh* systemId = getElementAttValue(elem, SchemaSymbols::fgATT_SYSTEM);
- fNotationRegistry->put((void*) fStringPool->getValueForId(fStringPool->addOrFind(name)),
- fTargetNSURI, 0);
- //we don't really care if something inside <notation> is wrong..
- checkContent(elem, XUtil::getFirstChildElement(elem), true);
- return name;
- }
- const XMLCh* TraverseSchema::traverseNotationDecl(const DOMElement* const elem,
- const XMLCh* const name,
- const XMLCh* const uriStr) {
- unsigned int uriId = fURIStringPool->addOrFind(uriStr);
- SchemaInfo* saveInfo = fSchemaInfo;
- if (fTargetNSURI != (int) uriId) {
- // Make sure that we have an explicit import statement.
- // Clause 4 of Schema Representation Constraint:
- // http://www.w3.org/TR/xmlschema-1/#src-resolve
- unsigned int uriId = fURIStringPool->addOrFind(uriStr);
- if (!fSchemaInfo->isImportingNS(uriId)) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, uriStr);
- return 0;
- }
- Grammar* grammar = fGrammarResolver->getGrammar(uriStr);
- if (grammar == 0 || grammar->getGrammarType() != Grammar::SchemaGrammarType) {
- reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, uriStr);
- return 0;
- }
- SchemaInfo* impInfo = fSchemaInfo->getImportInfo(uriId);
- if (!impInfo || impInfo->getProcessed()) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, uriStr, name);
- return 0;
- }
- fSchemaInfo = impInfo;
- fTargetNSURI = fSchemaInfo->getTargetNSURI();
- }
- DOMElement* notationElem = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_Notation,
- SchemaSymbols::fgELT_NOTATION, name, &fSchemaInfo);
- if (notationElem == 0) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::Notation_DeclNotFound, uriStr, name);
- return 0;
- }
- const XMLCh* notationName = traverseNotationDecl(notationElem);
- fSchemaInfo = saveInfo;
- fTargetNSURI = fSchemaInfo->getTargetNSURI();
- return notationName;
- }
- DatatypeValidator*
- TraverseSchema::traverseByList(const DOMElement* const rootElem,
- const DOMElement* const contentElem,
- const XMLCh* const typeName,
- const XMLCh* const qualifiedName,
- const int finalSet) {
- DatatypeValidator* baseValidator = 0;
- const XMLCh* baseTypeName = getElementAttValue(contentElem, SchemaSymbols::fgATT_ITEMTYPE);
- fAttributeCheck.checkAttributes(contentElem, GeneralAttributeCheck::E_List, this);
- if (XUtil::getNextSiblingElement(contentElem) != 0) {
- reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::SimpleTypeContentError);
- }
- DOMElement* content = 0;
- if (!baseTypeName || !*baseTypeName) { // must 'see' <simpleType>
- content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), false);
- if (!content) {
- reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::ExpectedSimpleTypeInList, typeName);
- popCurrentTypeNameStack();
- return 0;
- }
- if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_SIMPLETYPE)) {
- baseValidator = checkForSimpleTypeValidator(content, SchemaSymbols::XSD_LIST);
- }
- else {
- reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::ListUnionRestrictionError, typeName);
- popCurrentTypeNameStack();
- return 0;
- }
- content = XUtil::getNextSiblingElement(content);
- }
- else { // base was provided - get proper validator
- baseValidator = findDTValidator(contentElem, typeName, baseTypeName, SchemaSymbols::XSD_LIST);
- content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), true);
- }
- DatatypeValidator* newDV = 0;
-
- if (baseValidator) {
- if (!baseValidator->isAtomic()) {
- reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::AtomicItemType, baseTypeName);
- }
- else {
- // 'content' should be empty
- // If an annotation was encountered we have already traversed it in
- // checkContent in the case of a base provided (only allowed child is
- // an annotation).
- if (content != 0) { // report an error and continue
- reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::SimpleTypeDerivationByListError, typeName);
- }
- // create & register validator for "generated" type
- try {
- newDV = fDatatypeRegistry->createDatatypeValidator(
- qualifiedName, baseValidator, 0, 0, true, finalSet);
- }
- catch (const XMLException& excep) {
- reportSchemaError(contentElem, XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
- }
- catch(...) {
- reportSchemaError(contentElem, XMLUni::fgXMLErrDomain,
- XMLErrs::DatatypeValidatorCreationError, typeName);
- }
- }
- }
- popCurrentTypeNameStack();
- return newDV;
- }
- DatatypeValidator*
- TraverseSchema::traverseByRestriction(const DOMElement* const rootElem,
- const DOMElement* const contentElem,
- const XMLCh* const typeName,
- const XMLCh* const qualifiedName,
- const int finalSet) {
- DatatypeValidator* baseValidator = 0;
- DatatypeValidator* newDV = 0;
- const XMLCh* baseTypeName = getElementAttValue(contentElem, SchemaSymbols::fgATT_BASE);
- fAttributeCheck.checkAttributes(contentElem, GeneralAttributeCheck::E_Restriction, this);
- if (XUtil::getNextSiblingElement(contentElem) != 0) {
- reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::SimpleTypeContentError);
- }
- DOMElement* content = 0;
- if (!baseTypeName || !*baseTypeName) { // must 'see' <simpleType>
- content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), false);
- if (content == 0) {
- reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::ExpectedSimpleTypeInRestriction);
- popCurrentTypeNameStack();
- return 0;
- }
- if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_SIMPLETYPE)) {
- baseValidator = checkForSimpleTypeValidator(content);
- }
- else {
- reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::ListUnionRestrictionError, typeName);
- popCurrentTypeNameStack();
- return 0;
- }
- // Check for facets
- content = XUtil::getNextSiblingElement(content);
- }
- else { // base was provided - get proper validator
- baseValidator = findDTValidator(contentElem, typeName, baseTypeName, SchemaSymbols::XSD_RESTRICTION);
- content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), true);
- }
- if (baseValidator) {
- // Get facets if any existing
- RefHashTableOf<KVStringPair>* facets = 0;
- RefArrayVectorOf<XMLCh>* enums = 0;
- XMLBuffer pattern(128, fMemoryManager);
- XMLCh fixedFlagStr[16];
- unsigned int fixedFlag = 0;
- unsigned short scope = 0;
- bool isFirstPattern = true;
- while (content != 0) {
- if (content->getNodeType() == DOMNode::ELEMENT_NODE) {
- const XMLCh* facetName = content->getLocalName();
- try {
- scope = fAttributeCheck.getFacetId(facetName);
- }
- catch (...) {
- reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::InvalidFacetName, facetName);
- content = XUtil::getNextSiblingElement(content);
- continue;
- }
- const XMLCh* attValue = content->getAttribute(SchemaSymbols::fgATT_VALUE);
- fAttributeCheck.checkAttributes(content, scope, this);
- if (facets == 0) {
- facets = new (fMemoryManager) RefHashTableOf<KVStringPair>(29, true, fMemoryManager);
- }
- if (XMLString::equals(facetName, SchemaSymbols::fgELT_ENUMERATION)) {
- // REVISIT
- // if validator is a notation datatype validator, we need
- // to get the qualified name first before adding it to the
- // enum buffer
- if (!enums) {
- enums = new (fMemoryManager) RefArrayVectorOf<XMLCh>(8, true, fMemoryManager);
- }
- if (baseValidator->getType() == DatatypeValidator::NOTATION) {
- const XMLCh* localPart = getLocalPart(attValue);
- const XMLCh* prefix = getPrefix(attValue);
- const XMLCh* uriStr = (prefix && *prefix) ? resolvePrefixToURI(content, prefix) : fTargetNSURIString;
- unsigned int uriId = fURIStringPool->addOrFind(uriStr);
- if (!fNotationRegistry->containsKey(localPart, uriId)) {
- traverseNotationDecl(content, localPart, uriStr);
- }
- fBuffer.set(uriStr);
- fBuffer.append(chColon);
- fBuffer.append(localPart);
- enums->addElement(XMLString::replicate(fBuffer.getRawBuffer(), fMemoryManager));
- }
- else {
- enums->addElement(XMLString::replicate(attValue, fMemoryManager));
- }
- }
- else if (XMLString::equals(facetName, SchemaSymbols::fgELT_PATTERN)) {
- if (isFirstPattern) { // fBuffer.isEmpty() - overhead call
- isFirstPattern = false;
- pattern.set(attValue);
- }
- else { //datatypes: 5.2.4 pattern
- pattern.append(chPipe);
- pattern.append(attValue);
- }
- }
- else {
- if (facets->containsKey(facetName)) {
- reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateFacet, facetName);
- }
- else {
- if (XMLString::equals(facetName, SchemaSymbols::fgELT_WHITESPACE)
- && baseValidator->getType() != DatatypeValidator::String
- && !XMLString::equals(attValue, SchemaSymbols::fgWS_COLLAPSE)) {
- reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::WS_CollapseExpected, attValue);
- }
- else {
- const XMLCh* facetStr = fStringPool->getValueForId(fStringPool->addOrFind(facetName));
- facets->put((void*) facetStr, new (fMemoryManager) KVStringPair(facetStr, attValue, fMemoryManager));
- checkFixedFacet(content, facetStr, baseValidator, fixedFlag);
- }
- }
- }
- // REVISIT
- // check for annotation content - we are not checking whether the
- // return is empty or not. If not empty we should report an error
- checkContent(rootElem, XUtil::getFirstChildElement(content), true);
- }
- content = XUtil::getNextSiblingElement(content);
- } // end while
- if (!pattern.isEmpty()) {
- facets->put((void*) SchemaSymbols::fgELT_PATTERN,
- new (fMemoryManager) KVStringPair(SchemaSymbols::fgELT_PATTERN, pattern.getRawBuffer(), fMemoryManager));
- }
- if (fixedFlag) {
- XMLString::binToText(fixedFlag, fixedFlagStr, 15, 10);
- facets->put((void*) SchemaSymbols::fgATT_FIXED,
- new (fMemoryManager) KVStringPair(SchemaSymbols::fgATT_FIXED, fixedFlagStr, fMemoryManager));
- }
- try {
- newDV = fDatatypeRegistry->createDatatypeValidator(qualifiedName, baseValidator, facets, enums, false, finalSet);
- }
- catch (const XMLException& excep) {
- reportSchemaError(contentElem, XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
- }
- catch(...) {
- reportSchemaError(contentElem, XMLUni::fgXMLErrDomain,
- XMLErrs::DatatypeValidatorCreationError, typeName);
- }
- }
- popCurrentTypeNameStack();
- return newDV;
- }
- DatatypeValidator*
- TraverseSchema::traverseByUnion(const DOMElement* const rootElem,
- const DOMElement* const contentElem,
- const XMLCh* const typeName,
- const XMLCh* const qualifiedName,
- const int finalSet,
- int baseRefContext) {
- fAttributeCheck.checkAttributes(contentElem, GeneralAttributeCheck::E_Union, this);
- if (XUtil::getNextSiblingElement(contentElem) != 0) {
- reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::SimpleTypeContentError);
- }
- int size = 1;
- const XMLCh* baseTypeName = getElementAttValue(contentElem, SchemaSymbols::fgATT_MEMBERTYPES);
- DatatypeValidator* baseValidator = 0;
- RefVectorOf<DatatypeValidator>* validators = new (fMemoryManager) RefVectorOf<DatatypeValidator>(4, false, fMemoryManager);
- Janitor<DVRefVector> janValidators(validators);
- DOMElement* content = 0;
- if (baseTypeName && *baseTypeName) { //base was provided - get proper validator.
- XMLStringTokenizer unionMembers(baseTypeName, fMemoryManager);
- int tokCount = unionMembers.countTokens();
- for (int i = 0; i < tokCount; i++) {
- const XMLCh* memberTypeName = unionMembers.nextToken();
- baseValidator = findDTValidator(contentElem, typeName, memberTypeName, SchemaSymbols::XSD_UNION);
- if (baseValidator == 0) {
- popCurrentTypeNameStack();
- return 0;
- }
- validators->addElement(baseValidator);
- }
- content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), true);
- }
- else { // must 'see' <simpleType>
- content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), false);
- if (content == 0) {
- reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::ExpectedSimpleTypeInUnion, typeName);
- popCurrentTypeNameStack();
- return 0;
- }
- if (!XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_SIMPLETYPE)) {
- reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::ListUnionRestrictionError, typeName);
- popCurrentTypeNameStack();
- return 0;
- }
- }
- // process union content of simpleType children if any
- while (content != 0) {
- if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_SIMPLETYPE)) {
- baseValidator = checkForSimpleTypeValidator(content, baseRefContext | SchemaSymbols::XSD_UNION);
- if (baseValidator == 0) {
- popCurrentTypeNameStack();
- return 0;
- }
- validators->addElement(baseValidator);
- }
- else {
- // REVISIT - should we break. For now, we will continue and move to
- // the next sibling
- reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::ListUnionRestrictionError, typeName);
- }
- content = XUtil::getNextSiblingElement(content);
- } // end while
- DatatypeValidator* newDV = 0;
- janValidators.orphan();
- try {
- newDV = fDatatypeRegistry->createDatatypeValidator(qualifiedName, validators, finalSet);
- }
- catch (const XMLException& excep) {
- reportSchemaError(contentElem, XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
- }
- catch(...) {
- reportSchemaError(contentElem, XMLUni::fgXMLErrDomain,
- XMLErrs::DatatypeValidatorCreationError, typeName);
- }
- popCurrentTypeNameStack();
- return newDV;
- }
- /**
- * Traverse SimpleContent Declaration
- *
- * <simpleContent
- * id = ID
- * {any attributes with non-schema namespace...}>
- *
- * Content: (annotation? , (restriction | extension))
- * </simpleContent>
- *
- * <restriction
- * base = QNAME
- * id = ID
- * {any attributes with non-schema namespace...}>
- *
- * Content: (annotation?, (simpleType?, (minExclusive | minInclusive
- * | maxExclusive | maxInclusive | totalDigits | fractionDigits
- * | length | minLength | maxLength | enumeration | pattern
- * | whiteSpace)*)?, ((attribute | attributeGroup)* , anyAttribute?))
- * </restriction>
- *
- * <extension
- * base = QNAME
- * id = ID
- * {any attributes with non-schema namespace...}>
- * Content: (annotation? , ((attribute | attributeGroup)* , anyAttribute?))
- * </extension>
- *
- */
- void TraverseSchema::traverseSimpleContentDecl(const XMLCh* const typeName,
- const XMLCh* const qualifiedName,
- const DOMElement* const contentDecl,
- ComplexTypeInfo* const typeInfo)
- {
- // -----------------------------------------------------------------------
- // Check Attributes
- // -----------------------------------------------------------------------
- fAttributeCheck.checkAttributes(contentDecl, GeneralAttributeCheck::E_SimpleContent, this);
- // -----------------------------------------------------------------------
- // Set the content type to be simple, and initialize content spec handle
- // -----------------------------------------------------------------------
- typeInfo->setContentType(SchemaElementDecl::Simple);
- DOMElement* simpleContent = checkContent(contentDecl, XUtil::getFirstChildElement(contentDecl), false);
- // If there are no children, return
- if (simpleContent == 0) {
- reportSchemaError(contentDecl, XMLUni::fgXMLErrDomain, XMLErrs::EmptySimpleTypeContent);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- // -----------------------------------------------------------------------
- // The content should be either "restriction" or "extension"
- // -----------------------------------------------------------------------
- const XMLCh* const contentName = simpleContent->getLocalName();
- if (XMLString::equals(contentName, SchemaSymbols::fgATTVAL_RESTRICTION)) {
- fAttributeCheck.checkAttributes(simpleContent, GeneralAttributeCheck::E_Restriction, this);
- typeInfo->setDerivedBy(SchemaSymbols::XSD_RESTRICTION);
- }
- else if (XMLString::equals(contentName, SchemaSymbols::fgATTVAL_EXTENSION)) {
- fAttributeCheck.checkAttributes(simpleContent, GeneralAttributeCheck::E_Extension, this);
- typeInfo->setDerivedBy(SchemaSymbols::XSD_EXTENSION);
- }
- else {
- reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidSimpleContent);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- // -----------------------------------------------------------------------
- // Handle the base type name
- // -----------------------------------------------------------------------
- const XMLCh* baseName = getElementAttValue(simpleContent, SchemaSymbols::fgATT_BASE);
- if (!baseName || !*baseName) {
- reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::UnspecifiedBase);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- const XMLCh* prefix = getPrefix(baseName);
- const XMLCh* localPart = getLocalPart(baseName);
- const XMLCh* uri = resolvePrefixToURI(simpleContent, prefix);
- DatatypeValidator* baseValidator = getDatatypeValidator(uri, localPart);
- if (baseValidator != 0) {
- // check that the simpleType does not preclude derivation by extension
- if ((baseValidator->getFinalSet() & SchemaSymbols::XSD_EXTENSION) == typeInfo->getDerivedBy()) {
- reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::DisallowedSimpleTypeExtension,
- baseName, typeName);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- typeInfo->setBaseComplexTypeInfo(0);
- typeInfo->setBaseDatatypeValidator(baseValidator);
- }
- else {
- // check for 'anyType'
- if (XMLString::equals(uri, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)
- && XMLString::equals(localPart, SchemaSymbols::fgATTVAL_ANYTYPE)) {
- reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidSimpleContentBase, baseName);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- processBaseTypeInfo(simpleContent, 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();
- bool simpleTypeRequired = false;
- if (baseTypeInfo) {
- if (baseTypeInfo->getContentType() != SchemaElementDecl::Simple) {
- // Schema Errata: E1-27
- if (typeInfo->getDerivedBy() == SchemaSymbols::XSD_RESTRICTION
- && ((baseTypeInfo->getContentType() == SchemaElementDecl::Mixed_Simple
- || baseTypeInfo->getContentType() == SchemaElementDecl::Mixed_Complex)
- && emptiableParticle(baseTypeInfo->getContentSpec()))) {
- simpleTypeRequired = true;
- }
- else {
- reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidSimpleContentBase, baseName);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- }
- if ((baseTypeInfo->getFinalSet() & typeInfo->getDerivedBy()) != 0) {
- reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::ForbiddenDerivation, baseName);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- }
- // -----------------------------------------------------------------------
- // Process the content of the derivation
- // -----------------------------------------------------------------------
- //Skip over any annotations in the restriction or extension elements
- DOMElement* content = checkContent(simpleContent, XUtil::getFirstChildElement(simpleContent), true);
- if (typeInfo->getDerivedBy() == SchemaSymbols::XSD_RESTRICTION) {
- //Schema Spec: 5.11: Complex Type Definition Properties Correct: 2
- if (typeInfo->getBaseDatatypeValidator() != 0) {
- reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidComplexTypeBase, baseName);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- else {
- typeInfo->setBaseDatatypeValidator(baseTypeInfo->getDatatypeValidator());
- }
- if (content != 0) {
- // ---------------------------------------------------------------
- // There may be a simple type definition in the restriction
- // element. The data type validator will be based on it, if
- // specified
- // ---------------------------------------------------------------
- if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_SIMPLETYPE)) {
- DatatypeValidator* simpleTypeDV = traverseSimpleTypeDecl(content, false);
- if (simpleTypeDV) {
- // Check that the simpleType validator is validly derived
- // from base
- DatatypeValidator* baseDV = typeInfo->getBaseDatatypeValidator();
- if (baseDV && !baseDV->isSubstitutableBy(simpleTypeDV)) {
- reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::InvalidContentRestriction);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- typeInfo->setBaseDatatypeValidator(simpleTypeDV);
- content = XUtil::getNextSiblingElement(content);
- }
- else {
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- }
- // Schema Errata E1-27
- // Complex Type Definition Restriction OK: 2.2
- else if (simpleTypeRequired) {
- reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::CT_SimpleTypeChildRequired);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- // ---------------------------------------------------------------
- // Build up the facet info
- // ---------------------------------------------------------------
- RefHashTableOf<KVStringPair>* facets = 0;
- RefArrayVectorOf<XMLCh>* enums = 0;
- XMLBuffer pattern(128, fMemoryManager);
- XMLCh fixedFlagStr[16];
- unsigned int fixedFlag = 0;
- unsigned short scope = 0;
- bool isFirstPattern = true;
- while (content != 0) {
- const XMLCh* facetName = content->getLocalName();
- // if not a valid facet, break from the loop
- try {
- scope = fAttributeCheck.getFacetId(facetName);
- }
- catch(...) {
- break;
- }
- if (content->getNodeType() == DOMNode::ELEMENT_NODE) {
- fAttributeCheck.checkAttributes(content, scope, this);
- const XMLCh* attValue = content->getAttribute(SchemaSymbols::fgATT_VALUE);
- if (facets == 0) {
- facets = new (fMemoryManager) RefHashTableOf<KVStringPair>(29, true, fMemoryManager);
- }
- if (XMLString::equals(facetName, SchemaSymbols::fgELT_ENUMERATION)) {
- if (!enums) {
- enums = new (fMemoryManager) RefArrayVectorOf<XMLCh>(8, true, fMemoryManager);
- }
- enums->addElement(XMLString::replicate(attValue, fMemoryManager));
- }
- else if (XMLString::equals(facetName, SchemaSymbols::fgELT_PATTERN)) {
- if (isFirstPattern) { // fBuffer.isEmpty() - overhead call
- isFirstPattern = false;
- pattern.set(attValue);
- }
- else { //datatypes: 5.2.4 pattern
- pattern.append(chPipe);
- pattern.append(attValue);
- }
- }
- else {
- if (facets->containsKey(facetName)) {
- reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateFacet, facetName);
- }
- else {
- const XMLCh* facetNameStr =
- fStringPool->getValueForId(fStringPool->addOrFind(facetName));
- facets->put((void*) facetNameStr, new (fMemoryManager) KVStringPair(facetNameStr, attValue, fMemoryManager));
- checkFixedFacet(content, facetNameStr, typeInfo->getBaseDatatypeValidator(), fixedFlag);
- }
- }
- }
- content = XUtil::getNextSiblingElement(content);
- }
- if (facets) {
- if (!pattern.isEmpty()) {
- facets->put
- (
- (void*) SchemaSymbols::fgELT_PATTERN,
- new (fMemoryManager) KVStringPair
- (
- SchemaSymbols::fgELT_PATTERN,
- pattern.getRawBuffer()
- )
- );
- }
- if (fixedFlag) {
- XMLString::binToText(fixedFlag, fixedFlagStr, 15, 10);
- facets->put((void*) SchemaSymbols::fgATT_FIXED,
- new (fMemoryManager) KVStringPair(SchemaSymbols::fgATT_FIXED, fixedFlagStr, fMemoryManager));
- }
- try {
- typeInfo->setDatatypeValidator
- (
- fDatatypeRegistry->createDatatypeValidator
- (
- qualifiedName,
- typeInfo->getBaseDatatypeValidator(),
- facets, enums, false, 0
- )
- );
- }
- catch (const XMLException& excep) {
- reportSchemaError(simpleContent, XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
- }
- catch(...) {
- reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::DatatypeValidatorCreationError, typeName);
- }
- }
- else {
- typeInfo->setDatatypeValidator(typeInfo->getBaseDatatypeValidator());
- }
- }
- else {
- // Schema Errata E1-27
- // Complex Type Definition Restriction OK: 2.2
- if (simpleTypeRequired) {
- reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::CT_SimpleTypeChildRequired);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- typeInfo->setDatatypeValidator(typeInfo->getBaseDatatypeValidator());
- }
- } // end RESTRICTION
- else { // EXTENSION
- ComplexTypeInfo* baseTypeInfo = typeInfo->getBaseComplexTypeInfo();
- if (baseTypeInfo!= 0) {
- typeInfo->setBaseDatatypeValidator(baseTypeInfo->getDatatypeValidator());
- }
- typeInfo->setDatatypeValidator(typeInfo->getBaseDatatypeValidator());
- }
- // -----------------------------------------------------------------------
- // Process attributes if any
- // -----------------------------------------------------------------------
- processAttributes(simpleContent, content, baseName, localPart, uri, typeInfo);
- if (XUtil::getNextSiblingElement(simpleContent) != 0) {
- reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInSimpleContent);
- }
- } // End of function traverseSimpleContentDecl
- /**
- * Traverse complexContent Declaration
- *
- * <complexContent
- * id = ID
- * mixed = boolean
- * {any attributes with non-schema namespace...}>
- *
- * Content: (annotation? , (restriction | extension))
- * </complexContent>
- *
- * <restriction
- * base = QNAME
- * id = ID
- * {any attributes with non-schema namespace...}>
- *
- * Content: (annotation? , (group | all | choice | sequence)?,
- * ((attribute | attributeGroup)* , anyAttribute?))
- * </restriction>
- *
- * <extension
- * base = QNAME
- * id = ID
- * {any attributes with non-schema namespace...}>
- * Content: (annotation? , (group | all | choice | sequence)?,
- * ((attribute | attributeGroup)* , anyAttribute?))
- * </extension>
- */
- void TraverseSchema::traverseComplexContentDecl(const XMLCh* const typeName,
- const DOMElement* const contentDecl,
- ComplexTypeInfo* const typeInfo,
- const bool isMixed)
- {
- // ------------------------------------------------------------------
- // Check attributes
- // ------------------------------------------------------------------
- fAttributeCheck.checkAttributes(contentDecl, GeneralAttributeCheck::E_ComplexContent, this);
- // -----------------------------------------------------------------------
- // Determine whether the content is mixed, or element-only
- // Setting here overrides any setting on the complex type decl
- // -----------------------------------------------------------------------
- const XMLCh* const mixed = getElementAttValue(contentDecl, SchemaSymbols::fgATT_MIXED);
- bool mixedContent = isMixed;
- if (mixed) {
- if (XMLString::equals(mixed, SchemaSymbols::fgATTVAL_TRUE)
- || XMLString::equals(mixed, fgValueOne)) {
- mixedContent = true;
- }
- else if (XMLString::equals(mixed, SchemaSymbols::fgATTVAL_FALSE)
- || XMLString::equals(mixed, fgValueZero)) {
- mixedContent = false;
- }
- }
- // -----------------------------------------------------------------------
- // Since the type must have complex content, set the simple type validators
- // to null
- // -----------------------------------------------------------------------
- typeInfo->setDatatypeValidator(0);
- typeInfo->setBaseDatatypeValidator(0);
- DOMElement* complexContent = checkContent(contentDecl,XUtil::getFirstChildElement(contentDecl),false);
- // If there are no children, return
- if (complexContent == 0) {
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- // -----------------------------------------------------------------------
- // The content should be either "restriction" or "extension"
- // -----------------------------------------------------------------------
- const XMLCh* const complexContentName = complexContent->getLocalName();
- if (XMLString::equals(complexContentName, SchemaSymbols::fgELT_RESTRICTION)) {
- typeInfo->setDerivedBy(SchemaSymbols::XSD_RESTRICTION);
- }
- else if (XMLString::equals(complexContentName, SchemaSymbols::fgELT_EXTENSION)) {
- typeInfo->setDerivedBy(SchemaSymbols::XSD_EXTENSION);
- }
- else {
- reportSchemaError(complexContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidComplexContent);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- // -----------------------------------------------------------------------
- // Handle the base type name
- // -----------------------------------------------------------------------
- const XMLCh* baseName = getElementAttValue(complexContent, SchemaSymbols::fgATT_BASE);
- if (!baseName || !*baseName) {
- reportSchemaError(complexContent, XMLUni::fgXMLErrDomain, XMLErrs::UnspecifiedBase);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- const XMLCh* prefix = getPrefix(baseName);
- const XMLCh* localPart = getLocalPart(baseName);
- const XMLCh* uri = resolvePrefixToURI(complexContent, prefix);
- bool isBaseAnyType = false;
- // -------------------------------------------------------------
- // check if the base is "anyType"
- // -------------------------------------------------------------
- if (XMLString::equals(uri, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) &&
- XMLString::equals(localPart, SchemaSymbols::fgATTVAL_ANYTYPE)) {
- isBaseAnyType = true;
- }
- else {
- processBaseTypeInfo(complexContent, baseName, localPart, uri, typeInfo);
- //Check that the base is a complex type
- if (typeInfo->getBaseComplexTypeInfo() == 0) {
- reportSchemaError(complexContent, XMLUni::fgXMLErrDomain, XMLErrs::BaseNotComplexType);
- throw TraverseSchema::InvalidComplexTypeInfo;
- }
- }
- if (fCurrentGroupInfo) // defer processing until later
- throw TraverseSchema::RecursingElement;
- // -----------------------------------------------------------------------
- // Process the content of the derivation
- // -----------------------------------------------------------------------
- //Skip over any annotations in the restriction or extension elements
- DOMElement* content = checkContent(complexContent, XUtil::getFirstChildElement(complexContent), true);
- processComplexContent(complexContent, typeName, content, typeInfo, baseName, localPart,
- uri, mixedContent, isBaseAnyType);
- if (XUtil::getNextSiblingElement(complexContent) != 0) {
- reportSchemaError(complexContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInComplexContent);
- }
- }
- /**
- * <anyAttribute
- * id = ID
- * namespace = ((##any | ##other) | list of (anyURI | (##targetNamespace | ##local)))>
- * processContents = (lax | skip | strict) : strict
- * Content: (annotation?)
- * </anyAttribute>
- */
- SchemaAttDef* TraverseSchema::traverseAnyAttribute(const DOMElement* const elem) {
- // -----------------------------------------------------------------------
- // Check Attributes
- // -----------------------------------------------------------------------
- fAttributeCheck.checkAttributes(elem, GeneralAttributeCheck::E_AnyAttribute, this);
- // ------------------------------------------------------------------
- // First, handle any ANNOTATION declaration
- // ------------------------------------------------------------------
- if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AnyAttributeContentError);
- }
- // ------------------------------------------------------------------
- // Get attributes
- // ------------------------------------------------------------------
- const XMLCh* const processContents =
- getElementAttValue(elem, SchemaSymbols::fgATT_PROCESSCONTENTS);
- const XMLCh* const nameSpace =
- getElementAttValue(elem, SchemaSymbols::fgATT_NAMESPACE);
- // ------------------------------------------------------------------
- // Set default att type based on 'processContents' value
- // ------------------------------------------------------------------
- XMLAttDef::DefAttTypes attDefType = XMLAttDef::ProcessContents_Strict;
- if ((!processContents || !*processContents)
- || XMLString::equals(processContents, SchemaSymbols::fgATTVAL_STRICT)) {
- // Do nothing - defaulted already
- }
- else if (XMLString::equals(processContents, SchemaSymbols::fgATTVAL_SKIP)) {
- attDefType = XMLAttDef::ProcessContents_Skip;
- }
- else if (XMLString::equals(processContents, SchemaSymbols::fgATTVAL_LAX)) {
- attDefType = XMLAttDef::ProcessContents_Lax;
- }
- // ------------------------------------------------------------------
- // Process 'namespace' attribute
- // ------------------------------------------------------------------
- int uriIndex = fEmptyNamespaceURI;
- XMLAttDef::AttTypes attType = XMLAttDef::Any_Any;
- ValueVectorOf<unsigned int> namespaceList(8, fMemoryManager);
- if ((!nameSpace || !*nameSpace)
- || XMLString::equals(nameSpace, SchemaSymbols::fgATTVAL_TWOPOUNDANY)) {
- // Do nothing - defaulted already
- }
- else if (XMLString::equals(nameSpace, SchemaSymbols::fgATTVAL_TWOPOUNDOTHER)) {
- attType = XMLAttDef::Any_Other;
- uriIndex = fTargetNSURI;
- }
- else {
- XMLStringTokenizer tokenizer(nameSpace, fMemoryManager);
- DatatypeValidator* anyURIDV = fDatatypeRegistry->getDatatypeValidator(SchemaSymbols::fgDT_ANYURI);
- attType = XMLAttDef::Any_List;
- while (tokenizer.hasMoreTokens()) {
- const XMLCh* token = tokenizer.nextToken();
- if (XMLString::equals(token, SchemaSymbols::fgATTVAL_TWOPOUNDLOCAL)) {
- uriIndex = fEmptyNamespaceURI;
- }
- else if (XMLString::equals(token, SchemaSymbols::fgATTVAL_TWOPOUNDTRAGETNAMESPACE)) {
- uriIndex = fTargetNSURI;
- }
- else {
- try {
- anyURIDV->validate(token);
- }
- catch(const XMLException& excep) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DisplayErrorMessage, excep.getMessage());
- }
- uriIndex = fURIStringPool->addOrFind(token);
- }
- if (!namespaceList.containsElement(uriIndex)) {
- namespaceList.addElement(uriIndex);
- }
- }
- uriIndex = fEmptyNamespaceURI;
- }
- // ------------------------------------------------------------------
- // Create wildcard attribute
- // ------------------------------------------------------------------
- SchemaAttDef* attDef = new (fMemoryManager) SchemaAttDef(XMLUni::fgZeroLenString,
- XMLUni::fgZeroLenString,
- uriIndex, attType, attDefType,
- fMemoryManager);
- if (namespaceList.size()) {
- attDef->setNamespaceList(&namespaceList);
- }
- return attDef;
- }
- /**
- * <key
- * id = ID
- * name = NCName
- * Content: (annotation?, (selector, field+))
- * </key>
- */
- void TraverseSchema::traverseKey(const DOMElement* const icElem,
- SchemaElementDecl* const elemDecl) {
- // -----------------------------------------------------------------------
- // Check Attributes
- // -----------------------------------------------------------------------
- fAttributeCheck.checkAttributes(icElem, GeneralAttributeCheck::E_Key, this);
- // -----------------------------------------------------------------------
- // Create identity constraint
- // -----------------------------------------------------------------------
- const XMLCh* name = getElementAttValue(icElem, SchemaSymbols::fgATT_NAME);
- if (!name || !*name) {
- return;
- }
- if (!XMLString::isValidNCName(name)) {
- reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
- SchemaSymbols::fgELT_KEY, name);
- return;
- }
- if (!fIdentityConstraintNames) {
- fIdentityConstraintNames = new (fMemoryManager) RefHash2KeysTableOf<IdentityConstraint>(29, (bool) false, fMemoryManager);
- }
- if (fIdentityConstraintNames->containsKey(name, fTargetNSURI)) {
- reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_DuplicateDecl, name);
- return;
- }
- IC_Key* icKey = new (fMemoryManager) IC_Key(name, elemDecl->getBaseName(), fMemoryManager);
- Janitor<IC_Key> janKey(icKey);
- fIdentityConstraintNames->put((void*) name, fTargetNSURI, icKey);
- // -----------------------------------------------------------------------
- // Get selector and fields
- // -----------------------------------------------------------------------
- if (!traverseIdentityConstraint(icKey, icElem)) {
- fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0);
- return;
- }
- // -----------------------------------------------------------------------
- // Add key to element declaration
- // -----------------------------------------------------------------------
- elemDecl->addIdentityConstraint(icKey);
- janKey.orphan();
- }
- /**
- * <unique
- * id = ID
- * name = NCName
- * Content: (annotation?, (selector, field+))
- * </unique>
- */
- void TraverseSchema::traverseUnique(const DOMElement* const icElem,
- SchemaElementDecl* const elemDecl) {
- // -----------------------------------------------------------------------
- // Check Attributes
- // -----------------------------------------------------------------------
- fAttributeCheck.checkAttributes(icElem, GeneralAttributeCheck::E_Unique, this);
- // -----------------------------------------------------------------------
- // Create identity constraint
- // -----------------------------------------------------------------------
- const XMLCh* name = getElementAttValue(icElem, SchemaSymbols::fgATT_NAME);
- if (!name || !*name) {
- return;
- }
- if (!XMLString::isValidNCName(name)) {
- reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
- SchemaSymbols::fgELT_UNIQUE, name);
- return;
- }
- if (!fIdentityConstraintNames) {
- fIdentityConstraintNames = new (fMemoryManager) RefHash2KeysTableOf<IdentityConstraint>(29, (bool) false, fMemoryManager);
- }
- if (fIdentityConstraintNames->containsKey(name, fTargetNSURI)) {
- reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_DuplicateDecl, name);
- return;
- }
- IC_Unique* icUnique = new (fMemoryManager) IC_Unique(name, elemDecl->getBaseName(), fMemoryManager);
- Janitor<IC_Unique> janUnique(icUnique);
- fIdentityConstraintNames->put((void*) name, fTargetNSURI, icUnique);
- // -----------------------------------------------------------------------
- // Get selector and fields
- // -----------------------------------------------------------------------
- if (!traverseIdentityConstraint(icUnique, icElem)) {
- fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0);
- return;
- }
- // -----------------------------------------------------------------------
- // Add identity cosntraints to element declaration
- // -----------------------------------------------------------------------
- elemDecl->addIdentityConstraint(icUnique);
- janUnique.orphan();
- }
- /**
- * <keyref
- * id = ID
- * name = NCName
- * refer = QName
- * Content: (annotation?, (selector, field+))
- * </keyref>
- */
- void TraverseSchema::traverseKeyRef(const DOMElement* const icElem,
- SchemaElementDecl* const elemDecl,
- const unsigned int namespaceDepth) {
- // -----------------------------------------------------------------------
- // Check Attributes
- // -----------------------------------------------------------------------
- fAttributeCheck.checkAttributes(icElem, GeneralAttributeCheck::E_KeyRef, this);
- // -----------------------------------------------------------------------
- // Verify that key reference "refer" attribute is valid
- // -----------------------------------------------------------------------
- const XMLCh* name = getElementAttValue(icElem, SchemaSymbols::fgATT_NAME);
- const XMLCh* refer = getElementAttValue(icElem, SchemaSymbols::fgATT_REFER);
- if ((!name || !*name) || (!refer || !*refer)) {
- return;
- }
- if (!XMLString::isValidNCName(name)) {
- reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
- SchemaSymbols::fgELT_KEYREF, name);
- return;
- }
- const XMLCh* prefix = getPrefix(refer);
- const XMLCh* localPart = getLocalPart(refer);
- const XMLCh* uriStr = resolvePrefixToURI(icElem, prefix, namespaceDepth);
- IdentityConstraint* icKey = (fIdentityConstraintNames)
- ? fIdentityConstraintNames->get(localPart, fURIStringPool->addOrFind(uriStr)) : 0;
- if (!icKey) {
- reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_KeyRefReferNotFound, name, localPart);
- return;
- }
- // -----------------------------------------------------------------------
- // Create identity constraint
- // -----------------------------------------------------------------------
- if(fIdentityConstraintNames->containsKey(name, fTargetNSURI)) {
- reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_DuplicateDecl, name);
- return;
- }
- IC_KeyRef* icKeyRef = new (fMemoryManager) IC_KeyRef(name, elemDecl->getBaseName(), icKey, fMemoryManager);
- Janitor<IC_KeyRef> janKeyRef(icKeyRef);
- fIdentityConstraintNames->put((void*) name, fTargetNSURI, icKeyRef);
- // -----------------------------------------------------------------------
- // Get selector and fields
- // -----------------------------------------------------------------------
- if (!traverseIdentityConstraint(icKeyRef, icElem)) {
- fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0);
- return;
- }
- // -----------------------------------------------------------------------
- // Add key reference to element decl
- // -----------------------------------------------------------------------
- if (icKeyRef->getFieldCount() != icKey->getFieldCount()) {
- fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0);
- reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_KeyRefCardinality,
- name, icKey->getIdentityConstraintName());
- }
- else {
- elemDecl->addIdentityConstraint(icKeyRef);
- janKeyRef.orphan();
- }
- }
- bool TraverseSchema::traverseIdentityConstraint(IdentityConstraint* const ic,
- const DOMElement* const icElem) {
- // ------------------------------------------------------------------
- // First, handle any ANNOTATION declaration
- // ------------------------------------------------------------------
- DOMElement* elem = checkContent(icElem, XUtil::getFirstChildElement(icElem), false);
- // ------------------------------------------------------------------
- // Get selector
- // ------------------------------------------------------------------
- if (elem == 0) {
- // reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent);
- return false;
- }
- if (!XMLString::equals(elem->getLocalName(), SchemaSymbols::fgELT_SELECTOR)) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent);
- return false;
- }
- fAttributeCheck.checkAttributes(elem, GeneralAttributeCheck::E_Selector, this);
- checkContent(icElem, XUtil::getFirstChildElement(elem), true);
- // ------------------------------------------------------------------
- // Get xpath attribute
- // ------------------------------------------------------------------
- const XMLCh* xpathExpr = getElementAttValue(elem, SchemaSymbols::fgATT_XPATH, true);
- unsigned int xpathLen = XMLString::stringLen(xpathExpr);
- if (!xpathExpr || !xpathLen) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::IC_XPathExprMissing);
- return false;
- }
- fBuffer.reset();
- unsigned int startIndex = 0;
-
- while (startIndex < xpathLen) {
- if (!XMLString::startsWith(xpathExpr + startIndex, fgForwardSlash)
- && !XMLString::startsWith(xpathExpr + startIndex, fgDot)) {
- fBuffer.append(fgDotForwardSlash);
- }
- int chOffset = XMLString::indexOf(xpathExpr, chPipe, startIndex);
- if (chOffset == -1)
- break;
- fBuffer.append(xpathExpr + startIndex, chOffset + 1 - startIndex);
- startIndex = chOffset + 1;
- }
- if (startIndex < xpathLen)
- fBuffer.append(xpathExpr + startIndex);
- // ------------------------------------------------------------------
- // Parse xpath expression
- // ------------------------------------------------------------------
- try {
- XercesXPath* sXPath = new (fMemoryManager) XercesXPath(fBuffer.getRawBuffer(), fStringPool, fNamespaceScope, fEmptyNamespaceURI, true, fMemoryManager);
- IC_Selector* icSelector = new (fMemoryManager) IC_Selector(sXPath, ic);
- ic->setSelector(icSelector);
- }
- catch (const XPathException& e) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DisplayErrorMessage, e.getMessage());
- return false;
- }
- // ------------------------------------------------------------------
- // Get fields
- // ------------------------------------------------------------------
- elem = XUtil::getNextSiblingElement(elem);
- if (elem == 0) {
- reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent);
- return false;
- }
- while (elem != 0) {
- if (!XMLString::equals(elem->getLocalName(), SchemaSymbols::fgELT_FIELD)) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent);
- }
- else {
- // General Attribute Checking
- fAttributeCheck.checkAttributes(elem, GeneralAttributeCheck::E_Field, this);
- checkContent(icElem, XUtil::getFirstChildElement(elem), true);
- // xpath expression parsing
- xpathExpr = getElementAttValue(elem, SchemaSymbols::fgATT_XPATH, true);
- if (!xpathExpr || !*xpathExpr) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::IC_XPathExprMissing);
- return false;
- }
- if (XMLString::startsWith(xpathExpr, fgForwardSlash)
- || XMLString::startsWith(xpathExpr, fgDot)) {
- fBuffer.set(xpathExpr);
- }
- else {
- fBuffer.set(fgDotForwardSlash);
- fBuffer.append(xpathExpr);
- }
- try {
- XercesXPath* fieldXPath = new (fMemoryManager) XercesXPath
- (
- fBuffer.getRawBuffer()
- , fStringPool
- , fNamespaceScope
- , fEmptyNamespaceURI
- , false
- , fMemoryManager
- );
- IC_Field* icField = new (fMemoryManager) IC_Field(fieldXPath, ic);
- ic->addField(icField);
- }
- catch (const XPathException& e) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DisplayErrorMessage, e.getMessage());
- return false;
- }
- }
- elem = XUtil::getNextSiblingElement(elem);
- }
- if (ic->getFieldCount() == 0) {
- return false;
- }
- return true;
- }
- // ---------------------------------------------------------------------------
- // TraverseSchema: Helper methods
- // ---------------------------------------------------------------------------
- void TraverseSchema::retrieveNamespaceMapping(const DOMElement* const schemaRoot) {
- DOMNamedNodeMap* schemaEltAttrs = schemaRoot->getAttributes();
- bool seenXMLNS = false;
- int attrCount = schemaEltAttrs->getLength();
- for (int i = 0; i < attrCount; i++) {
- DOMNode* attribute = schemaEltAttrs->item(i);
- if (!attribute) {
- break;
- }
- const XMLCh* attName = attribute->getNodeName();
- // starts with 'xmlns:'
- if (XMLString::startsWith(attName, fgXMLNS_Str)) {
- int offsetIndex = XMLString::indexOf(attName, chColon);
- const XMLCh* attValue = attribute->getNodeValue();
- fNamespaceScope->addPrefix(attName + offsetIndex + 1, fURIStringPool->addOrFind(attValue));
- }
- else if (XMLString::equals(attName, XMLUni::fgXMLNSString)) { // == 'xmlns'
- const XMLCh* attValue = attribute->getNodeValue();
- fNamespaceScope->addPrefix(XMLUni::fgZeroLenString, fURIStringPool->addOrFind(attValue));
- seenXMLNS = true;
- }
- } // end for
- if (!seenXMLNS && (!fTargetNSURIString || !*fTargetNSURIString)) {
- fNamespaceScope->addPrefix(XMLUni::fgZeroLenString, fEmptyNamespaceURI);
- }
- // Add mapping for xml prefix
- fNamespaceScope->addPrefix(XMLUni::fgXMLString, fURIStringPool->addOrFind(XMLUni::fgXMLURIName));
- }
- void TraverseSchema::processChildren(const DOMElement* const root) {
- // process <redefine>, <include> and <import> info items.
- DOMElement* child = XUtil::getFirstChildElement(root);
- for (; child != 0; child = XUtil::getNextSiblingElement(child)) {
- const XMLCh* name = child->getLocalName();
- if (XMLString::equals(name, SchemaSymbols::fgELT_ANNOTATION)) {
- traverseAnnotationDecl(child, true);
- }
- else if (XMLString::equals(name, SchemaSymbols::fgELT_INCLUDE)) {
- traverseInclude(child);
- }
- else if (XMLString::equals(name, SchemaSymbols::fgELT_IMPORT)) {
- traverseImport(child);
- }
- else if (XMLString::equals(name, SchemaSymbols::fgELT_REDEFINE)) {
- traverseRedefine(child);
- }
- else
- break;
- }
- // child refers to the first info item which is not <annotation> or
- // one of the schema inclusion/importation declarations.
- for (; child != 0; child = XUtil::getNextSiblingElement(child)) {
- const XMLCh* name = child->getLocalName();
- const XMLCh* typeName = getElementAttValue(child, SchemaSymbols::fgATT_NAME);
- int fullNameId = 0;
- if (typeName) {
- fBuffer.set(fTargetNSURIString);
- fBuffer.append(chComma);
- fBuffer.append(typeName);
- fullNameId = fStringPool->addOrFind(fBuffer.getRawBuffer());
- }
- if (XMLString::equals(name, SchemaSymbols::fgELT_ANNOTATION)) {
- traverseAnnotationDecl(child, true);
- }
- else if (XMLString::equals(name, SchemaSymbols::fgELT_SIMPLETYPE)) {
- if (typeName && *typeName) {
- if (fGlobalDeclarations[ENUM_ELT_SIMPLETYPE]->containsElement(fullNameId)
- || fGlobalDeclarations[ENUM_ELT_COMPLEXTYPE]->containsElement(fullNameId)) {
- reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalType,
- SchemaSymbols::fgELT_SIMPLETYPE, typeName, SchemaSymbols::fgELT_COMPLEXTYPE);
- continue;
- }
- else {
- fGlobalDeclarations[ENUM_ELT_SIMPLETYPE]->addElement(fullNameId);
- }
- }
- traverseSimpleTypeDecl(child);
- }
- else if (XMLString::equals(name, SchemaSymbols::fgELT_COMPLEXTYPE)) {
- if (typeName && *typeName) {
- if (fGlobalDeclarations[ENUM_ELT_SIMPLETYPE]->containsElement(fullNameId)
- || fGlobalDeclarations[ENUM_ELT_COMPLEXTYPE]->containsElement(fullNameId)) {
- reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalType,
- SchemaSymbols::fgELT_COMPLEXTYPE, typeName, SchemaSymbols::fgELT_SIMPLETYPE);
- continue;
- }
- else {
- fGlobalDeclarations[ENUM_ELT_COMPLEXTYPE]->addElement(fullNameId);
- }
- }
- traverseComplexTypeDecl(child);
- }
- else if (XMLString::equals(name, SchemaSymbols::fgELT_ELEMENT)) {
- if (typeName && *typeName) {
- if (fGlobalDeclarations[ENUM_ELT_ELEMENT]->containsElement(fullNameId)) {
- reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalDeclaration,
- SchemaSymbols::fgELT_ELEMENT, typeName);
- continue;
- }
- else {
- fGlobalDeclarations[ENUM_ELT_ELEMENT]->addElement(fullNameId);
- }
- }
- QName* elmQName = traverseElementDecl(child, true);
- delete elmQName;
- }
- else if (XMLString::equals(name, SchemaSymbols::fgELT_ATTRIBUTEGROUP)) {
- if (typeName && *typeName) {
- if (fGlobalDeclarations[ENUM_ELT_ATTRIBUTEGROUP]->containsElement(fullNameId)) {
- reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalDeclaration,
- SchemaSymbols::fgELT_ATTRIBUTEGROUP, typeName);
- continue;
- }
- else {
- fGlobalDeclarations[ENUM_ELT_ATTRIBUTEGROUP]->addElement(fullNameId);
- }
- }
- if (!typeName || !fAttGroupRegistry->containsKey(typeName)) {
- traverseAttributeGroupDecl(child, 0, true);
- }
- }
- else if (XMLString::equals(name, SchemaSymbols::fgELT_ATTRIBUTE)) {
- if (typeName && *typeName) {
- if (fGlobalDeclarations[ENUM_ELT_ATTRIBUTE]->containsElement(fullNameId)) {
- reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, typeName);
- continue;
- }
- else {
- fGlobalDeclarations[ENUM_ELT_ATTRIBUTE]->addElement(fullNameId);
- }
- }
- if (!typeName || !fAttributeDeclRegistry->containsKey(typeName)) {
- traverseAttributeDecl( child, 0, true);
- }
- }
- else if (XMLString::equals(name, SchemaSymbols::fgELT_GROUP)) {
- if (typeName && *typeName) {
- if (fGlobalDeclarations[ENUM_ELT_GROUP]->containsElement(fullNameId)) {
- reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalDeclaration,
- SchemaSymbols::fgELT_GROUP, typeName);
- continue;
- }
- else {
- fGlobalDeclarations[ENUM_ELT_GROUP]->addElement(fullNameId);
- }
- }
- if (!typeName || !fGroupRegistry->containsKey(fBuffer.getRawBuffer())) {
- traverseGroupDecl(child);
- }
- }
- else if (XMLString::equals(name, SchemaSymbols::fgELT_NOTATION)) {
- traverseNotationDecl(child);
- }
- else {
- reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::SchemaElementContentError);
- }
- } // for each child node
- // Handle recursing elements - if any
- ValueVectorOf<const DOMElement*>* recursingAnonTypes = fSchemaInfo->getRecursingAnonTypes();
- if (recursingAnonTypes) {
- ValueVectorOf<const XMLCh*>* recursingTypeNames = fSchemaInfo->getRecursingTypeNames();
- unsigned int recurseSize = recursingAnonTypes->size();
- for (unsigned int i=0; i < recurseSize; i++) {
- traverseComplexTypeDecl(recursingAnonTypes->elementAt(i), false,
- recursingTypeNames->elementAt(i));
- }
- recursingAnonTypes->removeAllElements();
- recursingTypeNames->removeAllElements();
- }
- }
- void TraverseSchema::preprocessChildren(const DOMElement* const root) {
- // process <redefine>, <include> and <import> info items.
- DOMElement* child = XUtil::getFirstChildElement(root);
- for (; child != 0; child = XUtil::getNextSiblingElement(child)) {
- const XMLCh* name = child->getLocalName();
- if (XMLString::equals(name, SchemaSymbols::fgELT_ANNOTATION)) {
- continue;
- }
- else if (XMLString::equals(name, SchemaSymbols::fgELT_INCLUDE)) {
- preprocessInclude(child);
- }
- else if (XMLString::equals(name, SchemaSymbols::fgELT_IMPORT)) {
- preprocessImport(child);
- }
- else if (XMLString::equals(name, SchemaSymbols::fgELT_REDEFINE)) {
- preprocessRedefine(child);
- }
- else
- break;
- }
- }
- DOMElement* TraverseSchema::checkContent(const DOMElement* const rootElem,
- DOMElement* const contentElem,
- const bool isEmpty) {
- DOMElement* content = contentElem;
- const XMLCh* name = getElementAttValue(rootElem,SchemaSymbols::fgATT_NAME);
- if (!content) {
- if (!isEmpty) {
- reportSchemaError(rootElem, XMLUni::fgXMLErrDomain, XMLErrs::ContentError, name);
- }
- return 0;
- }
- if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_ANNOTATION)) {
- traverseAnnotationDecl(content);
- content = XUtil::getNextSiblingElement(content);
- if (!content) { // must be followed by content
- if (!isEmpty) {
- reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::ContentError, name);
- }
- return 0;
- }
- if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_ANNOTATION)) {
- reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::AnnotationError, name);
- return 0;
- }
- }
- return content;
- }
- DatatypeValidator*
- TraverseSchema::getDatatypeValidator(const XMLCh* const uriStr,
- const XMLCh* const localPartStr) {
- DatatypeValidator* dv = 0;
- if (XMLString::equals(uriStr, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) {
- dv = fDatatypeRegistry->getDatatypeValidator(localPartStr);
- }
- else {
- fBuffer.set(uriStr);
- fBuffer.append(chComma);
- fBuffer.append(localPartStr);
- if ((uriStr && *uriStr) && !XMLString::equals(uriStr, fTargetNSURIString)) {
- Grammar* grammar = fGrammarResolver->getGrammar(uriStr);
- if (grammar && grammar->getGrammarType() == Grammar::SchemaGrammarType) {
- dv = ((SchemaGrammar*) grammar)->getDatatypeRegistry()->getDatatypeValidator(fBuffer.getRawBuffer());
- }
- }
- else {
- dv = fDatatypeRegistry->getDatatypeValidator(fBuffer.getRawBuffer());
- }
- }
- return dv;
- }
- DatatypeValidator*
- TraverseSchema::checkForSimpleTypeValidator(const DOMElement* const content,
- int baseRefContext) {
- DatatypeValidator* baseValidator = traverseSimpleTypeDecl(content, false, baseRefContext);
- if (!baseValidator) {
- const XMLCh* name = getElementAttValue(content,SchemaSymbols::fgATT_NAME);
- reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::UnknownSimpleType, name);
- }
- return baseValidator;
- }
- ComplexTypeInfo*
- TraverseSchema::checkForComplexTypeInfo(const DOMElement* const content) {
- int typeNameIndex = traverseComplexTypeDecl(content, false);
- ComplexTypeInfo* baseTypeInfo = 0;
- if (typeNameIndex != -1) {
- baseTypeInfo = fComplexTypeRegistry->get(fStringPool->getValueForId(typeNameIndex));
- }
- if (typeNameIndex == -1 || baseTypeInfo == 0) {
- const XMLCh* name = getElementAttValue(content,SchemaSymbols::fgATT_NAME);
- reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::UnknownComplexType, name);
- }
- return baseTypeInfo;
- }
- DatatypeValidator*
- TraverseSchema::findDTValidator(const DOMElement* const elem,
- const XMLCh* const derivedTypeName,
- const XMLCh* const baseTypeName,
- const int baseRefContext) {
- const XMLCh* prefix = getPrefix(baseTypeName);
- const XMLCh* localPart = getLocalPart(baseTypeName);
- const XMLCh* uri = resolvePrefixToURI(elem, prefix);
- DatatypeValidator* baseValidator = getDatatypeValidator(uri, localPart);
- if (baseValidator == 0) {
- SchemaInfo* saveInfo = fSchemaInfo;
- DOMElement* baseTypeNode = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_SimpleType,
- SchemaSymbols::fgELT_SIMPLETYPE, localPart, &fSchemaInfo);
- if (baseTypeNode != 0) {
- baseValidator = traverseSimpleTypeDecl(baseTypeNode);
- // restore schema information, if necessary
- fSchemaInfo = saveInfo;
- }
- }
- if (baseValidator == 0) {
- reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::UnknownBaseDatatype, baseTypeName, derivedTypeName);
- }
- else if ((baseValidator->getFinalSet() & baseRefContext) != 0) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DisallowedBaseDerivation, baseTypeName);
- return 0;
- }
- return baseValidator;
- }
- const XMLCh* TraverseSchema::resolvePrefixToURI(const DOMElement* const elem,
- const XMLCh* const prefix) {
- int nameSpaceIndex = fNamespaceScope->getNamespaceForPrefix(prefix, fSchemaInfo->getNamespaceScopeLevel());
- const XMLCh* uriStr = fURIStringPool->getValueForId(nameSpaceIndex);
- if ((!uriStr || !*uriStr) && (prefix && *prefix)) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::UnresolvedPrefix, prefix);
- return XMLUni::fgZeroLenString;
- }
- return uriStr;
- }
- const XMLCh* TraverseSchema::resolvePrefixToURI(const DOMElement* const elem,
- const XMLCh* const prefix,
- const unsigned int namespaceDepth) {
- int nameSpaceIndex = fNamespaceScope->getNamespaceForPrefix(prefix, namespaceDepth);
- const XMLCh* uriStr = fURIStringPool->getValueForId(nameSpaceIndex);
- if ((!uriStr || !*uriStr) && (prefix && *prefix)) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::UnresolvedPrefix, prefix);
- return XMLUni::fgZeroLenString;
- }
- return uriStr;
- }
- QName* TraverseSchema::processElementDeclRef(const DOMElement* const elem,
- const XMLCh* const refName) {
- DOMElement* content = checkContent(elem, XUtil::getFirstChildElement(elem), true);
- if (content != 0) {
- reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::NoContentForRef, SchemaSymbols::fgELT_ELEMENT);
- }
- const XMLCh* prefix = getPrefix(refName);
- const XMLCh* localPart = getLocalPart(refName);
- const XMLCh* uriStr = resolvePrefixToURI(elem, prefix);
- QName* eltName = new (fMemoryManager) QName(prefix , localPart, uriStr != 0
- ? fURIStringPool->addOrFind(uriStr)
- : fEmptyNamespaceURI, fMemoryManager);
- //if from another schema, just return the element QName
- if (!XMLString::equals(uriStr, fTargetNSURIString)) {
- return eltName;
- }
- unsigned int uriID = eltName->getURI();
- SchemaElementDecl* refElemDecl = (SchemaElementDecl*)
- fSchemaGrammar->getElemDecl(uriID, localPart, 0, Grammar::TOP_LEVEL_SCOPE);
- //if not found, traverse the top level element that is referenced
- if (!refElemDecl) {
- SchemaInfo* saveInfo = fSchemaInfo;
- DOMElement* targetElem = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_Element,
- SchemaSymbols::fgELT_ELEMENT, localPart, &fSchemaInfo);
- if (targetElem == 0) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::RefElementNotFound, localPart);
- // REVISIT do we return 0 or what? for now we will return QName created
- return eltName;
- }
- else {
- delete eltName;
- eltName = traverseElementDecl(targetElem, true);
- refElemDecl = (SchemaElementDecl*)
- fSchemaGrammar->getElemDecl(uriID, localPart, 0, Grammar::TOP_LEVEL_SCOPE);
- // restore schema information
- fSchemaInfo = saveInfo;
- }
- }
- if (refElemDecl) {
- if (fCurrentComplexType)
- fCurrentComplexType->addElement(refElemDecl);
- if (fCurrentGroupInfo)
- fCurrentGroupInfo->addElement(refElemDecl);
- }
- return eltName;
- }
- int TraverseSchema::parseBlockSet(const DOMElement* const elem,
- const int blockType, const bool isRoot) {
- const XMLCh* blockVal = (isRoot) ? getElementAttValue(elem, SchemaSymbols::fgATT_BLOCKDEFAULT)
- : getElementAttValue(elem, SchemaSymbols::fgATT_BLOCK);
- if (!blockVal || !*blockVal) {
- return fSchemaInfo->getBlockDefault();
- }
- int blockSet = 0;
- if (XMLString::equals(blockVal, SchemaSymbols::fgATTVAL_POUNDALL)) {
- blockSet = SchemaSymbols::XSD_EXTENSION + SchemaSymbols::XSD_RESTRICTION + SchemaSymbols::XSD_SUBSTITUTION;
- return blockSet;
- }
- XMLStringTokenizer tokenizer(blockVal, fMemoryManager);
- while (tokenizer.hasMoreTokens()) {
- XMLCh* token = tokenizer.nextToken();
- if (XMLString::equals(token, SchemaSymbols::fgATTVAL_SUBSTITUTION)
- && blockType == ES_Block) {
- if ((blockSet & SchemaSymbols::XSD_SUBSTITUTION) == 0 ) {
- blockSet += SchemaSymbols::XSD_SUBSTITUTION;
- }
- else {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::SubstitutionRepeated);
- }
- }
- else if (XMLString::equals(token, SchemaSymbols::fgATTVAL_EXTENSION)) {
- if ((blockSet & SchemaSymbols::XSD_EXTENSION) == 0) {
- blockSet += SchemaSymbols::XSD_EXTENSION;
- }
- else {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::ExtensionRepeated);
- }
- }
- else if (XMLString::equals(token, SchemaSymbols::fgATTVAL_RESTRICTION)) {
- if ((blockSet & SchemaSymbols::XSD_RESTRICTION) == 0 ) {
- blockSet += SchemaSymbols::XSD_RESTRICTION;
- }
- else {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::RestrictionRepeated);
- }
- }
- else {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidBlockValue, blockVal);
- }
- } //end while
- return (blockSet == 0 ? fSchemaInfo->getBlockDefault() : blockSet);
- }
- int TraverseSchema::parseFinalSet(const DOMElement* const elem,
- const int finalType, const bool isRoot) {
- const XMLCh* finalVal = (isRoot) ? getElementAttValue(elem, SchemaSymbols::fgATT_FINALDEFAULT)
- : getElementAttValue(elem, SchemaSymbols::fgATT_FINAL);
- if (!finalVal || !*finalVal) {
- return fSchemaInfo->getFinalDefault();
- }
- int finalSet = 0;
- if (XMLString::equals(finalVal, SchemaSymbols::fgATTVAL_POUNDALL)) {
- finalSet = SchemaSymbols::XSD_RESTRICTION + SchemaSymbols::XSD_LIST +
- SchemaSymbols::XSD_UNION + SchemaSymbols::XSD_EXTENSION;
- return finalSet;
- }
- XMLStringTokenizer tokenizer(finalVal, fMemoryManager);
- while (tokenizer.hasMoreTokens()) {
- XMLCh* token = tokenizer.nextToken();
- if (XMLString::equals(token, SchemaSymbols::fgELT_UNION)
- && finalType == S_Final) {
- if ((finalSet & SchemaSymbols::XSD_UNION) == 0) {
- finalSet += SchemaSymbols::XSD_UNION;
- }
- else {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::UnionRepeated);
- }
- }
- else if (XMLString::equals(token, SchemaSymbols::fgATTVAL_EXTENSION)
- && finalType != S_Final) {
- if ((finalSet & SchemaSymbols::XSD_EXTENSION) == 0) {
- finalSet += SchemaSymbols::XSD_EXTENSION;
- }
- else {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::ExtensionRepeated);
- }
- }
- else if (XMLString::equals(token, SchemaSymbols::fgELT_LIST)
- && finalType == S_Final) {
- if ((finalSet & SchemaSymbols::XSD_LIST) == 0 ) {
- finalSet += SchemaSymbols::XSD_LIST;
- }
- else {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::ListRepeated);
- }
- }
- else if (XMLString::equals(token, SchemaSymbols::fgATTVAL_RESTRICTION)) {
- if ((finalSet & SchemaSymbols::XSD_RESTRICTION) == 0 ) {
- finalSet += SchemaSymbols::XSD_RESTRICTION;
- }
- else {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::RestrictionRepeated);
- }
- }
- else {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidFinalValue, finalVal);
- }
- } //end while
- return (finalSet == 0 ? fSchemaInfo->getFinalDefault() : finalSet);
- }
- const DOMElement*
- TraverseSchema::checkIdentityConstraintContent(const DOMElement* const content) {
- const DOMElement* child = content;
- if (child != 0) {
- do {
- if (!isIdentityConstraintName(child->getLocalName())) {
- break;
- }
- child = XUtil::getNextSiblingElement(child);
- } while (child != 0);
- }
- return child;
- }
- bool TraverseSchema::isIdentityConstraintName(const XMLCh* const name) {
- return (XMLString::equals(name, SchemaSymbols::fgELT_KEY)
- || XMLString::equals(name, SchemaSymbols::fgELT_KEYREF)
- || XMLString::equals(name, SchemaSymbols::fgELT_UNIQUE));
- }
- const XMLCh*
- TraverseSchema::checkTypeFromAnotherSchema(const DOMElement* const elem,
- const XMLCh* const typeStr) {
- const XMLCh* prefix = getPrefix(typeStr);
- const XMLCh* typeURI = resolvePrefixToURI(elem, prefix);
- if (!XMLString::equals(typeURI, fTargetNSURIString)
- && !XMLString::equals(typeURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)
- && (typeURI && *typeURI)) {
- return typeURI;
- }
- return 0;
- }
- DatatypeValidator*
- TraverseSchema::getElementTypeValidator(const DOMElement* const elem,
- const XMLCh* const typeStr,
- bool& noErrorDetected,
- const XMLCh* const otherSchemaURI)
- {
- const XMLCh* localPart = getLocalPart(typeStr);
- const XMLCh* typeURI = otherSchemaURI;
- DatatypeValidator* dv = 0;
- SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
- SchemaInfo* saveInfo = fSchemaInfo;
- int saveScope = fCurrentScope;
- if (otherSchemaURI != 0) {
- // Make sure that we have an explicit import statement.
- // Clause 4 of Schema Representation Constraint:
- // http://www.w3.org/TR/xmlschema-1/#src-resolve
- unsigned int uriId = fURIStringPool->addOrFind(otherSchemaURI);
- if (!fSchemaInfo->isImportingNS(uriId)) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, otherSchemaURI);
- return 0;
- }
- dv = getDatatypeValidator(typeURI, localPart);
- if (dv) {
- return dv;
- }
- SchemaInfo* impInfo = fSchemaInfo->getImportInfo(uriId);
- if (!impInfo || impInfo->getProcessed()) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, typeURI, localPart);
- return 0;
- }
- infoType = SchemaInfo::IMPORT;
- restoreSchemaInfo(impInfo, infoType);
- }
- else {
- const XMLCh* prefix = getPrefix(typeStr);
- typeURI = resolvePrefixToURI(elem, prefix);
- dv = getDatatypeValidator(typeURI, localPart);
- }
- if (!dv) {
- if (!XMLString::equals(typeURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)
- || XMLString::equals(fTargetNSURIString, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) {
- DOMElement* typeElem = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_SimpleType,
- SchemaSymbols::fgELT_SIMPLETYPE, localPart, &fSchemaInfo);
- if (typeElem) {
- dv = traverseSimpleTypeDecl(typeElem);
- }
- }
- // restore schema information, if necessary
- if (saveInfo != fSchemaInfo) {
- restoreSchemaInfo(saveInfo, infoType, saveScope);
- }
- if (!dv) {
- noErrorDetected = false;
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, typeURI, localPart);
- }
- }
- return dv;
- }
- DatatypeValidator*
- TraverseSchema::getAttrDatatypeValidatorNS(const DOMElement* const elem,
- const XMLCh* localPart,
- const XMLCh* typeURI)
- {
- DatatypeValidator* dv = getDatatypeValidator(typeURI, localPart);
- SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
- SchemaInfo* saveInfo = fSchemaInfo;
- int saveScope = fCurrentScope;
- if (!XMLString::equals(typeURI, fTargetNSURIString)
- && (typeURI && *typeURI)) {
- // Make sure that we have an explicit import statement.
- // Clause 4 of Schema Representation Constraint:
- // http://www.w3.org/TR/xmlschema-1/#src-resolve
- unsigned int uriId = fURIStringPool->addOrFind(typeURI);
- if (!fSchemaInfo->isImportingNS(uriId)) {
- reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, typeURI);
- return 0;
- }
- if (!dv) {
- SchemaInfo* impInfo = fSchemaInfo->getImportInfo(uriId);
- if (!impInfo || impInfo->getProcessed())
- return 0;
- infoType = SchemaInfo::IMPORT;
- restoreSchemaInfo(impInfo, infoType);
- }
- }