GME
13
|
00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one or more 00003 * contributor license agreements. See the NOTICE file distributed with 00004 * this work for additional information regarding copyright ownership. 00005 * The ASF licenses this file to You under the Apache License, Version 2.0 00006 * (the "License"); you may not use this file except in compliance with 00007 * the License. You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /* 00019 * $Id: SubstitutionGroupComparator.cpp 794273 2009-07-15 14:13:07Z amassari $ 00020 */ 00021 00022 00023 // --------------------------------------------------------------------------- 00024 // Includes 00025 // --------------------------------------------------------------------------- 00026 #include <xercesc/framework/XMLGrammarPool.hpp> 00027 #include <xercesc/framework/XMLSchemaDescription.hpp> 00028 #include <xercesc/framework/psvi/XSAnnotation.hpp> 00029 #include <xercesc/validators/schema/SubstitutionGroupComparator.hpp> 00030 #include <xercesc/validators/common/Grammar.hpp> 00031 #include <xercesc/validators/schema/SchemaGrammar.hpp> 00032 #include <xercesc/validators/schema/ComplexTypeInfo.hpp> 00033 #include <xercesc/validators/schema/SchemaSymbols.hpp> 00034 00035 XERCES_CPP_NAMESPACE_BEGIN 00036 00037 bool SubstitutionGroupComparator::isEquivalentTo(const QName* const anElement 00038 , const QName* const exemplar) 00039 { 00040 if (!anElement && !exemplar) 00041 return true; 00042 00043 if ((!anElement && exemplar) || (anElement && !exemplar)) 00044 return false; 00045 00046 00047 if (XMLString::equals(anElement->getLocalPart(), exemplar->getLocalPart()) && 00048 (anElement->getURI() == exemplar->getURI())) 00049 return true; // they're the same! 00050 00051 if (!fGrammarResolver || !fStringPool ) 00052 { 00053 ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::SubGrpComparator_NGR, anElement->getMemoryManager()); 00054 } 00055 00056 unsigned int uriId = anElement->getURI(); 00057 if (uriId == XMLContentModel::gEOCFakeId || 00058 uriId == XMLContentModel::gEpsilonFakeId || 00059 uriId == XMLElementDecl::fgPCDataElemId || 00060 uriId == XMLElementDecl::fgInvalidElemId) 00061 return false; 00062 00063 const XMLCh* uri = fStringPool->getValueForId(uriId); 00064 const XMLCh* localpart = anElement->getLocalPart(); 00065 00066 // In addition to simply trying to find a chain between anElement and exemplar, 00067 // we need to make sure that no steps in the chain are blocked. 00068 // That is, at every step, we need to make sure that the element 00069 // being substituted for will permit being substituted 00070 // for, and whether the type of the element will permit derivations in 00071 // instance documents of this sort. 00072 00073 if (!uri) 00074 return false; 00075 00076 SchemaGrammar *sGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(uri); 00077 if (!sGrammar || sGrammar->getGrammarType() == Grammar::DTDGrammarType) 00078 return false; 00079 00080 SchemaElementDecl* anElementDecl = (SchemaElementDecl*) sGrammar->getElemDecl(uriId, localpart, 0, Grammar::TOP_LEVEL_SCOPE); 00081 if (!anElementDecl) 00082 return false; 00083 00084 SchemaElementDecl* pElemDecl = anElementDecl->getSubstitutionGroupElem(); 00085 bool foundIt = false; 00086 00087 while (pElemDecl) //(substitutionGroupFullName) 00088 { 00089 if (XMLString::equals(pElemDecl->getBaseName(), exemplar->getLocalPart()) && 00090 (pElemDecl->getURI() == exemplar->getURI())) 00091 { 00092 // time to check for block value on element 00093 if((pElemDecl->getBlockSet() & SchemaSymbols::XSD_SUBSTITUTION) != 0) 00094 return false; 00095 00096 foundIt = true; 00097 break; 00098 } 00099 00100 pElemDecl = pElemDecl->getSubstitutionGroupElem(); 00101 }//while 00102 00103 if (!foundIt) 00104 return false; 00105 00106 // this will contain anElement's complexType information. 00107 ComplexTypeInfo *aComplexType = anElementDecl->getComplexTypeInfo(); 00108 int exemplarBlockSet = pElemDecl->getBlockSet(); 00109 00110 if(!aComplexType) 00111 { 00112 // check on simpleType case 00113 DatatypeValidator *anElementDV = anElementDecl->getDatatypeValidator(); 00114 DatatypeValidator *exemplarDV = pElemDecl->getDatatypeValidator(); 00115 00116 return((anElementDV == 0) || 00117 ((anElementDV == exemplarDV) || 00118 ((exemplarBlockSet & SchemaSymbols::XSD_RESTRICTION) == 0))); 00119 } 00120 00121 // 2.3 The set of all {derivation method}s involved in the derivation of D's {type definition} from C's {type definition} does not intersect with the union of the blocking constraint, C's {prohibited substitutions} (if C is complex, otherwise the empty set) and the {prohibited substitutions} (respectively the empty set) of any intermediate {type definition}s in the derivation of D's {type definition} from C's {type definition}. 00122 // prepare the combination of {derivation method} and 00123 // {disallowed substitution} 00124 int devMethod = 0; 00125 int blockConstraint = exemplarBlockSet; 00126 00127 ComplexTypeInfo *exemplarComplexType = pElemDecl->getComplexTypeInfo(); 00128 ComplexTypeInfo *tempType = aComplexType;; 00129 00130 while (tempType != 0 && 00131 tempType != exemplarComplexType) 00132 { 00133 devMethod |= tempType->getDerivedBy(); 00134 tempType = tempType->getBaseComplexTypeInfo(); 00135 if (tempType) { 00136 blockConstraint |= tempType->getBlockSet(); 00137 } 00138 } 00139 if (tempType != exemplarComplexType) { 00140 return false; 00141 } 00142 if ((devMethod & blockConstraint) != 0) { 00143 return false; 00144 } 00145 00146 return true; 00147 } 00148 00149 00150 bool SubstitutionGroupComparator::isAllowedByWildcard(SchemaGrammar* const pGrammar, 00151 QName* const element, 00152 unsigned int wuri, bool wother) 00153 { 00154 // whether the uri is allowed directly by the wildcard 00155 unsigned int uriId = element->getURI(); 00156 00157 // Here we assume that empty string has id 1. 00158 // 00159 if ((!wother && uriId == wuri) || 00160 (wother && 00161 uriId != 1 && 00162 uriId != wuri && 00163 uriId != XMLContentModel::gEOCFakeId && 00164 uriId != XMLContentModel::gEpsilonFakeId && 00165 uriId != XMLElementDecl::fgPCDataElemId && 00166 uriId != XMLElementDecl::fgInvalidElemId)) 00167 { 00168 return true; 00169 } 00170 00171 // get all elements that can substitute the current element 00172 RefHash2KeysTableOf<ElemVector>* theValidSubstitutionGroups = pGrammar->getValidSubstitutionGroups(); 00173 00174 if (!theValidSubstitutionGroups) 00175 return false; 00176 00177 ValueVectorOf<SchemaElementDecl*>* subsElements = theValidSubstitutionGroups->get(element->getLocalPart(), uriId); 00178 00179 if (!subsElements) 00180 return false; 00181 00182 // then check whether there exists one element that is allowed by the wildcard 00183 XMLSize_t size = subsElements->size(); 00184 00185 for (XMLSize_t i = 0; i < size; i++) 00186 { 00187 unsigned int subUriId = subsElements->elementAt(i)->getElementName()->getURI(); 00188 00189 // Here we assume that empty string has id 1. 00190 // 00191 if ((!wother && subUriId == wuri) || 00192 (wother && 00193 subUriId != 1 && 00194 subUriId != wuri && 00195 subUriId != XMLContentModel::gEOCFakeId && 00196 subUriId != XMLContentModel::gEpsilonFakeId && 00197 subUriId != XMLElementDecl::fgPCDataElemId && 00198 subUriId != XMLElementDecl::fgInvalidElemId)) 00199 { 00200 return true; 00201 } 00202 } 00203 return false; 00204 } 00205 00206 XERCES_CPP_NAMESPACE_END 00207