/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * $Id$ */ // --------------------------------------------------------------------------- // Includes // --------------------------------------------------------------------------- #include #include #include #include #include #include #include #include #include XERCES_CPP_NAMESPACE_BEGIN // private function used to update fXSModel void XMLGrammarPoolImpl::createXSModel() { delete fXSModel; fXSModel = 0; fXSModel = new (getMemoryManager()) XSModel(this, getMemoryManager()); fXSModelIsValid = true; } // --------------------------------------------------------------------------- // XMLGrammarPoolImpl: constructor and destructor // --------------------------------------------------------------------------- XMLGrammarPoolImpl::~XMLGrammarPoolImpl() { delete fGrammarRegistry; delete fStringPool; if(fSynchronizedStringPool) delete fSynchronizedStringPool; if(fXSModel) delete fXSModel; } XMLGrammarPoolImpl::XMLGrammarPoolImpl(MemoryManager* const memMgr) :XMLGrammarPool(memMgr) ,fGrammarRegistry(0) ,fStringPool(0) ,fSynchronizedStringPool(0) ,fXSModel(0) ,fLocked(false) ,fXSModelIsValid(false) { fGrammarRegistry = new (memMgr) RefHashTableOf(29, true, memMgr); fStringPool = new (memMgr) XMLStringPool(109, memMgr); } // ----------------------------------------------------------------------- // Implementation of Grammar Pool Interface // ----------------------------------------------------------------------- bool XMLGrammarPoolImpl::cacheGrammar(Grammar* const gramToCache ) { if(fLocked || !gramToCache) return false; const XMLCh* grammarKey = gramToCache->getGrammarDescription()->getGrammarKey(); if (fGrammarRegistry->containsKey(grammarKey)) { return false; } fGrammarRegistry->put((void*) grammarKey, gramToCache); if (fXSModelIsValid && gramToCache->getGrammarType() == Grammar::SchemaGrammarType) { fXSModelIsValid = false; } return true; } Grammar* XMLGrammarPoolImpl::retrieveGrammar(XMLGrammarDescription* const gramDesc) { if (!gramDesc) return 0; /*** * This implementation simply use GrammarKey */ return fGrammarRegistry->get(gramDesc->getGrammarKey()); } Grammar* XMLGrammarPoolImpl::orphanGrammar(const XMLCh* const nameSpaceKey) { if (!fLocked) { Grammar* grammar = fGrammarRegistry->orphanKey(nameSpaceKey); if (fXSModelIsValid && grammar && grammar->getGrammarType() == Grammar::SchemaGrammarType) { fXSModelIsValid = false; } return grammar; } return 0; } RefHashTableOfEnumerator XMLGrammarPoolImpl::getGrammarEnumerator() const { return RefHashTableOfEnumerator(fGrammarRegistry, false, fGrammarRegistry->getMemoryManager()); } bool XMLGrammarPoolImpl::clear() { if (!fLocked) { fGrammarRegistry->removeAll(); fXSModelIsValid = false; if (fXSModel) { delete fXSModel; fXSModel = 0; } return true; } return false; } void XMLGrammarPoolImpl::lockPool() { if (!fLocked) { fLocked = true; MemoryManager *memMgr = getMemoryManager(); if(!fSynchronizedStringPool) { fSynchronizedStringPool = new (memMgr) XMLSynchronizedStringPool(fStringPool, 109, memMgr); } if (!fXSModelIsValid) { createXSModel(); } } } void XMLGrammarPoolImpl::unlockPool() { if (fLocked) { fLocked = false; if(fSynchronizedStringPool) { fSynchronizedStringPool->flushAll(); // if user calls Lock again, need to have null fSynchronizedStringPool delete fSynchronizedStringPool; fSynchronizedStringPool = 0; } fXSModelIsValid = false; if (fXSModel) { delete fXSModel; fXSModel = 0; } } } // ----------------------------------------------------------------------- // Implementation of Factory Interface // ----------------------------------------------------------------------- DTDGrammar* XMLGrammarPoolImpl::createDTDGrammar() { return new (getMemoryManager()) DTDGrammar(getMemoryManager()); } SchemaGrammar* XMLGrammarPoolImpl::createSchemaGrammar() { return new (getMemoryManager()) SchemaGrammar(getMemoryManager()); } XMLDTDDescription* XMLGrammarPoolImpl::createDTDDescription(const XMLCh* const systemId) { return new (getMemoryManager()) XMLDTDDescriptionImpl(systemId, getMemoryManager()); } XMLSchemaDescription* XMLGrammarPoolImpl::createSchemaDescription(const XMLCh* const targetNamespace) { return new (getMemoryManager()) XMLSchemaDescriptionImpl(targetNamespace, getMemoryManager()); } XSModel *XMLGrammarPoolImpl::getXSModel(bool& XSModelWasChanged) { XSModelWasChanged = false; if (fLocked || fXSModelIsValid) return fXSModel; createXSModel(); XSModelWasChanged = true; return fXSModel; } XMLStringPool *XMLGrammarPoolImpl::getURIStringPool() { if(fLocked) return fSynchronizedStringPool; return fStringPool; } // ----------------------------------------------------------------------- // serialization and deserialization support // ----------------------------------------------------------------------- /*** * * don't serialize * * XMLSynchronizedStringPool* fSynchronizedStringPool; */ /*** * .non-empty gramamrRegistry ***/ void XMLGrammarPoolImpl::serializeGrammars(BinOutputStream* const binOut) { RefHashTableOfEnumerator grammarEnum(fGrammarRegistry, false, getMemoryManager()); if (!(grammarEnum.hasMoreElements())) { ThrowXMLwithMemMgr(XSerializationException, XMLExcepts::XSer_GrammarPool_Empty, getMemoryManager()); } XSerializeEngine serEng(binOut, this); //version information serEng<<(unsigned int)XERCES_GRAMMAR_SERIALIZATION_LEVEL; //lock status serEng<serialize(serEng); /*** * Serialize RefHashTableOf* fGrammarRegistry; ***/ XTemplateSerializer::storeObject(fGrammarRegistry, serEng); } /*** * .empty stringPool * .empty gramamrRegistry ***/ void XMLGrammarPoolImpl::deserializeGrammars(BinInputStream* const binIn) { MemoryManager *memMgr = getMemoryManager(); unsigned int stringCount = fStringPool->getStringCount(); if (stringCount) { /*** * it contains only the four predefined one, that is ok * but we need to reset the string before deserialize it * ***/ if ( stringCount <= 4 ) { fStringPool->flushAll(); } else { ThrowXMLwithMemMgr(XSerializationException, XMLExcepts::XSer_StringPool_NotEmpty, memMgr); } } RefHashTableOfEnumerator grammarEnum(fGrammarRegistry, false, memMgr); if (grammarEnum.hasMoreElements()) { ThrowXMLwithMemMgr(XSerializationException, XMLExcepts::XSer_GrammarPool_NotEmpty, memMgr); } // This object will take care of cleaning up if an exception is // thrown during deserialization. JanitorMemFunCall cleanup(this, &XMLGrammarPoolImpl::cleanUp); try { XSerializeEngine serEng(binIn, this); //version information unsigned int StorerLevel; serEng>>StorerLevel; serEng.fStorerLevel = StorerLevel; // The storer level must match the loader level. // if (StorerLevel != (unsigned int)XERCES_GRAMMAR_SERIALIZATION_LEVEL) { XMLCh StorerLevelChar[5]; XMLCh LoaderLevelChar[5]; XMLString::binToText(StorerLevel, StorerLevelChar, 4, 10, memMgr); XMLString::binToText(XERCES_GRAMMAR_SERIALIZATION_LEVEL, LoaderLevelChar, 4, 10, memMgr); ThrowXMLwithMemMgr2(XSerializationException , XMLExcepts::XSer_Storer_Loader_Mismatch , StorerLevelChar , LoaderLevelChar , memMgr); } //lock status serEng>>fLocked; //StringPool, don't use >> fStringPool->serialize(serEng); /*** * Deserialize RefHashTableOf* fGrammarRegistry; ***/ XTemplateSerializer::loadObject(&fGrammarRegistry, 29, true, serEng); } catch(const OutOfMemoryException&) { // This is a special case, because we don't want // to execute cleanup code on out-of-memory // conditions. cleanup.release(); throw; } // Everything is OK, so we can release the cleanup object. cleanup.release(); if (fLocked) { createXSModel(); } } void XMLGrammarPoolImpl::cleanUp() { fLocked = false; clear(); } XERCES_CPP_NAMESPACE_END