Added Xerces-C++ 3.1.2
This commit is contained in:
@@ -0,0 +1,445 @@
|
||||
/*
|
||||
* 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 $
|
||||
*/
|
||||
|
||||
#include <xercesc/validators/common/GrammarResolver.hpp>
|
||||
#include <xercesc/validators/schema/SchemaSymbols.hpp>
|
||||
#include <xercesc/validators/schema/SchemaGrammar.hpp>
|
||||
#include <xercesc/validators/schema/XMLSchemaDescriptionImpl.hpp>
|
||||
#include <xercesc/validators/DTD/XMLDTDDescriptionImpl.hpp>
|
||||
#include <xercesc/framework/XMLGrammarPoolImpl.hpp>
|
||||
#include <xercesc/framework/psvi/XSAnnotation.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// GrammarResolver: Constructor and Destructor
|
||||
// ---------------------------------------------------------------------------
|
||||
GrammarResolver::GrammarResolver(XMLGrammarPool* const gramPool
|
||||
, MemoryManager* const manager)
|
||||
:fCacheGrammar(false)
|
||||
,fUseCachedGrammar(false)
|
||||
,fGrammarPoolFromExternalApplication(true)
|
||||
,fStringPool(0)
|
||||
,fGrammarBucket(0)
|
||||
,fGrammarFromPool(0)
|
||||
,fDataTypeReg(0)
|
||||
,fMemoryManager(manager)
|
||||
,fGrammarPool(gramPool)
|
||||
,fXSModel(0)
|
||||
,fGrammarPoolXSModel(0)
|
||||
,fGrammarsToAddToXSModel(0)
|
||||
{
|
||||
fGrammarBucket = new (manager) RefHashTableOf<Grammar>(29, true, manager);
|
||||
|
||||
/***
|
||||
* Grammars in this set are not owned
|
||||
*/
|
||||
fGrammarFromPool = new (manager) RefHashTableOf<Grammar>(29, false, manager);
|
||||
|
||||
if (!gramPool)
|
||||
{
|
||||
/***
|
||||
* We need to instantiate a default grammar pool object so that
|
||||
* all grammars and grammar components could be created through
|
||||
* the Factory methods
|
||||
*/
|
||||
fGrammarPool = new (manager) XMLGrammarPoolImpl(manager);
|
||||
fGrammarPoolFromExternalApplication=false;
|
||||
}
|
||||
fStringPool = fGrammarPool->getURIStringPool();
|
||||
|
||||
// REVISIT: size
|
||||
fGrammarsToAddToXSModel = new (manager) ValueVectorOf<SchemaGrammar*> (29, manager);
|
||||
}
|
||||
|
||||
GrammarResolver::~GrammarResolver()
|
||||
{
|
||||
delete fGrammarBucket;
|
||||
delete fGrammarFromPool;
|
||||
|
||||
if (fDataTypeReg)
|
||||
delete fDataTypeReg;
|
||||
|
||||
/***
|
||||
* delete the grammar pool iff it is created by this resolver
|
||||
*/
|
||||
if (!fGrammarPoolFromExternalApplication)
|
||||
delete fGrammarPool;
|
||||
|
||||
if (fXSModel)
|
||||
delete fXSModel;
|
||||
// don't delete fGrammarPoolXSModel! we don't own it!
|
||||
delete fGrammarsToAddToXSModel;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// GrammarResolver: Getter methods
|
||||
// ---------------------------------------------------------------------------
|
||||
DatatypeValidator*
|
||||
GrammarResolver::getDatatypeValidator(const XMLCh* const uriStr,
|
||||
const XMLCh* const localPartStr) {
|
||||
|
||||
DatatypeValidator* dv = 0;
|
||||
|
||||
if (XMLString::equals(uriStr, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) {
|
||||
|
||||
if (!fDataTypeReg) {
|
||||
|
||||
fDataTypeReg = new (fMemoryManager) DatatypeValidatorFactory(fMemoryManager);
|
||||
}
|
||||
|
||||
dv = fDataTypeReg->getDatatypeValidator(localPartStr);
|
||||
}
|
||||
else {
|
||||
|
||||
Grammar* grammar = getGrammar(uriStr);
|
||||
|
||||
if (grammar && grammar->getGrammarType() == Grammar::SchemaGrammarType) {
|
||||
|
||||
XMLBuffer nameBuf(128, fMemoryManager);
|
||||
|
||||
nameBuf.set(uriStr);
|
||||
nameBuf.append(chComma);
|
||||
nameBuf.append(localPartStr);
|
||||
|
||||
dv = ((SchemaGrammar*) grammar)->getDatatypeRegistry()->getDatatypeValidator(nameBuf.getRawBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
return dv;
|
||||
}
|
||||
|
||||
Grammar* GrammarResolver::getGrammar( const XMLCh* const namespaceKey)
|
||||
{
|
||||
if (!namespaceKey)
|
||||
return 0;
|
||||
|
||||
Grammar* grammar = fGrammarBucket->get(namespaceKey);
|
||||
|
||||
if (grammar)
|
||||
return grammar;
|
||||
|
||||
if (fUseCachedGrammar)
|
||||
{
|
||||
grammar = fGrammarFromPool->get(namespaceKey);
|
||||
if (grammar)
|
||||
{
|
||||
return grammar;
|
||||
}
|
||||
else
|
||||
{
|
||||
XMLSchemaDescription* gramDesc = fGrammarPool->createSchemaDescription(namespaceKey);
|
||||
Janitor<XMLGrammarDescription> janName(gramDesc);
|
||||
grammar = fGrammarPool->retrieveGrammar(gramDesc);
|
||||
if (grammar)
|
||||
{
|
||||
fGrammarFromPool->put((void*) grammar->getGrammarDescription()->getGrammarKey(), grammar);
|
||||
}
|
||||
return grammar;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Grammar* GrammarResolver::getGrammar( XMLGrammarDescription* const gramDesc)
|
||||
{
|
||||
if (!gramDesc)
|
||||
return 0;
|
||||
|
||||
Grammar* grammar = fGrammarBucket->get(gramDesc->getGrammarKey());
|
||||
|
||||
if (grammar)
|
||||
return grammar;
|
||||
|
||||
if (fUseCachedGrammar)
|
||||
{
|
||||
grammar = fGrammarFromPool->get(gramDesc->getGrammarKey());
|
||||
if (grammar)
|
||||
{
|
||||
return grammar;
|
||||
}
|
||||
else
|
||||
{
|
||||
grammar = fGrammarPool->retrieveGrammar(gramDesc);
|
||||
if (grammar)
|
||||
{
|
||||
fGrammarFromPool->put((void*) grammar->getGrammarDescription()->getGrammarKey(), grammar);
|
||||
}
|
||||
return grammar;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
RefHashTableOfEnumerator<Grammar>
|
||||
GrammarResolver::getGrammarEnumerator() const
|
||||
{
|
||||
return RefHashTableOfEnumerator<Grammar>(fGrammarBucket, false, fMemoryManager);
|
||||
}
|
||||
|
||||
RefHashTableOfEnumerator<Grammar>
|
||||
GrammarResolver::getReferencedGrammarEnumerator() const
|
||||
{
|
||||
return RefHashTableOfEnumerator<Grammar>(fGrammarFromPool, false, fMemoryManager);
|
||||
}
|
||||
|
||||
RefHashTableOfEnumerator<Grammar>
|
||||
GrammarResolver::getCachedGrammarEnumerator() const
|
||||
{
|
||||
return fGrammarPool->getGrammarEnumerator();
|
||||
}
|
||||
|
||||
bool GrammarResolver::containsNameSpace( const XMLCh* const nameSpaceKey )
|
||||
{
|
||||
if (!nameSpaceKey)
|
||||
return false;
|
||||
if (fGrammarBucket->containsKey(nameSpaceKey))
|
||||
return true;
|
||||
if (fUseCachedGrammar)
|
||||
{
|
||||
if (fGrammarFromPool->containsKey(nameSpaceKey))
|
||||
return true;
|
||||
|
||||
// Lastly, need to check in fGrammarPool
|
||||
XMLSchemaDescription* gramDesc = fGrammarPool->createSchemaDescription(nameSpaceKey);
|
||||
Janitor<XMLGrammarDescription> janName(gramDesc);
|
||||
Grammar* grammar = fGrammarPool->retrieveGrammar(gramDesc);
|
||||
if (grammar)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GrammarResolver::putGrammar(Grammar* const grammarToAdopt)
|
||||
{
|
||||
if (!grammarToAdopt)
|
||||
return;
|
||||
|
||||
/***
|
||||
* the grammar will be either in the grammarpool, or in the grammarbucket
|
||||
*/
|
||||
if (!fCacheGrammar || !fGrammarPool->cacheGrammar(grammarToAdopt))
|
||||
{
|
||||
// either we aren't caching or the grammar pool doesn't want it
|
||||
// so we need to look after it
|
||||
fGrammarBucket->put( (void*) grammarToAdopt->getGrammarDescription()->getGrammarKey(), grammarToAdopt );
|
||||
if (grammarToAdopt->getGrammarType() == Grammar::SchemaGrammarType)
|
||||
{
|
||||
fGrammarsToAddToXSModel->addElement((SchemaGrammar*) grammarToAdopt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// GrammarResolver: methods
|
||||
// ---------------------------------------------------------------------------
|
||||
void GrammarResolver::reset() {
|
||||
fGrammarBucket->removeAll();
|
||||
fGrammarsToAddToXSModel->removeAllElements();
|
||||
delete fXSModel;
|
||||
fXSModel = 0;
|
||||
}
|
||||
|
||||
void GrammarResolver::resetCachedGrammar()
|
||||
{
|
||||
//REVISIT: if the pool is locked this will fail... should throw an exception?
|
||||
fGrammarPool->clear();
|
||||
// Even though fXSModel and fGrammarPoolXSModel will be invalid don't touch
|
||||
// them here as getXSModel will handle this.
|
||||
|
||||
//to clear all other references to the grammars just deleted from fGrammarPool
|
||||
fGrammarFromPool->removeAll();
|
||||
|
||||
}
|
||||
|
||||
void GrammarResolver::cacheGrammars()
|
||||
{
|
||||
RefHashTableOfEnumerator<Grammar> grammarEnum(fGrammarBucket, false, fMemoryManager);
|
||||
ValueVectorOf<XMLCh*> keys(8, fMemoryManager);
|
||||
unsigned int keyCount = 0;
|
||||
|
||||
// Build key set
|
||||
while (grammarEnum.hasMoreElements())
|
||||
{
|
||||
XMLCh* grammarKey = (XMLCh*) grammarEnum.nextElementKey();
|
||||
keys.addElement(grammarKey);
|
||||
keyCount++;
|
||||
}
|
||||
|
||||
// PSVI: assume everything will be added, if caching fails add grammar back
|
||||
// into vector
|
||||
fGrammarsToAddToXSModel->removeAllElements();
|
||||
|
||||
// Cache
|
||||
for (unsigned int i = 0; i < keyCount; i++)
|
||||
{
|
||||
XMLCh* grammarKey = keys.elementAt(i);
|
||||
|
||||
/***
|
||||
* It is up to the GrammarPool implementation to handle duplicated grammar
|
||||
*/
|
||||
Grammar* grammar = fGrammarBucket->get(grammarKey);
|
||||
if(fGrammarPool->cacheGrammar(grammar))
|
||||
{
|
||||
// only orphan grammar if grammar pool accepts caching of it
|
||||
fGrammarBucket->orphanKey(grammarKey);
|
||||
}
|
||||
else if (grammar->getGrammarType() == Grammar::SchemaGrammarType)
|
||||
{
|
||||
// add it back to list of grammars not in grammar pool
|
||||
fGrammarsToAddToXSModel->addElement((SchemaGrammar*) grammar);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// GrammarResolver: Setter methods
|
||||
// ---------------------------------------------------------------------------
|
||||
void GrammarResolver::cacheGrammarFromParse(const bool aValue)
|
||||
{
|
||||
reset();
|
||||
fCacheGrammar = aValue;
|
||||
}
|
||||
|
||||
Grammar* GrammarResolver::orphanGrammar(const XMLCh* const nameSpaceKey)
|
||||
{
|
||||
if (fCacheGrammar)
|
||||
{
|
||||
Grammar* grammar = fGrammarPool->orphanGrammar(nameSpaceKey);
|
||||
if (grammar)
|
||||
{
|
||||
if (fGrammarFromPool->containsKey(nameSpaceKey))
|
||||
fGrammarFromPool->removeKey(nameSpaceKey);
|
||||
}
|
||||
// Check to see if it's in fGrammarBucket, since
|
||||
// we put it there if the grammar pool refused to
|
||||
// cache it.
|
||||
else if (fGrammarBucket->containsKey(nameSpaceKey))
|
||||
{
|
||||
grammar = fGrammarBucket->orphanKey(nameSpaceKey);
|
||||
}
|
||||
|
||||
return grammar;
|
||||
}
|
||||
else
|
||||
{
|
||||
return fGrammarBucket->orphanKey(nameSpaceKey);
|
||||
}
|
||||
}
|
||||
|
||||
XSModel *GrammarResolver::getXSModel()
|
||||
{
|
||||
XSModel* xsModel;
|
||||
if (fCacheGrammar || fUseCachedGrammar)
|
||||
{
|
||||
// We know if the grammarpool changed thru caching, orphaning and erasing
|
||||
// but NOT by other mechanisms such as lockPool() or unlockPool() so it
|
||||
// is safest to always get it. The grammarPool XSModel will only be
|
||||
// regenerated if something changed.
|
||||
bool XSModelWasChanged;
|
||||
// The grammarpool will always return an xsmodel, even if it is just
|
||||
// the schema for schema xsmodel...
|
||||
xsModel = fGrammarPool->getXSModel(XSModelWasChanged);
|
||||
if (XSModelWasChanged)
|
||||
{
|
||||
// we know the grammarpool XSModel has changed or this is the
|
||||
// first call to getXSModel
|
||||
if (!fGrammarPoolXSModel && (fGrammarsToAddToXSModel->size() == 0) &&
|
||||
!fXSModel)
|
||||
{
|
||||
fGrammarPoolXSModel = xsModel;
|
||||
return fGrammarPoolXSModel;
|
||||
}
|
||||
else
|
||||
{
|
||||
fGrammarPoolXSModel = xsModel;
|
||||
// We had previously augmented the grammar pool XSModel
|
||||
// with our our grammars or we would like to upate it now
|
||||
// so we have to regenerate the XSModel
|
||||
fGrammarsToAddToXSModel->removeAllElements();
|
||||
RefHashTableOfEnumerator<Grammar> grammarEnum(fGrammarBucket, false, fMemoryManager);
|
||||
while (grammarEnum.hasMoreElements())
|
||||
{
|
||||
Grammar& grammar = (Grammar&) grammarEnum.nextElement();
|
||||
if (grammar.getGrammarType() == Grammar::SchemaGrammarType)
|
||||
fGrammarsToAddToXSModel->addElement((SchemaGrammar*)&grammar);
|
||||
}
|
||||
delete fXSModel;
|
||||
if (fGrammarsToAddToXSModel->size())
|
||||
{
|
||||
fXSModel = new (fMemoryManager) XSModel(fGrammarPoolXSModel, this, fMemoryManager);
|
||||
fGrammarsToAddToXSModel->removeAllElements();
|
||||
return fXSModel;
|
||||
}
|
||||
fXSModel = 0;
|
||||
return fGrammarPoolXSModel;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// we know that the grammar pool XSModel is the same as before
|
||||
if (fGrammarsToAddToXSModel->size())
|
||||
{
|
||||
// we need to update our fXSModel with the new grammars
|
||||
if (fXSModel)
|
||||
{
|
||||
xsModel = new (fMemoryManager) XSModel(fXSModel, this, fMemoryManager);
|
||||
fXSModel = xsModel;
|
||||
}
|
||||
else
|
||||
{
|
||||
fXSModel = new (fMemoryManager) XSModel(fGrammarPoolXSModel, this, fMemoryManager);
|
||||
}
|
||||
fGrammarsToAddToXSModel->removeAllElements();
|
||||
return fXSModel;
|
||||
}
|
||||
// Nothing has changed!
|
||||
if (fXSModel)
|
||||
{
|
||||
return fXSModel;
|
||||
}
|
||||
else if (fGrammarPoolXSModel)
|
||||
{
|
||||
return fGrammarPoolXSModel;
|
||||
}
|
||||
fXSModel = new (fMemoryManager) XSModel(0, this, fMemoryManager);
|
||||
return fXSModel;
|
||||
}
|
||||
}
|
||||
// Not Caching...
|
||||
if (fGrammarsToAddToXSModel->size())
|
||||
{
|
||||
xsModel = new (fMemoryManager) XSModel(fXSModel, this, fMemoryManager);
|
||||
fGrammarsToAddToXSModel->removeAllElements();
|
||||
fXSModel = xsModel;
|
||||
}
|
||||
else if (!fXSModel)
|
||||
{
|
||||
// create a new model only if we didn't have one already
|
||||
fXSModel = new (fMemoryManager) XSModel(0, this, fMemoryManager);
|
||||
}
|
||||
return fXSModel;
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
Reference in New Issue
Block a user