blob: a6631679b2a92872bf810f02223a2be9f2ea145d [file] [log] [blame]
/*=========================================================================
* Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
* This product is protected by U.S. and international copyright
* and intellectual property laws. Pivotal products are covered by
* more patents listed at http://www.pivotal.io/patents.
*========================================================================
*/
#include "CacheXmlParser.hpp"
#include "CacheRegionHelper.hpp"
#include "../CacheAttributesFactory.hpp"
#include "../PoolManager.hpp"
#include "../PoolFactory.hpp"
#include "AutoDelete.hpp"
#include "CacheImpl.hpp"
#if defined (_WIN32)
#include <windows.h>
#else
#include <dlfcn.h>
#endif
using namespace gemfire;
namespace gemfire_impl {
void* getFactoryFunc( const char* lib, const char* funcName );
}
using namespace gemfire_impl;
/////////////////XML Parser Callback functions////////////////////////
extern "C" void startElementSAX2Function
(void *ctx, const xmlChar *name, const xmlChar **atts)
{
CacheXmlParser* parser = (CacheXmlParser*)ctx;
if (!parser)
Log::error("CacheXmlParser::startElementSAX2Function:Parser is NULL");
if ((!parser->isCacheXmlException()) &&
(!parser->isIllegalStateException()) &&
(!parser->isAnyOtherException()))
{
try
{
if(strcmp( (char*)name, parser->CACHE) == 0)
{
parser->startCache(ctx, atts);
}
else if(strcmp( (char*)name, parser->CLIENT_CACHE) == 0)
{
parser->startCache(ctx, atts);
}
else if(strcmp( (char*)name, parser->PDX) == 0)
{
parser->startPdx(atts);
}
else if(strcmp( (char*)name, parser->REGION) == 0)
{
parser->incNesting();
parser->startRegion( atts, parser->isRootLevel() );
}
else if(strcmp( (char*)name, parser->ROOT_REGION) == 0)
{
parser->incNesting();
parser->startRegion( atts, parser->isRootLevel() );
}
else if(strcmp( (char*)name, parser->REGION_ATTRIBUTES) == 0)
{
parser->startRegionAttributes(atts);
}
else if(strcmp( (char*)name, parser->REGION_TIME_TO_LIVE) == 0)
{
}
else if(strcmp( (char*)name, parser->REGION_IDLE_TIME) == 0)
{
}
else if(strcmp( (char*)name, parser->ENTRY_TIME_TO_LIVE) == 0)
{
}
else if(strcmp( (char*)name, parser->ENTRY_IDLE_TIME) == 0)
{
}
else if(strcmp( (char*)name, parser->EXPIRATION_ATTRIBUTES) == 0)
{
parser->startExpirationAttributes(atts);
}
else if(strcmp( (char*)name, parser->CACHE_LOADER) == 0)
{
parser->startCacheLoader(atts);
}
else if(strcmp( (char* )name, parser->CACHE_WRITER)== 0)
{
parser->startCacheWriter(atts);
}
else if(strcmp( (char*)name, parser->CACHE_LISTENER) == 0)
{
parser->startCacheListener(atts);
}
else if(strcmp( (char*)name, parser->PARTITION_RESOLVER) == 0)
{
parser->startPartitionResolver(atts);
}
else if (strcmp( (char*)name, parser->PERSISTENCE_MANAGER) == 0)
{
parser->startPersistenceManager(atts);
}
else if (strcmp( (char*)name, parser->PROPERTIES) == 0)
{
}
else if (strcmp( (char*)name, parser->PROPERTY) == 0)
{
parser->startPersistenceProperties(atts);
}
else if (strcmp( (char*)name, parser->POOL) == 0)
{
parser->startPool(atts);
}
else if (strcmp( (char*)name, parser->LOCATOR) == 0)
{
parser->startLocator(atts);
}
else if (strcmp( (char*)name, parser->SERVER) == 0)
{
parser->startServer(atts);
}
else
{
std::string temp((char*)name);
std::string s = "XML:Unknown XML element \"" + temp + "\"";
throw CacheXmlException(s.c_str());
}
}
catch (const CacheXmlException& e)
{
parser->setCacheXmlException();
std::string s = e.getMessage();
parser->setError(s);
}
catch (const IllegalStateException& ex)
{
parser->setIllegalStateException();
std::string s = ex.getMessage();
parser->setError(s);
}
catch (const Exception& ex)
{
parser->setAnyOtherException();
std::string s = ex.getMessage();
parser->setError(s);
}
}//flag
}
extern "C" void endElementSAX2Function(void * ctx, const xmlChar * name)
{
CacheXmlParser* parser = (CacheXmlParser*)ctx;
if (!parser)
Log::error("Error occured while xml parsing: CacheXmlParser:startElementSAX2Function:Parser is NULL");
if ((!parser->isCacheXmlException()) &&
(!parser->isIllegalStateException()) &&
(!parser->isAnyOtherException()))
{
try
{
if(strcmp( (char*)name, parser->CACHE)== 0)
{
parser->endCache();
}
else if(strcmp( (char*)name, parser->CLIENT_CACHE)== 0)
{
parser->endCache();
}
else if(strcmp( (char*)name, parser->PDX)== 0)
{
parser->endPdx();
}
else if(strcmp( (char*)name, parser->REGION)== 0)
{
parser->endRegion( parser->isRootLevel() );
parser->decNesting();
}
else if(strcmp( (char*)name, parser->ROOT_REGION)== 0)
{
parser->endRegion( parser->isRootLevel() );
parser->decNesting();
}
else if(strcmp( (char*)name, parser->REGION_ATTRIBUTES)== 0)
{
parser->endRegionAttributes();
}
else if(strcmp( (char*)name, parser->REGION_TIME_TO_LIVE)== 0)
{
parser->endRegionTimeToLive();
}
else if(strcmp( (char*)name, parser->REGION_IDLE_TIME)== 0)
{
parser->endRegionIdleTime();
}
else if(strcmp( (char*)name, parser->ENTRY_TIME_TO_LIVE)== 0)
{
parser->endEntryTimeToLive();
}
else if(strcmp( (char*)name, parser->ENTRY_IDLE_TIME)== 0)
{
parser->endEntryIdleTime();
}
else if(strcmp( (char*)name,parser->EXPIRATION_ATTRIBUTES)== 0)
{
}
else if(strcmp( (char*)name, parser->CACHE_LOADER)== 0)
{
}
else if(strcmp( (char*)name, parser->CACHE_WRITER)== 0)
{
}
else if(strcmp( (char*)name, parser->CACHE_LISTENER)== 0)
{
}
else if(strcmp( (char*)name, parser->PARTITION_RESOLVER)== 0)
{
}
else if(strcmp( (char*)name, parser->PERSISTENCE_MANAGER) == 0)
{
parser->endPersistenceManager();
}
else if (strcmp( (char*)name, parser->PROPERTIES) == 0)
{
}
else if (strcmp( (char*)name, parser->PROPERTY) == 0)
{
}
else if (strcmp( (char*)name, parser->POOL) == 0)
{
parser->endPool();
}
else if (strcmp( (char*)name, parser->LOCATOR) == 0)
{
//parser->endLocator();
}
else if (strcmp( (char*)name, parser->SERVER) == 0)
{
//parser->endServer();
}
else
{
std::string temp((char*)name);
std::string s = "XML:Unknown XML element \"" + temp + "\"";
throw CacheXmlException(s.c_str());
}
}
catch(CacheXmlException& e)
{
parser->setCacheXmlException();
std::string s = e.getMessage();
parser->setError(s);
}
catch(IllegalStateException& ex)
{
parser->setIllegalStateException();
std::string s = ex.getMessage();
parser->setError(s);
}
catch(Exception& ex)
{
parser->setAnyOtherException();
std::string s = ex.getMessage();
parser->setError(s);
}
}//flag
}
/**
* warningDebug:
* @ctxt: An XML parser context
* @msg: the message to display/transmit
* @...: extra parameters for the message display
*
* Display and format a warning messages, gives file, line, position and
* extra parameters.
*/
extern "C" void warningDebug(void *ctx, const char *msg, ...)
{
char logmsg[2048];
va_list args;
va_start(args, msg);
vsprintf(logmsg, msg, args);
va_end(args);
LOGWARN( "SAX.warning during XML declarative client initialization: %s", logmsg );
}
/**
* fatalErrorDebug:
* @ctxt: An XML parser context
* @msg: the message to display/transmit
* @...: extra parameters for the message display
*
* Display and format a fatalError messages, gives file, line, position and
* extra parameters.
*/
extern "C" void fatalErrorDebug(void *ctx , const char *msg, ...)
{
char buf[1024];
va_list args;
va_start(args, msg);
CacheXmlParser* parser = (CacheXmlParser*)ctx;
vsprintf (buf,msg,args);
std::string stringMsg(buf);
parser->setParserMessage(parser->getParserMessage() + stringMsg);
va_end(args);
}
/////////////End of XML Parser Cackllback functions///////////////
///////////////static variables of the class////////////////////////
LibraryCacheLoaderFn CacheXmlParser::managedCacheLoaderFn = NULL;
LibraryCacheListenerFn CacheXmlParser::managedCacheListenerFn = NULL;
LibraryPartitionResolverFn CacheXmlParser::managedPartitionResolverFn = NULL;
LibraryCacheWriterFn CacheXmlParser::managedCacheWriterFn = NULL;
LibraryPersistenceManagerFn CacheXmlParser::managedPersistenceManagerFn = NULL;
//////////////////////////////////////////////////////////////////
CacheXmlParser::CacheXmlParser() :
m_parserMessage(""), m_config(NULLPTR), m_cacheCreation(NULL),
m_attrs(NULLPTR), m_nestedRegions(0), m_flagCacheXmlException(false),
m_flagExpirationAttribute(false), m_flagIllegalStateException(false),
m_flagAnyOtherException(false)
{
static xmlSAXHandler saxHandler =
{
NULL, /* internalSubset */
NULL, /* isStandalone */
NULL, /* hasInternalSubset */
NULL, /* hasExternalSubset */
NULL, /* resolveEntity */
NULL, /* getEntity */
NULL, /* entityDecl */
NULL, /* notationDecl */
NULL, /* attributeDecl */
NULL, /* elementDecl */
NULL, /* unparsedEntityDecl */
NULL, /* setDocumentLocator */
NULL, /* startDocument */
NULL, /* endDocument */
startElementSAX2Function, /* startElement */
endElementSAX2Function, /* endElement */
NULL, /* reference */
NULL, /* characters */
NULL, /* ignorableWhitespace */
NULL, /* processingInstruction */
NULL, //commentDebug, /* comment */
warningDebug, /* xmlParserWarning */
fatalErrorDebug, /* xmlParserError */
NULL, /* xmlParserError */
NULL, /* getParameterEntity */
NULL, /* cdataBlock; */
NULL, /* externalSubset; */
XML_SAX2_MAGIC,
NULL,
NULL,/* startElementNs */
NULL,/* endElementNs */
NULL /* xmlStructuredErrorFunc */
};
m_saxHandler = saxHandler;
namedRegions = CacheImpl::getRegionShortcut();
}
////////////////////// Static Methods //////////////////////
/**
* Parses XML data and from it creates an instance of
* <code>CacheXmlParser</code> that can be used to create
* the {@link Cache}, etc.
*
* @param cacheXml
* The xml file
*
* @throws CacheXmlException
* Something went wrong while parsing the XML
* @throws OutOfMemoryException
* @throws CacheXmlException
* If xml file is not well-formed or
* Something went wrong while parsing the XML
* @throws IllegalStateException
* If xml file is well-flrmed but not valid
* @throws UnknownException otherwise
*/
CacheXmlParser* CacheXmlParser::parse(const char* cacheXml)
{
int res =0;
CacheXmlParser* handler;
GF_NEW(handler, CacheXmlParser());
// use RAII to delete the handler object in case of exceptions
DeleteObject<CacheXmlParser> delHandler(handler);
{
res = xmlSAXUserParseFile(&handler->m_saxHandler, handler, cacheXml);
if(res == -1)
{
std::string temp(cacheXml);
std::string tempString = "Xml file " + temp + " not found\n";
throw CacheXmlException(tempString.c_str());
}
if (res != 0) //xml file is not well-formed
{
char buf[256];
ACE_OS::snprintf(buf, 256, "Error code returned by xml parser is : %d ",res);
Log::error(buf);
std::string temp =
"Xml file is not well formed. Error _stack: \n"
+ handler->m_parserMessage;
throw CacheXmlException(temp.c_str());
}
std::string temp = handler->getError();
if(temp == "")
{
Log::info("Xml file parsed successfully");
}
else //well formed, but not according to our specs(dtd errors thrown manually)
{
if(handler->m_flagCacheXmlException)
throw CacheXmlException(temp.c_str());
else if (handler->m_flagIllegalStateException)
throw IllegalStateException(temp.c_str());
else if(handler->m_flagAnyOtherException)
throw UnknownException(temp.c_str());
handler->setError("");
}
delHandler.noDelete();
return handler;
}
}
void CacheXmlParser::setAttributes( Cache* cache )
{
if (m_attrs != NULLPTR) {
CacheRegionHelper::getCacheImpl( cache )->setAttributes( m_attrs );
}
}
/**
* Creates cache artifacts ({@link Cache}s, etc.) based upon the XML
* parsed by this parser.
*
* @param cache
* The cachewhcih is to be populated
* @throws OutOfMemoryException if the memory allocation failed
* @throws NotConnectedException if the cache is not connected
* @throws InvalidArgumentException if the attributePtr is NULL.
* or if RegionAttributes is null or if regionName is null,
* the empty string, or contains a '/'
* @throws RegionExistsException
* @throws CacheClosedException if the cache is closed
* at the time of region creation
* @throws UnknownException otherwise
*
*/
void CacheXmlParser::create(Cache* cache)
{
// use DeleteObject class to delete m_cacheCreation in case of exceptions
DeleteObject<CacheXmlCreation> delCacheCreation(m_cacheCreation);
if (cache == NULL) {
std::string s = "XML:No cache specified for performing configuration";
throw IllegalArgumentException(s.c_str());
}
if (!m_cacheCreation) {
throw CacheXmlException("XML: Element <cache> was not provided in the xml");
}
m_cacheCreation->create(cache);
delCacheCreation.noDelete();
Log::info("Declarative configuration of cache completed successfully");
}
void CacheXmlParser::startCache(void* ctx,const xmlChar **attrs)
{
int attrsCount = 0;
if ( attrs != NULL ) {
CacheAttributesFactory cFact;
char* attrName;
char* attrValue;
while ( ( attrName = (char*)attrs[ attrsCount++ ] ) != NULL ) {
attrValue = (char*)attrs[ attrsCount++ ];
if ( attrValue == NULL ) {
std::string exStr = "XML: No value provided for attribute: ";
exStr += attrName;
throw CacheXmlException( exStr.c_str( ) );
}
if ( strcmp( attrName, ENDPOINTS ) == 0 ) {
cFact.setEndpoints( attrValue );
} else if ( strcmp( attrName, REDUNDANCY_LEVEL ) == 0 ) {
cFact.setRedundancyLevel( atoi( attrValue ) );
} else {
std::string exStr = "XML: Unknown cache attribute: ";
exStr += attrName;
throw CacheXmlException( exStr.c_str( ) );
}
}
m_attrs = cFact.createCacheAttributes( );
}
GF_NEW(m_cacheCreation, CacheXmlCreation());
}
void CacheXmlParser::startPdx(const xmlChar **atts)
{
if(!atts)
{
return;
}
int attrsCount = 0;
while(atts[attrsCount] != NULL)
{
const char * name = (const char *) atts[attrsCount];
++attrsCount;
const char * value = (const char *) atts[attrsCount];
if (strcmp(name, IGNORE_UNREAD_FIELDS)==0)
{
bool ignorePdxUnreadfields = false;
if( strcmp("true",value)== 0
|| strcmp("TRUE",value)== 0)
{
ignorePdxUnreadfields = true;
}
else if (strcmp("false",value)== 0
|| strcmp("FALSE",value)== 0)
{
ignorePdxUnreadfields = false;
}
else
{
std::string temp(value);
std::string s = "XML: "+ temp +
" is not a valid value for the attribute <ignore-unread-fields>";
throw CacheXmlException(s.c_str());
}
m_cacheCreation->setPdxIgnoreUnreadField(ignorePdxUnreadfields);
}
else if (strcmp(name, READ_SERIALIZED)==0)
{
bool readSerialized = false;
if( strcmp("true",value)== 0
|| strcmp("TRUE",value)== 0)
{
readSerialized = true;
}
else if (strcmp("false",value)== 0
|| strcmp("FALSE",value)== 0)
{
readSerialized = false;
}
else
{
std::string temp(value);
std::string s = "XML: "+ temp +
" is not a valid value for the attribute <ignore-unread-fields>";
throw CacheXmlException(s.c_str());
}
m_cacheCreation->setPdxReadSerialized(readSerialized);
}
else
{
throw CacheXmlException("XML:Unrecognized pdx attribute");
}
++attrsCount;
}
}
void CacheXmlParser::endPdx()
{
}
void CacheXmlParser::startLocator(const xmlChar **atts)
{
int attrsCount = 0;
if(!atts)
{
/* adongre
* CID 28741: Parse warning (PW.EXPR_HAS_NO_EFFECT)expression has no effect
*/
std::string s = "XML:No attributes provided for <locator>. "
"A locator requires a host and port";
throw CacheXmlException(s.c_str());
}
PoolFactory * factory = reinterpret_cast<PoolFactory*>(_stack.top());
const char * host = NULL;
const char * port = NULL;
while(atts[attrsCount] != NULL)
{
const char * name = (const char *) atts[attrsCount];
++attrsCount;
const char * value = (const char *) atts[attrsCount];
if (strcmp(name, HOST)==0)
{
host = value;
}
else if (strcmp(name, PORT)==0)
{
port = value;
}
else
{
throw CacheXmlException("XML:Unrecognized locator attribute");
}
++attrsCount;
}
if(attrsCount < 4)
{
throw CacheXmlException("XML:Not enough attributes provided for a <locator> - host and port required");
}
factory->addLocator(host, atoi(port));
}
void CacheXmlParser::startServer(const xmlChar **atts)
{
int attrsCount = 0;
if(!atts)
{
/* adongre
* CID 28742: Parse warning (PW.EXPR_HAS_NO_EFFECT)expression has no effect
*/
std::string s = "XML:No attributes provided for <server>. A server requires a host and port";
throw CacheXmlException(s.c_str());
}
PoolFactory * factory = reinterpret_cast<PoolFactory*>(_stack.top());
const char * host = NULL;
const char * port = NULL;
while(atts[attrsCount] != NULL)
{
const char * name = (const char *) atts[attrsCount];
++attrsCount;
const char * value = (const char *) atts[attrsCount];
if (strcmp(name, HOST)==0)
{
host = value;
}
else if (strcmp(name, PORT)==0)
{
port = value;
}
else
{
throw CacheXmlException("XML:Unrecognized server attribute");
}
++attrsCount;
}
if(attrsCount < 4)
{
throw CacheXmlException("XML:Not enough attributes provided for a <server> - host and port required");
}
factory->addServer(host, atoi(port));
}
void CacheXmlParser::startPool(const xmlChar ** atts)
{
int attrsCount = 0;
if(!atts)
{
std::string s = "XML:No attributes provided for <pool>. "
"A pool cannot be created without a name";
throw CacheXmlException(s.c_str());
}
PoolFactoryPtr factory = PoolManager::createFactory();
const char * poolName = NULL;
while(atts[attrsCount] != NULL)
{
const char * name = (const char *) atts[attrsCount];
++attrsCount;
const char * value = (const char *) atts[attrsCount];
if (strcmp(name, NAME)==0)
{
poolName = value;
}
else
{
setPoolInfo(factory.ptr(), name, value);
}
++attrsCount;
}
if(attrsCount < 2)
{
std::string s = "XML:No attributes provided for a <pool> - at least the name is required";
throw CacheXmlException(s.c_str());
}
PoolXmlCreation * poolxml = new PoolXmlCreation(poolName, factory);
_stack.push(poolxml);
_stack.push(factory.ptr());
}
void CacheXmlParser::endPool()
{
_stack.pop(); // remove factory
PoolXmlCreation * poolxml = reinterpret_cast<PoolXmlCreation*>(_stack.top());
_stack.pop(); // remove pool
m_cacheCreation->addPool(poolxml);
}
void CacheXmlParser::setPoolInfo(PoolFactory * factory, const char * name, const char * value)
{
if (strcmp(name, FREE_CONNECTION_TIMEOUT)==0)
{
factory->setFreeConnectionTimeout(atoi(value));
}
else if(strcmp(name, MULTIUSER_SECURE_MODE)==0)
{
if (ACE_OS::strcasecmp(value, "true")==0)
{
factory->setMultiuserAuthentication(true);
}
else
{
factory->setMultiuserAuthentication(false);
}
}
else if (strcmp(name, IDLE_TIMEOUT)==0)
{
factory->setIdleTimeout(atoi(value));
}
else if (strcmp(name, LOAD_CONDITIONING_INTERVAL)==0)
{
factory->setLoadConditioningInterval(atoi(value));
}
else if (strcmp(name, MAX_CONNECTIONS)==0)
{
factory->setMaxConnections(atoi(value));
}
else if (strcmp(name, MIN_CONNECTIONS)==0)
{
factory->setMinConnections(atoi(value));
}
else if (strcmp(name, PING_INTERVAL)==0)
{
factory->setPingInterval(atoi(value));
}
else if (strcmp(name, UPDATE_LOCATOR_LIST_INTERVAL)==0)
{
factory->setUpdateLocatorListInterval(atoi(value));
}
else if (strcmp(name, READ_TIMEOUT)==0)
{
factory->setReadTimeout(atoi(value));
}
else if (strcmp(name, RETRY_ATTEMPTS)==0)
{
factory->setRetryAttempts(atoi(value));
}
else if (strcmp(name, SERVER_GROUP)==0)
{
factory->setServerGroup(value);
}
else if (strcmp(name, SOCKET_BUFFER_SIZE)==0)
{
factory->setSocketBufferSize(atoi(value));
}
else if (strcmp(name, STATISTIC_INTERVAL)==0)
{
factory->setStatisticInterval(atoi(value));
}
else if (strcmp(name, SUBSCRIPTION_ACK_INTERVAL)==0)
{
factory->setSubscriptionAckInterval(atoi(value));
}
else if (strcmp(name, SUBSCRIPTION_ENABLED)==0)
{
if (ACE_OS::strcasecmp(value, "true")==0)
{
factory->setSubscriptionEnabled(true);
}
else
{
factory->setSubscriptionEnabled(false);
}
}
else if (strcmp(name, SUBSCRIPTION_MTT)==0)
{
factory->setSubscriptionMessageTrackingTimeout(atoi(value));
}
else if (strcmp(name, SUBSCRIPTION_REDUNDANCY)==0)
{
factory->setSubscriptionRedundancy(atoi(value));
}
else if (strcmp(name, THREAD_LOCAL_CONNECTIONS)==0)
{
if (ACE_OS::strcasecmp(value, "true")==0)
{
factory->setThreadLocalConnections(true);
}
else
{
factory->setThreadLocalConnections(false);
}
}
else if (strcmp(name, PR_SINGLE_HOP_ENABLED)==0)
{
if (ACE_OS::strcasecmp(value, "true")==0)
{
factory->setPRSingleHopEnabled(true);
}
else
{
factory->setPRSingleHopEnabled(false);
}
}
else
{
std::string s = "XML:Unrecognized pool attribute ";
s += name;
throw CacheXmlException(s.c_str());
}
}
/**
* When a <code>region</code> element is first encountered, we
* create a {@link RegionCreation} and push it on the _stack.
* An {@link AttributesFactory }is also created and puhed on _stack.
*/
void CacheXmlParser::startRegion(const xmlChar **atts, bool isRoot)
{
int attrsCount = 0;
if (!atts) {
std::string s = "XML:No attributes provided for <region>. "
"A region cannot be created without a name";
throw CacheXmlException(s.c_str());
}
while (atts[attrsCount] != NULL)
++attrsCount;
if (attrsCount < 2 || attrsCount > 4) {
std::string s =
"XML:Incorrect number of attributes provided for a <region>";
throw CacheXmlException(s.c_str());
}
char* regionName = NULL;
char* refid = NULL;
for (int i = 0; (atts[i] != NULL); i++) {
if (atts[i] != NULL) {
char* name = (char *) atts[i];
i++;
if (atts[i] != NULL) {
char* value = (char *) atts[i];
if (strcmp(name, "name") == 0) {
regionName = value;
} else if (strcmp(name, "refid") == 0) {
refid = value;
} else {
std::string temp(name);
std::string s = "XML:<region> does not contain the attribute :"
+ temp + "";
throw CacheXmlException(s.c_str());
}
}
}
}
if (regionName == NULL || strcmp(regionName, "") == 0)//empty string
{
std::string s =
"XML:The attribute name of <region> should be specified and cannot be empty ";
throw CacheXmlException(s.c_str());
}
RegionXmlCreation* region = new RegionXmlCreation(regionName, isRoot);
if (!region)
throw UnknownException("CacheXmlParser::startRegion:Out of memeory");
_stack.push(region);
AttributesFactory* attrsFactory = NULL;
if (refid == NULL) {
attrsFactory = new AttributesFactory();
} else {
std::string refidStr(refid);
if (namedRegions.find(refidStr) != namedRegions.end()) {
attrsFactory = new AttributesFactory(namedRegions[refidStr]);
} else {
std::string s = "XML:referenced named attribute '" + refidStr
+ "' does not exist.";
throw CacheXmlException(s.c_str());
}
}
region->setAttributes(attrsFactory->createRegionAttributes());
delete attrsFactory;
}
void CacheXmlParser::startSubregion(const xmlChar **atts)
{
startRegion(atts, false);
}
void CacheXmlParser::startRootRegion(const xmlChar **atts)
{
startRegion(atts, true);
}
void CacheXmlParser::startRegionAttributes(const xmlChar **atts)
{
bool isDistributed = false;
bool isTCR = false;
AttributesFactory* attrsFactory = NULL;
if(atts)
{
int attrsCount = 0;
while(atts[attrsCount] != NULL)
++attrsCount;
if(attrsCount > 24 ) // Remember to change this when the number changes
{
std::string s =
"XML:Number of attributes provided for <region-attributes> are more";
throw CacheXmlException(s.c_str());
}
char* refid = NULL;
for (int i = 0; (atts[i] != NULL); i++) {
i++;
if (atts[i] != NULL) {
char * value = (char*) atts[i];
if (strcmp(value, "") == 0) {
std::string s = "XML:In the <region-attributes> element no "
"attribute can be set to empty string. It should either have a "
"value or the attribute should be removed. In the latter case "
"the default value will be set";
throw CacheXmlException(s.c_str());
}
if (strcmp((char*) atts[i - 1], ID) == 0) {
RegionXmlCreation* region =
reinterpret_cast<RegionXmlCreation *> (_stack.top());
region->setAttrId(std::string((char*) atts[i]));
} else if (strcmp((char*) atts[i - 1], REFID) == 0) {
refid = (char*) atts[i];
}
}
}
if (refid == NULL) {
RegionXmlCreation* region = reinterpret_cast<RegionXmlCreation *> (_stack.top());
attrsFactory = new AttributesFactory(region->getAttributes());
} else {
std::string refidStr(refid);
if (namedRegions.find(refidStr) != namedRegions.end()) {
attrsFactory = new AttributesFactory(namedRegions[refidStr]);
} else {
std::string s = "XML:referenced named attribute '" + refidStr
+ "' does not exist.";
throw CacheXmlException(s.c_str());
}
}
if (!attrsFactory)
throw UnknownException(
"CacheXmlParser::startRegionAttributes:Out of memeory");
_stack.push(attrsFactory);
for (int i = 0;(atts[i] != NULL);i++)
{
if (strcmp(ID, (char*) atts[i]) == 0 || strcmp(REFID, (char*) atts[i]) == 0)
{
i++;
continue;
}
else if (strcmp(SCOPE, (char *) atts[i]) == 0)
{
i++;
char* scope = (char *)atts[i];
if (strcmp(LOCAL,scope)== 0)
{
attrsFactory->setScope(gemfire::ScopeType::LOCAL);
}
else if (strcmp(DISTRIBUTED_ACK,scope)== 0)
{
attrsFactory->setScope(gemfire::ScopeType::DISTRIBUTED_ACK);
isDistributed = false;
}
else if (strcmp(DISTRIBUTED_NO_ACK,scope)== 0)
{
attrsFactory->setScope(gemfire::ScopeType::DISTRIBUTED_NO_ACK);
isDistributed = false;
}
else
{
char* name = (char* )atts[i];
std::string temp(name);
std::string s = "XML: " + temp + " is not a valid value for the attribute <scope>";
throw CacheXmlException(s.c_str());
}
}
else if(strcmp(CLIENT_NOTIFICATION_ENABLED, (char *) atts[i])== 0)
{
i++;
char * client_notification_enabled = (char *)atts[i];
if ( strcmp("false",client_notification_enabled)== 0
|| strcmp("FALSE",client_notification_enabled)== 0)
{
attrsFactory->setClientNotificationEnabled(false);
}
else if ( strcmp("true",client_notification_enabled)== 0
|| strcmp("TRUE",client_notification_enabled)== 0)
{
attrsFactory->setClientNotificationEnabled(true);
}
else
{
char* name = (char* )atts[i];
std::string temp(name);
std::string s = "XML: " + temp + " is not a valid value for the attribute <client-notification>\n";
throw CacheXmlException(s.c_str());
}
}
else if(strcmp(INITIAL_CAPACITY, (char *) atts[i])== 0)
{
i++;
char * initialCapacity = (char *)atts[i];
attrsFactory->setInitialCapacity(atoi(initialCapacity));
}
else if(strcmp(CONCURRENCY_LEVEL, (char *) atts[i])== 0)
{
i++;
char* concurrencyLevel = (char *)atts[i];
attrsFactory->setConcurrencyLevel(atoi(concurrencyLevel));
}
else if(strcmp(LOAD_FACTOR, (char *) atts[i]) == 0)
{
i++;
char* loadFactor = (char *)atts[i];
attrsFactory->setLoadFactor((float) atof(loadFactor)); //check whether this works
}
else if(strcmp(CACHING_ENABLED,(char*)atts[i]) ==0)
{
bool flag= false;
i++;
char* cachingEnabled = (char*)atts[i];
if( strcmp("true",cachingEnabled)== 0
|| strcmp("TRUE",cachingEnabled)== 0)
{
flag = true;
}
else if (strcmp("false",cachingEnabled)== 0
|| strcmp("FALSE",cachingEnabled)== 0)
{
flag = false;
}
else
{
char* name = (char* )atts[i];
std::string temp(name);
std::string s = "XML: "+ temp +
" is not a valid value for the attribute <caching-enabled>";
throw CacheXmlException(s.c_str());
}
attrsFactory->setCachingEnabled(flag); //check whether this works
}
else if(strcmp(LRU_ENTRIES_LIMIT, (char*)atts[i])== 0)
{
i++;
char* lruentriesLimit = (char *)atts[i];
int lruentriesLimitInt = atoi(lruentriesLimit);
uint32_t temp = (uint32_t)lruentriesLimitInt;
attrsFactory->setLruEntriesLimit(temp);
}
else if(strcmp(DISK_POLICY, (char *) atts[i])== 0)
{
i++;
char* diskPolicy = (char *)atts[i];
if (strcmp(OVERFLOWS,diskPolicy)== 0)
{
attrsFactory->setDiskPolicy(gemfire::DiskPolicyType::OVERFLOWS);
}
else if (strcmp(PERSIST,diskPolicy)== 0)
{
throw IllegalStateException(" persistence feature is not supported");
}
else if (strcmp(NONE,diskPolicy)== 0)
{
attrsFactory->setDiskPolicy(gemfire::DiskPolicyType::NONE);
}
else
{
char* name = (char* )atts[i];
std::string temp(name);
std::string s = "XML: " + temp + " is not a valid value for the attribute <disk-policy>";
throw CacheXmlException(s.c_str());
}
}
else if(strcmp(ENDPOINTS, (char*)atts[i])== 0)
{
i++;
char *endpoints = (char *)atts[i];
attrsFactory->setEndpoints(endpoints);
isTCR = true;
}
else if(strcmp(POOL_NAME, (char*)atts[i])== 0)
{
i++;
char *poolName = (char *)atts[i];
attrsFactory->setPoolName(poolName);
isTCR = true;
}
else if(strcmp(CLONING_ENABLED , (char*)atts[i])== 0)
{
i++;
bool flag = false;
char *isClonable = (char *)atts[i];
if( strcmp("true",isClonable)== 0
|| strcmp("TRUE",isClonable)== 0)
{
flag = true;
}
else if (strcmp("false",isClonable)== 0
|| strcmp("FALSE",isClonable)== 0)
{
flag = false;
}
else
{
char* name = (char* )atts[i];
std::string temp(name);
std::string s = "XML: "+ temp +
" is not a valid value for the attribute <cloning-enabled>";
throw CacheXmlException(s.c_str());
}
attrsFactory->setCloningEnabled( flag );
isTCR = true;
}
else if(strcmp(CONCURRENCY_CHECKS_ENABLED,(char*)atts[i]) ==0)
{
bool flag= false;
i++;
char* concurrencyChecksEnabled = (char*)atts[i];
if( strcmp("true",concurrencyChecksEnabled)== 0
|| strcmp("TRUE",concurrencyChecksEnabled)== 0)
{
flag = true;
}
else if (strcmp("false",concurrencyChecksEnabled)== 0
|| strcmp("FALSE",concurrencyChecksEnabled)== 0)
{
flag = false;
}
else
{
char* name = (char* )atts[i];
std::string temp(name);
std::string s = "XML: "+ temp +
" is not a valid value for the attribute <concurrency-checks-enabled>";
throw CacheXmlException(s.c_str());
}
attrsFactory->setConcurrencyChecksEnabled(flag);
}
}//for loop
}//atts is NULL
else
{
RegionXmlCreation* region = reinterpret_cast<RegionXmlCreation *> (_stack.top());
attrsFactory = new AttributesFactory(region->getAttributes());
_stack.push(attrsFactory);
}
if (isDistributed && isTCR)
{
/* we don't allow DR+TCR at current stage according to sudhir */
std::string s = "XML:endpoints cannot be defined for distributed region.\n";
throw CacheXmlException(s.c_str());
}
}
void CacheXmlParser::endRegionAttributes()
{
AttributesFactory* attrsFactory =
reinterpret_cast<AttributesFactory *> (_stack.top());
_stack.pop();
if (!attrsFactory)
throw UnknownException(
"CacheXmlParser::endRegion:AttributesFactory is null");
RegionAttributesPtr regionAttributesPtr =
attrsFactory->createRegionAttributes();
RegionXmlCreation* regionPtr =
reinterpret_cast<RegionXmlCreation*> (_stack.top());
if (!regionPtr)
throw UnknownException("CacheXmlParser::endRegion:Region is null");
std::string id = regionPtr->getAttrId();
if (id != "") {
namedRegions[id] = regionAttributesPtr;
}
regionPtr->setAttributes(regionAttributesPtr);
}
/**
* When a <code>expiration-attributes</code> element is first
* encountered, we create an {@link ExpirationAttibutes} object from
* the element's attributes and push it on the _stack.
*/
void CacheXmlParser::startExpirationAttributes(const xmlChar** atts)
{
if(!atts)
{
std::string s = "XML:No attributes provided for <expiration-attributes> ";
throw CacheXmlException(s.c_str());
}
m_flagExpirationAttribute = true;
int attrsCount = 0;
while(atts[attrsCount] != NULL)
++attrsCount;
if(attrsCount > 4)
{
std::string s =
"XML:Incorrect number of attributes provided for <expirartion-attributes>";
throw CacheXmlException(s.c_str());
}
char* timeOut = NULL;
int timeOutInt =0;
ExpirationAction::Action expire = ExpirationAction::INVALID_ACTION;
for (int i = 0;(atts[i] != NULL);i++)
{
if(strcmp(TIMEOUT, (char *) atts[i])== 0)
{
i++;
timeOut = (char *)atts[i];
if (strcmp(timeOut, "") ==0)
{
std::string s = "XML:Value for attribute <timeout> needs to be specified";
throw CacheXmlException(s.c_str());
}
timeOutInt = atoi(timeOut);
}
else if(strcmp(ACTION, (char *) atts[i])== 0)
{
i++;
char* action = (char* )atts[i];
if (strcmp(action, "") == 0)
{
std::string s = "XML:The attribute <action> of <expiration-attributes> cannot be set to empty string. It should either have a value or the attribute should be removed. In the latter case the default value will be set";
throw CacheXmlException(s.c_str());
}
else if (strcmp(INVALIDATE,action)== 0)
{
expire = ExpirationAction::INVALIDATE;
}
else if (strcmp(DESTROY,action)== 0)
{
expire = ExpirationAction::DESTROY;
}
else if (strcmp(LOCAL_INVALIDATE,action)== 0)
{
expire = ExpirationAction::LOCAL_INVALIDATE;
}
else if (strcmp(LOCAL_DESTROY,action)== 0)
{
expire = ExpirationAction::LOCAL_DESTROY;
}
else
{
char* name = (char* )atts[i];
std::string temp(name);
std::string s = "XML: " + temp +
" is not a valid value for the attribute <action>";
throw CacheXmlException(s.c_str());
}
}
else
{
char* name = (char* )atts[i];
std::string temp(name);
std::string s = "XML:Incorrect attribute name specified in <expiration-attributes>: " + temp;
throw CacheXmlException(s.c_str());
}
}
if(timeOut == NULL || strcmp( timeOut, "") == 0)
{
std::string s="XML:The attribute <timeout> not specified in <expiration-attributes>.";
throw CacheXmlException(s.c_str());
}
ExpirationAttributes* expireAttr=new ExpirationAttributes(timeOutInt,expire);
if(!expireAttr)
throw UnknownException(
"CacheXmlParser::startExpirationAttributes:Out of memeory");
expireAttr->setAction(expire);
_stack.push(expireAttr);
}
void CacheXmlParser::startPersistenceManager(const xmlChar **atts)
{
int attrsCount = 0;
if(!atts)
{
std::string s = "XML:No attributes provided for <persistence-manager>";
throw CacheXmlException(s.c_str());
}
while(atts[attrsCount] != NULL)
++attrsCount;
if(attrsCount > 4)
{
std::string s = "XML:Incorrect number of attributes provided for <persistence-manager>";
throw CacheXmlException(s.c_str());
}
char * libraryName = NULL;
char * libraryFunctionName = NULL;
for (int i = 0;(atts[i] != NULL);i++)
{
if(strcmp(LIBRARY_NAME, (char *) atts[i])== 0)
{
i++;
int len = strlen((char*)atts[i])+1;
libraryName = new char[len];
/* adongre
* CID 28824: Dereference before null check (REVERSE_INULL)
*/
if ( libraryName == NULL ) {
std::string s = "Memory allocation fails";
throw CacheXmlException(s.c_str());
}
ACE_OS::strncpy(libraryName, (char *)atts[i], len);
if (libraryName == NULL)
{
std::string s = "XML:The attribute <library-name> of <persistence-manager> cannot be set to an empty string. It should either have a value or the attribute should be removed. In the latter case the default value will be set";
throw CacheXmlException(s.c_str());
}
}
else if (strcmp(LIBRARY_FUNCTION_NAME, (char *) atts[i])== 0)
{
i++;
int len = strlen((char*)atts[i]) + 1;
libraryFunctionName = new char[len];
/* adongre
* CID 28823: Dereference before null check (REVERSE_INULL)
*/
if ( libraryFunctionName == NULL ) {
std::string s = "Memory allocation fails";
throw CacheXmlException(s.c_str());
}
ACE_OS::strncpy(libraryFunctionName, (char *)atts[i], len);
if(libraryFunctionName == NULL)
{
std::string s="XML:Value for the <library-function-name> needs to be provided";;
throw CacheXmlException(s.c_str());
}
}
else
{
char* name = (char* )atts[i];
std::string temp(name);
std::string s="XML:Incorrect attribute name specified in <persistence-manager>: " + temp;
throw CacheXmlException(s.c_str());
}
}
if(libraryFunctionName == NULL)
{
std::string s =
"XML:Library function name not specified in the <persistence-manager>";
throw CacheXmlException(s.c_str());
}
try {
if ( managedPersistenceManagerFn != NULL
&& strchr( libraryFunctionName, '.' ) != NULL ) {
// this is a managed library
( *managedPersistenceManagerFn )( libraryName, libraryFunctionName );
} else {
getFactoryFunc( libraryName, libraryFunctionName );
}
} catch ( IllegalArgumentException& ex ) {
throw CacheXmlException( ex.getMessage() );
}
_stack.push(libraryName);
_stack.push(libraryFunctionName);
}
void CacheXmlParser::startPersistenceProperties(const xmlChar** atts)
{
if(!atts)
{
std::string s = "XML:No attributes provided for <property> ";
throw CacheXmlException(s.c_str());
}
int attrsCount = 0;
while(atts[attrsCount] != NULL)
++attrsCount;
if(attrsCount > 4)
{
std::string s =
"XML:Incorrect number of attributes provided for <property>";
throw CacheXmlException(s.c_str());
}
else
{
if (m_config == NULLPTR) {
m_config = Properties::create();
}
}
char* propName = NULL;
char* propValue = NULL;
for (int i = 0;(atts[i] != NULL);i++)
{
if(strcmp("name",(char *)atts[i]) == 0)
{
i++;
propName = (char *)atts[i];
if (propName == NULL || strcmp(propName, "") ==0)
{
std::string s = "XML:Value for attribute <name> needs to be specified in the <property>";
throw CacheXmlException(s.c_str());
}
}
else if(strcmp("value",(char *) atts[i])== 0)
{
i++;
propValue = (char *)atts[i];
if (propValue == NULL || strcmp(propValue,"")== 0)
{
std::string s = "XML:Value for attribute <value> needs to be "
"specified in the <property>";
throw CacheXmlException(s.c_str());
}
}
else
{
char* name = (char* )atts[i];
std::string temp(name);
std::string s = "XML:Incorrect attribute name specified in <property>: " + temp;
throw CacheXmlException(s.c_str());
}
}
if(propName == NULL || strcmp(propName, "") ==0)
{
std::string s =
"XML:attribute <name> needs to be specified in the <property>";
throw CacheXmlException(s.c_str());
}
if(propValue == NULL || strcmp(propValue, "") ==0)
{
std::string s =
"XML:attribute <value> needs to be specified in the <property>";
throw CacheXmlException(s.c_str());
}
m_config->insert(propName,propValue);
}
void CacheXmlParser::startCacheLoader(const xmlChar** atts)
{
char* libraryName = NULL;
char* libraryFunctionName = NULL;
int attrsCount = 0;
if(!atts)
{
std::string s = "XML:No attributes provided for <cache-loader>";
throw CacheXmlException(s.c_str());
}
while(atts[attrsCount] != NULL)
++attrsCount;
if(attrsCount > 4)
{
std::string s = "XML:Incorrect number of attributes provided for <cache-loader>";
throw CacheXmlException(s.c_str());
}
for (int i = 0;(atts[i] != NULL);i++)
{
if(strcmp(LIBRARY_NAME, (char *) atts[i])== 0)
{
i++;
libraryName = (char *)atts[i];
if (libraryName == NULL || strcmp(libraryName, "") == 0)
{
std::string s = "XML:The attribute <library-name> of <cache-loader> cannot be set to an empty string. It should either have a value or the attribute should be removed. In the latter case the default value will be set";
throw CacheXmlException(s.c_str());
}
}
else if (strcmp(LIBRARY_FUNCTION_NAME, (char *) atts[i])== 0)
{
i++;
libraryFunctionName = (char *)atts[i];
if(libraryFunctionName == NULL || strcmp(libraryFunctionName,"") == 0)
{
std::string s=
"XML:Value for the <library-function-name> needs to be provided";
throw CacheXmlException(s.c_str());
}
}
else
{
char* name = (char* )atts[i];
std::string temp(name);
std::string s="XML:Incorrect attribute name specified in <cache-loader> : " + temp;
throw CacheXmlException(s.c_str());
}
}
if(libraryFunctionName == NULL || strcmp(libraryFunctionName, "") ==0)
{
std::string s =
"XML:<library-function-name> not specified in <cache-loader> ";
throw CacheXmlException(s.c_str());
}
try {
if ( managedCacheLoaderFn != NULL
&& strchr( libraryFunctionName, '.' ) != NULL ) {
// this is a managed library
( *managedCacheLoaderFn )( libraryName, libraryFunctionName );
} else {
getFactoryFunc( libraryName, libraryFunctionName );
}
} catch ( IllegalArgumentException& ex ) {
throw CacheXmlException( ex.getMessage() );
}
AttributesFactory* attrsFactory =
reinterpret_cast<AttributesFactory*>( _stack.top());
attrsFactory->setCacheLoader(libraryName, libraryFunctionName);
}
void CacheXmlParser::startCacheListener(const xmlChar** atts)
{
char* libraryName = NULL;
char* libraryFunctionName = NULL;
int attrsCount = 0;
if(!atts)
{
std::string s = "XML:No attributes provided for <cache-listener> ";
throw CacheXmlException(s.c_str());
}
while(atts[attrsCount] != NULL)
++attrsCount;
if(attrsCount > 4)
{
std::string s = "XML:Incorrect number of attributes provided for <cache-listener>";
throw CacheXmlException(s.c_str());
}
for (int i = 0;(atts[i] != NULL);i++)
{
if(strcmp(LIBRARY_NAME, (char *) atts[i])== 0)
{
i++;
libraryName = (char *)atts[i];
if (libraryName == NULL || strcmp(libraryName, "") == 0)
{
std::string s = "XML:The attribute <library-name> of the <cache-listener> tag cannot be set to an empty string. It should either have a value or the attribute should be removed. In the latter case the default value will be set";
throw CacheXmlException(s.c_str());
}
}
else if (strcmp(LIBRARY_FUNCTION_NAME, (char *) atts[i])== 0)
{
i++;
libraryFunctionName = (char *)atts[i];
if(libraryFunctionName == NULL || strcmp(libraryFunctionName,"") == 0)
{
std::string s="XML:Value for <library-function-name> needs to be provided";
throw CacheXmlException(s.c_str());
}
}
else
{
char* name = (char* )atts[i];
std::string temp(name);
std::string s =
"XML:Incorrect attribute name specified in <cache-listener> : "
+ temp;
throw CacheXmlException(s.c_str());
}
}
if(libraryFunctionName == NULL || strcmp(libraryFunctionName, "") ==0)
{
std::string s =
"XML:Library function name not specified in <cache-listener> ";
throw CacheXmlException(s.c_str());
}
try {
if ( managedCacheListenerFn != NULL
&& strchr( libraryFunctionName, '.' ) != NULL ) {
// this is a managed library
( *managedCacheListenerFn )( libraryName, libraryFunctionName );
} else {
getFactoryFunc( libraryName, libraryFunctionName );
}
} catch ( IllegalArgumentException& ex ) {
throw CacheXmlException( ex.getMessage() );
}
AttributesFactory* attrsFactory =
reinterpret_cast<AttributesFactory*>( _stack.top());
attrsFactory->setCacheListener(libraryName, libraryFunctionName);
}
void CacheXmlParser::startPartitionResolver(const xmlChar** atts)
{
char* libraryName = NULL;
char* libraryFunctionName = NULL;
int attrsCount = 0;
if(!atts)
{
std::string s = "XML:No attributes provided for <partition-resolver> ";
throw CacheXmlException(s.c_str());
}
while(atts[attrsCount] != NULL)
++attrsCount;
if(attrsCount > 4)
{
std::string s = "XML:Incorrect number of attributes provided for <partition-resolver>";
throw CacheXmlException(s.c_str());
}
for (int i = 0;(atts[i] != NULL);i++)
{
if(strcmp(LIBRARY_NAME, (char *) atts[i])== 0)
{
i++;
libraryName = (char *)atts[i];
if (libraryName == NULL || strcmp(libraryName, "") == 0)
{
std::string s = "XML:The attribute <library-name> of the <partition-resolver> tag cannot be set to an empty string. It should either have a value or the attribute should be removed. In the latter case the default value will be set";
throw CacheXmlException(s.c_str());
}
}
else if (strcmp(LIBRARY_FUNCTION_NAME, (char *) atts[i])== 0)
{
i++;
libraryFunctionName = (char *)atts[i];
if(libraryFunctionName == NULL || strcmp(libraryFunctionName,"") == 0)
{
std::string s="XML:Value for <library-function-name> needs to be provided";
throw CacheXmlException(s.c_str());
}
}
else
{
char* name = (char* )atts[i];
std::string temp(name);
std::string s =
"XML:Incorrect attribute name specified in <partition-resolver> : "
+ temp;
throw CacheXmlException(s.c_str());
}
}
if(libraryFunctionName == NULL || strcmp(libraryFunctionName, "") ==0)
{
std::string s =
"XML:Library function name not specified in <partition-resolver> ";
throw CacheXmlException(s.c_str());
}
try {
if ( managedPartitionResolverFn != NULL
&& strchr( libraryFunctionName, '.' ) != NULL ) {
// this is a managed library
( *managedPartitionResolverFn )( libraryName, libraryFunctionName );
} else {
getFactoryFunc( libraryName, libraryFunctionName );
}
} catch ( IllegalArgumentException& ex ) {
throw CacheXmlException( ex.getMessage() );
}
AttributesFactory* attrsFactory =
reinterpret_cast<AttributesFactory*>( _stack.top());
attrsFactory->setPartitionResolver(libraryName, libraryFunctionName);
}
void CacheXmlParser::startCacheWriter(const xmlChar** atts)
{
char* libraryName = NULL;
char* libraryFunctionName = NULL;
int attrsCount = 0;
if(!atts)
{
std::string s = "XML:No attributes provided for <cache-writer>";
throw CacheXmlException(s.c_str());
}
while(atts[attrsCount] != NULL)
++attrsCount;
if(attrsCount > 4)
{
std::string s = "XML:Incorrect number of attributes provided for <cache-writer>";
throw CacheXmlException(s.c_str());
}
for (int i = 0;(atts[i] != NULL);i++)
{
if(strcmp(LIBRARY_NAME, (char *) atts[i])== 0)
{
i++;
libraryName = (char *)atts[i];
if (libraryName == NULL || strcmp(libraryName, "") == 0)
{
std::string s = "XML:The attribute <library-name> of <cache-writer> cannot be set to an empty string. It should either have a value or the attribute should be removed. In the latter case the default value will be set";
throw CacheXmlException(s.c_str());
}
}
else if (strcmp(LIBRARY_FUNCTION_NAME, (char *) atts[i])== 0)
{
i++;
libraryFunctionName = (char *)atts[i];
if(libraryFunctionName == NULL || strcmp(libraryFunctionName,"") == 0)
{
std::string s="XML:Value for the <library-function-name> needs to be provided";
throw CacheXmlException(s.c_str());
}
}
else
{
char* name = (char* )atts[i];
std::string temp(name);
std::string s="XML:Incorrect attribute name specified in <cache-writer>: " + temp;
throw CacheXmlException(s.c_str());
}
}
if(strcmp(libraryFunctionName, "") ==0)
{
std::string s =
"XML:Library function name not specified in the <cache-writer>";
throw CacheXmlException(s.c_str());
}
try {
if ( managedCacheWriterFn != NULL
&& strchr( libraryFunctionName, '.' ) != NULL ) {
// this is a managed library
( *managedCacheWriterFn )( libraryName, libraryFunctionName );
} else {
getFactoryFunc( libraryName, libraryFunctionName );
}
} catch ( IllegalArgumentException& ex ) {
throw CacheXmlException( ex.getMessage() );
}
AttributesFactory* attrsFactory =
reinterpret_cast<AttributesFactory*>( _stack.top());
attrsFactory->setCacheWriter(libraryName, libraryFunctionName);
}
/**
* After popping the current <code>RegionXmlCreation</code> off the
* _stack, if the element on top of the _stack is a
* <code>RegionXmlCreation</code>, then it is the parent region.
*/
void CacheXmlParser::endRegion(bool isRoot)
{
RegionXmlCreation* regionPtr =
reinterpret_cast<RegionXmlCreation*> (_stack.top());
_stack.pop();
if (isRoot)
{
if(!_stack.empty())
{
std::string s = "Xml file has incorrectly nested region tags";
throw CacheXmlException(s.c_str());
}
if (!m_cacheCreation)
throw CacheXmlException
("XML: Element <cache> was not provided in the xml");
m_cacheCreation->addRootRegion(regionPtr);
}
else
{
if(_stack.empty())
{
std::string s = "Xml file has incorrectly nested region tags";
throw CacheXmlException(s.c_str());
}
RegionXmlCreation* parent =
reinterpret_cast<RegionXmlCreation*>(_stack.top());
parent->addSubregion(regionPtr);
}
}
void CacheXmlParser::endSubregion()
{
endRegion(false);
}
void CacheXmlParser::endRootRegion()
{
endRegion(true);
}
/**
* When a <code>cache</code> element is finished
*/
void CacheXmlParser::endCache()
{
}
/**
* When a <code>region-time-to-live</code> element is finished, the
* {@link ExpirationAttributes} are on top of the _stack followed by
* the {@link AttributesFactory} to which the expiration
* attributes are assigned.
*/
void CacheXmlParser::endRegionTimeToLive()
{
if(!m_flagExpirationAttribute)
{
std::string s = "XML: <region-time-to-live> cannot be without a <expiration-attributes>";
throw CacheXmlException(s.c_str());
}
ExpirationAttributes* expireAttr =
reinterpret_cast<ExpirationAttributes*>(_stack.top());
_stack.pop();
AttributesFactory* attrsFactory =
reinterpret_cast<AttributesFactory*>( _stack.top());
attrsFactory->setRegionTimeToLive(expireAttr->getAction(),expireAttr->getTimeout());
m_flagExpirationAttribute = false;
}
/**
* When a <code>region-idle-time</code> element is finished, the
* {@link ExpirationAttributes} are on top of the _stack followed by
* the {@link AttributesFactory} to which the expiration
* attributes are assigned.
*/
void CacheXmlParser::endRegionIdleTime()
{
if(!m_flagExpirationAttribute)
{
std::string s = "XML: <region-idle-time> cannot be without <expiration-attributes>";
throw CacheXmlException(s.c_str());
}
ExpirationAttributes* expireAttr = reinterpret_cast<ExpirationAttributes*>(_stack.top());
_stack.pop();
AttributesFactory* attrsFactory =
reinterpret_cast<AttributesFactory*>( _stack.top());
attrsFactory->setRegionIdleTimeout(expireAttr->getAction(),expireAttr->getTimeout());
m_flagExpirationAttribute = false;
}
/**
* When a <code>entry-time-to-live</code> element is finished, the
* {@link ExpirationAttributes} are on top of the _stack followed by
* the {@link AttributesFactory} to which the expiration
* attributes are assigned.
*/
void CacheXmlParser::endEntryTimeToLive()
{
if(!m_flagExpirationAttribute)
{
std::string s = "XML: <entry-time-to-live> cannot be without "
"<expiration-attributes>";
throw CacheXmlException(s.c_str());
}
ExpirationAttributes* expireAttr = reinterpret_cast<ExpirationAttributes*>(_stack.top());
_stack.pop();
AttributesFactory* attrsFactory =
reinterpret_cast<AttributesFactory*>( _stack.top());
attrsFactory->setEntryTimeToLive(expireAttr->getAction(),expireAttr->getTimeout());
m_flagExpirationAttribute = false;
}
/**
* When a <code>entry-idle-time</code> element is finished, the
* {@link ExpirationAttributes} are on top of the _stack followed by
* the {@link AttributesFactory} to which the expiration
* attributes are assigned.
*/
void CacheXmlParser::endEntryIdleTime()
{
if(!m_flagExpirationAttribute)
{
std::string s = "XML: <entry-idle-time> cannot be without <expiration-attributes>";
throw CacheXmlException(s.c_str());
}
ExpirationAttributes* expireAttr = reinterpret_cast<ExpirationAttributes*>(_stack.top());
_stack.pop();
AttributesFactory* attrsFactory =
reinterpret_cast<AttributesFactory*>( _stack.top());
attrsFactory->setEntryIdleTimeout(expireAttr->getAction(),expireAttr->getTimeout());
m_flagExpirationAttribute = false;
}
/**
* When persistence-manager attributes is finished, it will set the attribute factory.
*/
void CacheXmlParser::endPersistenceManager()
{
char* libraryFunctionName = (char*)(_stack.top());
_stack.pop();
char* libraryName = (char*)(_stack.top());
_stack.pop();
AttributesFactory* attrsFactory = reinterpret_cast<AttributesFactory*>( _stack.top());
if (m_config != NULLPTR) {
attrsFactory->setPersistenceManager(libraryName,libraryFunctionName,m_config);
m_config = NULLPTR;
}
else
{
attrsFactory->setPersistenceManager(libraryName,libraryFunctionName);
}
//Free memory allocated in startPersistenceManager, already checked for NULL
free(libraryName);
free(libraryFunctionName);
}
CacheXmlParser::~CacheXmlParser()
{
GF_SAFE_DELETE(m_cacheCreation);
}
void CacheXmlParser::setError(const std::string& err)
{
m_error = err;
}
const std::string& CacheXmlParser::getError() const
{
return m_error;
}