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: XMLGrammarPoolImpl.cpp 676823 2008-07-15 07:57:44Z borisk $ 00020 */ 00021 00022 00023 // --------------------------------------------------------------------------- 00024 // Includes 00025 // --------------------------------------------------------------------------- 00026 #include <xercesc/framework/XMLGrammarPoolImpl.hpp> 00027 #include <xercesc/internal/XSerializeEngine.hpp> 00028 #include <xercesc/internal/XTemplateSerializer.hpp> 00029 #include <xercesc/validators/DTD/DTDGrammar.hpp> 00030 #include <xercesc/validators/DTD/XMLDTDDescriptionImpl.hpp> 00031 #include <xercesc/validators/schema/SchemaGrammar.hpp> 00032 #include <xercesc/validators/schema/XMLSchemaDescriptionImpl.hpp> 00033 #include <xercesc/util/OutOfMemoryException.hpp> 00034 #include <xercesc/util/SynchronizedStringPool.hpp> 00035 00036 XERCES_CPP_NAMESPACE_BEGIN 00037 00038 // private function used to update fXSModel 00039 void XMLGrammarPoolImpl::createXSModel() 00040 { 00041 delete fXSModel; 00042 fXSModel = 0; 00043 fXSModel = new (getMemoryManager()) XSModel(this, getMemoryManager()); 00044 fXSModelIsValid = true; 00045 } 00046 00047 // --------------------------------------------------------------------------- 00048 // XMLGrammarPoolImpl: constructor and destructor 00049 // --------------------------------------------------------------------------- 00050 XMLGrammarPoolImpl::~XMLGrammarPoolImpl() 00051 { 00052 delete fGrammarRegistry; 00053 delete fStringPool; 00054 if(fSynchronizedStringPool) 00055 delete fSynchronizedStringPool; 00056 if(fXSModel) 00057 delete fXSModel; 00058 } 00059 00060 XMLGrammarPoolImpl::XMLGrammarPoolImpl(MemoryManager* const memMgr) 00061 :XMLGrammarPool(memMgr) 00062 ,fGrammarRegistry(0) 00063 ,fStringPool(0) 00064 ,fSynchronizedStringPool(0) 00065 ,fXSModel(0) 00066 ,fLocked(false) 00067 ,fXSModelIsValid(false) 00068 { 00069 fGrammarRegistry = new (memMgr) RefHashTableOf<Grammar>(29, true, memMgr); 00070 fStringPool = new (memMgr) XMLStringPool(109, memMgr); 00071 } 00072 00073 // ----------------------------------------------------------------------- 00074 // Implementation of Grammar Pool Interface 00075 // ----------------------------------------------------------------------- 00076 bool XMLGrammarPoolImpl::cacheGrammar(Grammar* const gramToCache ) 00077 { 00078 if(fLocked || !gramToCache) 00079 return false; 00080 00081 const XMLCh* grammarKey = gramToCache->getGrammarDescription()->getGrammarKey(); 00082 00083 if (fGrammarRegistry->containsKey(grammarKey)) 00084 { 00085 return false; 00086 } 00087 00088 fGrammarRegistry->put((void*) grammarKey, gramToCache); 00089 00090 if (fXSModelIsValid && gramToCache->getGrammarType() == Grammar::SchemaGrammarType) 00091 { 00092 fXSModelIsValid = false; 00093 } 00094 return true; 00095 } 00096 00097 Grammar* XMLGrammarPoolImpl::retrieveGrammar(XMLGrammarDescription* const gramDesc) 00098 { 00099 if (!gramDesc) 00100 return 0; 00101 00102 /*** 00103 * This implementation simply use GrammarKey 00104 */ 00105 return fGrammarRegistry->get(gramDesc->getGrammarKey()); 00106 } 00107 00108 Grammar* XMLGrammarPoolImpl::orphanGrammar(const XMLCh* const nameSpaceKey) 00109 { 00110 if (!fLocked) 00111 { 00112 Grammar* grammar = fGrammarRegistry->orphanKey(nameSpaceKey); 00113 if (fXSModelIsValid && grammar && grammar->getGrammarType() == Grammar::SchemaGrammarType) 00114 { 00115 fXSModelIsValid = false; 00116 } 00117 return grammar; 00118 } 00119 return 0; 00120 } 00121 00122 RefHashTableOfEnumerator<Grammar> 00123 XMLGrammarPoolImpl::getGrammarEnumerator() const 00124 { 00125 return RefHashTableOfEnumerator<Grammar>(fGrammarRegistry, false, fGrammarRegistry->getMemoryManager()); 00126 } 00127 00128 00129 bool XMLGrammarPoolImpl::clear() 00130 { 00131 if (!fLocked) 00132 { 00133 fGrammarRegistry->removeAll(); 00134 00135 fXSModelIsValid = false; 00136 if (fXSModel) 00137 { 00138 delete fXSModel; 00139 fXSModel = 0; 00140 } 00141 return true; 00142 } 00143 return false; 00144 } 00145 00146 void XMLGrammarPoolImpl::lockPool() 00147 { 00148 if (!fLocked) 00149 { 00150 fLocked = true; 00151 MemoryManager *memMgr = getMemoryManager(); 00152 if(!fSynchronizedStringPool) 00153 { 00154 fSynchronizedStringPool = new (memMgr) XMLSynchronizedStringPool(fStringPool, 109, memMgr); 00155 } 00156 if (!fXSModelIsValid) 00157 { 00158 createXSModel(); 00159 } 00160 } 00161 } 00162 00163 void XMLGrammarPoolImpl::unlockPool() 00164 { 00165 if (fLocked) 00166 { 00167 fLocked = false; 00168 if(fSynchronizedStringPool) 00169 { 00170 fSynchronizedStringPool->flushAll(); 00171 // if user calls Lock again, need to have null fSynchronizedStringPool 00172 delete fSynchronizedStringPool; 00173 fSynchronizedStringPool = 0; 00174 } 00175 fXSModelIsValid = false; 00176 if (fXSModel) 00177 { 00178 delete fXSModel; 00179 fXSModel = 0; 00180 } 00181 } 00182 } 00183 00184 // ----------------------------------------------------------------------- 00185 // Implementation of Factory Interface 00186 // ----------------------------------------------------------------------- 00187 DTDGrammar* XMLGrammarPoolImpl::createDTDGrammar() 00188 { 00189 return new (getMemoryManager()) DTDGrammar(getMemoryManager()); 00190 } 00191 00192 SchemaGrammar* XMLGrammarPoolImpl::createSchemaGrammar() 00193 { 00194 return new (getMemoryManager()) SchemaGrammar(getMemoryManager()); 00195 } 00196 00197 XMLDTDDescription* XMLGrammarPoolImpl::createDTDDescription(const XMLCh* const systemId) 00198 { 00199 return new (getMemoryManager()) XMLDTDDescriptionImpl(systemId, getMemoryManager()); 00200 } 00201 00202 XMLSchemaDescription* XMLGrammarPoolImpl::createSchemaDescription(const XMLCh* const targetNamespace) 00203 { 00204 return new (getMemoryManager()) XMLSchemaDescriptionImpl(targetNamespace, getMemoryManager()); 00205 } 00206 00207 XSModel *XMLGrammarPoolImpl::getXSModel(bool& XSModelWasChanged) 00208 { 00209 XSModelWasChanged = false; 00210 if (fLocked || fXSModelIsValid) 00211 return fXSModel; 00212 00213 createXSModel(); 00214 XSModelWasChanged = true; 00215 return fXSModel; 00216 } 00217 00218 XMLStringPool *XMLGrammarPoolImpl::getURIStringPool() 00219 { 00220 if(fLocked) 00221 return fSynchronizedStringPool; 00222 return fStringPool; 00223 } 00224 00225 // ----------------------------------------------------------------------- 00226 // serialization and deserialization support 00227 // ----------------------------------------------------------------------- 00228 /*** 00229 * 00230 * don't serialize 00231 * 00232 * XMLSynchronizedStringPool* fSynchronizedStringPool; 00233 */ 00234 00235 /*** 00236 * .non-empty gramamrRegistry 00237 ***/ 00238 void XMLGrammarPoolImpl::serializeGrammars(BinOutputStream* const binOut) 00239 { 00240 RefHashTableOfEnumerator<Grammar> grammarEnum(fGrammarRegistry, false, getMemoryManager()); 00241 if (!(grammarEnum.hasMoreElements())) 00242 { 00243 ThrowXMLwithMemMgr(XSerializationException, XMLExcepts::XSer_GrammarPool_Empty, getMemoryManager()); 00244 } 00245 00246 XSerializeEngine serEng(binOut, this); 00247 00248 //version information 00249 serEng<<(unsigned int)XERCES_GRAMMAR_SERIALIZATION_LEVEL; 00250 00251 //lock status 00252 serEng<<fLocked; 00253 00254 //StringPool, don't use << 00255 fStringPool->serialize(serEng); 00256 00257 /*** 00258 * Serialize RefHashTableOf<Grammar>* fGrammarRegistry; 00259 ***/ 00260 XTemplateSerializer::storeObject(fGrammarRegistry, serEng); 00261 } 00262 00263 /*** 00264 * .empty stringPool 00265 * .empty gramamrRegistry 00266 ***/ 00267 void XMLGrammarPoolImpl::deserializeGrammars(BinInputStream* const binIn) 00268 { 00269 MemoryManager *memMgr = getMemoryManager(); 00270 unsigned int stringCount = fStringPool->getStringCount(); 00271 if (stringCount) 00272 { 00273 /*** 00274 * it contains only the four predefined one, that is ok 00275 * but we need to reset the string before deserialize it 00276 * 00277 ***/ 00278 if ( stringCount <= 4 ) 00279 { 00280 fStringPool->flushAll(); 00281 } 00282 else 00283 { 00284 ThrowXMLwithMemMgr(XSerializationException, XMLExcepts::XSer_StringPool_NotEmpty, memMgr); 00285 } 00286 } 00287 00288 RefHashTableOfEnumerator<Grammar> grammarEnum(fGrammarRegistry, false, memMgr); 00289 if (grammarEnum.hasMoreElements()) 00290 { 00291 ThrowXMLwithMemMgr(XSerializationException, XMLExcepts::XSer_GrammarPool_NotEmpty, memMgr); 00292 } 00293 00294 // This object will take care of cleaning up if an exception is 00295 // thrown during deserialization. 00296 JanitorMemFunCall<XMLGrammarPoolImpl> cleanup(this, &XMLGrammarPoolImpl::cleanUp); 00297 00298 try 00299 { 00300 XSerializeEngine serEng(binIn, this); 00301 00302 //version information 00303 unsigned int StorerLevel; 00304 serEng>>StorerLevel; 00305 serEng.fStorerLevel = StorerLevel; 00306 00307 // The storer level must match the loader level. 00308 // 00309 if (StorerLevel != (unsigned int)XERCES_GRAMMAR_SERIALIZATION_LEVEL) 00310 { 00311 XMLCh StorerLevelChar[5]; 00312 XMLCh LoaderLevelChar[5]; 00313 XMLString::binToText(StorerLevel, StorerLevelChar, 4, 10, memMgr); 00314 XMLString::binToText(XERCES_GRAMMAR_SERIALIZATION_LEVEL, LoaderLevelChar, 4, 10, memMgr); 00315 00316 ThrowXMLwithMemMgr2(XSerializationException 00317 , XMLExcepts::XSer_Storer_Loader_Mismatch 00318 , StorerLevelChar 00319 , LoaderLevelChar 00320 , memMgr); 00321 } 00322 00323 //lock status 00324 serEng>>fLocked; 00325 00326 //StringPool, don't use >> 00327 fStringPool->serialize(serEng); 00328 00329 /*** 00330 * Deserialize RefHashTableOf<Grammar>* fGrammarRegistry; 00331 ***/ 00332 XTemplateSerializer::loadObject(&fGrammarRegistry, 29, true, serEng); 00333 00334 } 00335 catch(const OutOfMemoryException&) 00336 { 00337 // This is a special case, because we don't want 00338 // to execute cleanup code on out-of-memory 00339 // conditions. 00340 cleanup.release(); 00341 00342 throw; 00343 } 00344 00345 // Everything is OK, so we can release the cleanup object. 00346 cleanup.release(); 00347 00348 if (fLocked) 00349 { 00350 createXSModel(); 00351 } 00352 } 00353 00354 00355 void 00356 XMLGrammarPoolImpl::cleanUp() 00357 { 00358 fLocked = false; 00359 00360 clear(); 00361 } 00362 00363 00364 XERCES_CPP_NAMESPACE_END