///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoXMLSpace.cc
// ---------------
// Cego XML space implementation
//     
// Design and Implementation by Bjoern Lemke
//     
// (C)opyright 2000-2025 Bjoern Lemke
//
// IMPLEMENTATION MODULE
//
// Class: CegoXMLSpace
// 
// Description: XML based database control file management
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// base includes
#include <lfcbase/File.h>
#include <lfcbase/Datetime.h>
#include <lfcbase/ThreadLock.h>
#include <lfcbase/Tokenizer.h>
#include <lfcbase/Matcher.h>
#include <lfcbase/Directory.h>
#include <lfcbase/Host.h>
#include <lfcbase/Timer.h>

// xml includes
#include <lfcxml/XMLSuite.h>
#include <lfcxml/Element.h>
#include <lfcxml/Document.h>

// cego includes
#include "CegoXMLdef.h"
#include "CegoXMLSpace.h"

static ThreadLock xmlLock("XML");

extern char __caseSensitiveFlag;
extern bool __lockStatOn;

// xml space keeps fsync variable, but is is also used in filehandler and loghandler
bool __fsyncOn = false;

/////////////////////
// CegoXMLSpace //
/////////////////////

CegoXMLSpace::CegoXMLSpace(const Chain& xmlDef,const Chain& logFile, const Chain& progName) : CegoFileHandler(logFile, progName)
{
    for ( unsigned i = 0 ; i < TABMNG_MAXTABSET ; i++)
	_tsCache[i] = 0;
    
    _xmlDef = xmlDef;
    _pDoc = new Document;

    xmlLock.init(LCKMNG_LOCKWAITDELAY, __lockStatOn);

    _modId = getModId("CegoXMLSpace");
}

CegoXMLSpace::~CegoXMLSpace()
{  
    delete _pDoc;
}

Element* CegoXMLSpace::getDbSpec()
{
    return _pDoc->getRootElement()->createClone();
}

Element* CegoXMLSpace::getTableSetInfo(const Chain& tableSet)
{
    P();

    Element *pTSE = getTableSetElement(tableSet);
    if ( pTSE )
    {

	Element *pTS = pTSE->createClone();
	
	V();
	return pTS;	
    }
    
    V();
    Chain msg = Chain("Unknown tableset name ") + tableSet; 
    throw Exception(EXLOC, msg);
}

void CegoXMLSpace::setTableSetInfo(const Chain& tableSet, Element *pTS)
{    
    P();
    
    ListT<Element*> tsList;    
    tsList = _pDoc->getRootElement()->getChildren(XML_TABLESET_ELEMENT);
    
    Element **pOldTS = tsList.First();
    bool notFound = true;
    while ( pOldTS && notFound ) 
    {
	if ( (*pOldTS)->getAttributeValue(XML_NAME_ATTR) == tableSet )
	{    
	    unsigned tabSetId = (*pOldTS)->getAttributeValue(XML_TSID_ATTR).asUnsigned();
	    _tsCache[tabSetId] = 0;
	    _pDoc->getRootElement()->removeChild( *pOldTS );
	    notFound = false;
	}
	pOldTS = tsList.Next();
    }

    unsigned tabSetId = pTS->getAttributeValue(XML_TSID_ATTR).asUnsigned();
    _tsCache[tabSetId] = pTS;
    _pDoc->getRootElement()->addContent( pTS );
    V();
}

Element* CegoXMLSpace::getTableSetList()
{
    P();

    ListT<Element*> tabSetList = _pDoc->getRootElement()->getChildren(XML_TABLESET_ELEMENT);
    
    Element *pTabSetInfo = new Element(XML_TABLESETLIST_ELEMENT);
    
    Element **pTabSet = tabSetList.First();
    while ( pTabSet )
    {
	Element *pTS = new Element(XML_TABLESET_ELEMENT);
	pTS->setAttribute(XML_NAME_ATTR, (*pTabSet)->getAttributeValue(XML_NAME_ATTR));
	pTS->setAttribute(XML_RUNSTATE_ATTR, (*pTabSet)->getAttributeValue(XML_RUNSTATE_ATTR));
	pTS->setAttribute(XML_ARCHMODE_ATTR, (*pTabSet)->getAttributeValue(XML_ARCHMODE_ATTR));
	
	pTabSetInfo->addContent(pTS);
	pTabSet = tabSetList.Next();
    }

    V();

    return pTabSetInfo;
}

void CegoXMLSpace::getTableSetList(ListT<Chain>& tsList)
{
    P();

    ListT<Element*> tabSetList = _pDoc->getRootElement()->getChildren(XML_TABLESET_ELEMENT);
        
    Element **pTabSet = tabSetList.First();
    while ( pTabSet )
    {
	tsList.Insert ( (*pTabSet)->getAttributeValue(XML_NAME_ATTR));
	pTabSet = tabSetList.Next();
    }

    V();

    return;
}

Element* CegoXMLSpace::getNodeList()
{
    P();

    ListT<Element*> nodeList = _pDoc->getRootElement()->getChildren(XML_NODE_ELEMENT);
    Element *pNodeInfo = new Element(XML_NODEINFO_ELEMENT);
    
    Element **pNode = nodeList.First();
    while ( pNode )
    {
	Element *pN = new Element(XML_NODE_ELEMENT);
	pN->setAttribute(XML_HOSTNAME_ATTR, (*pNode)->getAttributeValue(XML_HOSTNAME_ATTR));
	pN->setAttribute(XML_STATUS_ATTR, (*pNode)->getAttributeValue(XML_STATUS_ATTR));
	pNodeInfo->addContent(pN);
	pNode = nodeList.Next();
    }
    V();

    return pNodeInfo;
}

void CegoXMLSpace::addHost(const Chain& hostName, const Chain& status)
{
    P();
    Element* pHostEntry = new Element(XML_NODE_ELEMENT);
    pHostEntry->setAttribute(XML_HOSTNAME_ATTR, hostName);
    pHostEntry->setAttribute(XML_STATUS_ATTR, status);
    _pDoc->getRootElement()->addContent(pHostEntry);
    V();
}

void CegoXMLSpace::setHostStatus( const Chain& hostName, const Chain& status)
{
    P();

    ListT<Element*> nodeList;    
    nodeList = _pDoc->getRootElement()->getChildren(XML_NODE_ELEMENT);

    Element **pNode = nodeList.First();
    while ( pNode ) 
    {
	if ( (*pNode)->getAttributeValue(XML_HOSTNAME_ATTR) == hostName )
	{
	    (*pNode)->setAttribute(XML_STATUS_ATTR, status);
	    Datetime d;
	    (*pNode)->setAttribute(XML_TIMESTAMP_ATTR, d.asChain());
	    V();
	    return;
	}
	else
	    pNode = nodeList.Next();
    }
    
    V();

    addHost(hostName, status);
}

void CegoXMLSpace::getStatusByHost(const Chain& hostName, Chain& status)
{
    P();
    
    ListT<Element*> nodeList;    
    nodeList = _pDoc->getRootElement()->getChildren(XML_NODE_ELEMENT);

    Element **pNode = nodeList.First();
    while ( pNode ) 
    {
	if ( (*pNode)->getAttributeValue(XML_HOSTNAME_ATTR) == (Chain)hostName )
	{
	    status = (*pNode)->getAttributeValue(XML_STATUS_ATTR);
	    V();
	    return;
	}
	else
	{
	    pNode = nodeList.Next();
	}
    }
    V();
    Chain msg = Chain("Unknown hostname ") + hostName; 
    throw Exception(EXLOC, msg);
}

void CegoXMLSpace::removeHost( const Chain& hostName)
{    
    P();
    ListT<Element*> nodeList;    
    nodeList = _pDoc->getRootElement()->getChildren(XML_NODE_ELEMENT);

    Element **pNode = nodeList.First();
    while ( pNode ) 
    {
	if ( (*pNode)->getAttributeValue(XML_HOSTNAME_ATTR) == hostName )
	{
	    _pDoc->getRootElement()->removeChild(*pNode);
	    V();
	    return;
	}
	else
	    pNode = nodeList.Next();
    }
    V();
    Chain msg = Chain("Unknown hostname ") + hostName; 
    throw Exception(EXLOC, msg);
}

unsigned CegoXMLSpace::getSelectTimeout()
{
    P();
    unsigned selectTimeout = _pDoc->getRootElement()->getAttributeValue(XML_SELECTTIMEOUT_ATTR).asUnsigned();
    V();
 
    if ( selectTimeout == 0 )
	selectTimeout = NETMNG_SELECT_TIMEOUT;

    return selectTimeout;
}

unsigned CegoXMLSpace::getQueueDelay()
{
    P();
    unsigned queueDelay = _pDoc->getRootElement()->getAttributeValue(XML_QUEUEDELAY_ATTR).asUnsigned();
    V();
 
    if ( queueDelay == 0 )
	queueDelay = NETMNG_QUEUE_DELAY;

    return queueDelay;
}

unsigned CegoXMLSpace::getNumRecordSema()
{
    P();
    unsigned numRecSema = _pDoc->getRootElement()->getAttributeValue(XML_NUMRECSEMA_ATTR).asUnsigned();
    V();
 
    if ( numRecSema == 0 )
	numRecSema = LCKMNG_NUM_RECORD_SEMA;

    return numRecSema;
}

unsigned CegoXMLSpace::getNumRBRecordSema()
{
    P();
    unsigned numRBRecSema = _pDoc->getRootElement()->getAttributeValue(XML_NUMRBRECSEMA_ATTR).asUnsigned();
    V();
    
    if ( numRBRecSema == 0 )
	numRBRecSema = LCKMNG_NUM_RBRECORD_SEMA;

    return numRBRecSema;
}

unsigned CegoXMLSpace::getNumSysRecordSema()
{
    P();
    unsigned numSysRecSema = _pDoc->getRootElement()->getAttributeValue(XML_NUMSYSRECSEMA_ATTR).asUnsigned();
    V();
    
    if ( numSysRecSema == 0 )
	numSysRecSema = LCKMNG_NUM_SYSRECORD_SEMA;

    return numSysRecSema;
}

unsigned CegoXMLSpace::getNumSysPageSema()
{
    P();
    unsigned numSysPageSema = _pDoc->getRootElement()->getAttributeValue(XML_NUMSYSPAGESEMA_ATTR).asUnsigned();
    V();
    if ( numSysPageSema == 0 )
	numSysPageSema = LCKMNG_NUM_SYSPAGE_SEMA;
    return numSysPageSema;
}

unsigned CegoXMLSpace::getNumDataPageSema()
{
    P();
    unsigned numDataPageSema = _pDoc->getRootElement()->getAttributeValue(XML_NUMDATAPAGESEMA_ATTR).asUnsigned();
    V();
    if ( numDataPageSema == 0 )
	numDataPageSema = LCKMNG_NUM_DATAPAGE_SEMA;
    return numDataPageSema;
}

unsigned CegoXMLSpace::getNumIndexPageSema()
{
    P();
    unsigned numIdxPageSema = _pDoc->getRootElement()->getAttributeValue(XML_NUMIDXPAGESEMA_ATTR).asUnsigned();
    V();
    if ( numIdxPageSema == 0 )
	numIdxPageSema = LCKMNG_NUM_IDXPAGE_SEMA;
    return numIdxPageSema;
}

unsigned CegoXMLSpace::getNumRBPageSema()
{
    P();
    unsigned numRBPageSema = _pDoc->getRootElement()->getAttributeValue(XML_NUMRBPAGESEMA_ATTR).asUnsigned();
    V();
    if ( numRBPageSema == 0 )
	numRBPageSema = LCKMNG_NUM_RBPAGE_SEMA;
    return numRBPageSema;
}

unsigned CegoXMLSpace::getNumDataFileSema()
{
    P();
    unsigned numDataFileSema = _pDoc->getRootElement()->getAttributeValue(XML_NUMDATAFILESEMA_ATTR).asUnsigned();
    V();
    if ( numDataFileSema == 0 )
	numDataFileSema = LCKMNG_NUM_DATAFILE_SEMA;
    return numDataFileSema;
}

unsigned CegoXMLSpace::getNumBufferPoolSema()
{
    P();
    unsigned numBufferPoolSema = _pDoc->getRootElement()->getAttributeValue(XML_NUMBUFFERPOOLSEMA_ATTR).asUnsigned();
    V();
    if ( numBufferPoolSema == 0 )
	numBufferPoolSema = LCKMNG_NUM_BUFFERPOOL_SEMA;
    return numBufferPoolSema;    
}

unsigned CegoXMLSpace::getMaxFixTries()
{
    P();
    unsigned maxFixTries = _pDoc->getRootElement()->getAttributeValue(XML_MAXFIXTRIES_ATTR).asUnsigned();
    V();
    if ( maxFixTries == 0 )
	maxFixTries = BUPMNG_MAXFIXTRIES;
    return maxFixTries;    
}

unsigned CegoXMLSpace::getMaxPageDelete()
{
    P();
    unsigned maxPageDelete = _pDoc->getRootElement()->getAttributeValue(XML_MAXPAGEDELETE_ATTR).asUnsigned();
    V();
    if ( maxPageDelete == 0 )
	maxPageDelete = BUPMNG_MAXPAGEDELETE;
    return maxPageDelete;
}

unsigned CegoXMLSpace::getPageLockTimeout()
{
    P();
    unsigned lockTimeout = _pDoc->getRootElement()->getAttributeValue(XML_PAGELOCKTIMEOUT_ATTR).asUnsigned();
    V();
    if ( lockTimeout == 0 )
	lockTimeout = PG_LOCKTIMEOUT;
    return lockTimeout;
}

unsigned CegoXMLSpace::getRecLockTimeout()
{
    P();
    unsigned lockTimeout = _pDoc->getRootElement()->getAttributeValue(XML_RECLOCKTIMEOUT_ATTR).asUnsigned();
    V();
    if ( lockTimeout == 0 )
	lockTimeout = RC_LOCKTIMEOUT;
    return lockTimeout;
}

unsigned CegoXMLSpace::getFileLockTimeout()
{
    P();
    unsigned lockTimeout = _pDoc->getRootElement()->getAttributeValue(XML_FILELOCKTIMEOUT_ATTR).asUnsigned();
    V();
    if ( lockTimeout == 0 )
	lockTimeout = FH_LOCKTIMEOUT;
    return lockTimeout;
}

unsigned CegoXMLSpace::getPoolLockTimeout()
{
    P();
    unsigned lockTimeout = _pDoc->getRootElement()->getAttributeValue(XML_POOLLOCKTIMEOUT_ATTR).asUnsigned();
    V();
    if ( lockTimeout == 0 )
	lockTimeout = BP_LOCKTIMEOUT;
    return lockTimeout;
}

unsigned CegoXMLSpace::getNumLockTries()
{
    P();
    unsigned numLockTries = _pDoc->getRootElement()->getAttributeValue(XML_NUMLOCKTRIES_ATTR).asUnsigned();
    V();
    if ( numLockTries == 0 )
	numLockTries = LCKMNG_NUMLOCKTRIES;
    return numLockTries;
}

void CegoXMLSpace::setNumQueryLast(unsigned numLast)
{
    P();
    _pDoc->getRootElement()->setAttribute(XML_NUMQUERYLAST_ATTR, Chain(numLast));
    V();
}

unsigned CegoXMLSpace::getNumQueryLast()
{
    P();
    unsigned numQueryLast = _pDoc->getRootElement()->getAttributeValue(XML_NUMQUERYLAST_ATTR).asUnsigned();
    V();
    return numQueryLast;
}

void CegoXMLSpace::setNumQueryCost(unsigned numCost)
{
    P();
    _pDoc->getRootElement()->setAttribute(XML_NUMQUERYCOST_ATTR, Chain(numCost));
    V();
}

unsigned CegoXMLSpace::getNumQueryCost()
{
    P();
    unsigned numQueryCost = _pDoc->getRootElement()->getAttributeValue(XML_NUMQUERYCOST_ATTR).asUnsigned();
    V();
    return numQueryCost;
}

unsigned CegoXMLSpace::getMaxSendLen()
{
    P();
    unsigned maxSendLen = _pDoc->getRootElement()->getAttributeValue(XML_MAXSENDLEN_ATTR).asUnsigned();
    V();
    if ( maxSendLen == 0 )
	maxSendLen = NETMNG_MAXSENDLEN;
    return maxSendLen;
}

void CegoXMLSpace::adjustPageOffset()
{
    PageIdType pageOffset = getMaxPageOffset();
	
    P();
    PageIdType currentOffset = _pDoc->getRootElement()->getAttributeValue(XML_PAGEOFFSET_ATTR).asUnsignedLongLong();
    if ( currentOffset < pageOffset )
	_pDoc->getRootElement()->setAttribute(XML_PAGEOFFSET_ATTR, Chain(pageOffset));
    V();
}

PageIdType CegoXMLSpace::getNextPageOffset(unsigned numPages)
{
    P();
    PageIdType currentOffset = _pDoc->getRootElement()->getAttributeValue(XML_PAGEOFFSET_ATTR).asUnsignedLongLong();

    if ( currentOffset == 0 )
	currentOffset = 1;
    
    PageIdType newOffset = currentOffset + (PageIdType)numPages;
    _pDoc->getRootElement()->setAttribute(XML_PAGEOFFSET_ATTR, Chain(newOffset));
    V();
    return currentOffset;    
}

void CegoXMLSpace::setSysPageOffset(const unsigned tabSetId, const PageIdType pageOffset)
{
    Element *pTSE = getCachedTableSetElement(tabSetId);

    P();

    if ( pTSE )
    {
	pTSE->setAttribute(XML_SYSPAGEOFFSET_ATTR, Chain(pageOffset));  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset id ") + Chain(tabSetId); 
	throw Exception(EXLOC, msg);
    }
    V();
}

PageIdType CegoXMLSpace::getSysPageOffset(const unsigned tabSetId)
{
    PageIdType pageOffset = 0;
    
    Element *pTSE = getCachedTableSetElement(tabSetId);

    P();

    if ( pTSE )
    {
	pageOffset = pTSE->getAttributeValue(XML_SYSPAGEOFFSET_ATTR).asUnsignedLongLong();  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset id ") + Chain(tabSetId); 
	throw Exception(EXLOC, msg);
    }
    V();

    return pageOffset;
}

void CegoXMLSpace::setTempPageOffset(const unsigned tabSetId, const PageIdType pageOffset)
{
    Element *pTSE = getCachedTableSetElement(tabSetId);

    P();

    if ( pTSE )
    {
	pTSE->setAttribute(XML_TEMPPAGEOFFSET_ATTR, Chain(pageOffset));  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset id ") + Chain(tabSetId); 
	throw Exception(EXLOC, msg);
    }
    V();
}

PageIdType CegoXMLSpace::getTempPageOffset(const unsigned tabSetId)
{
    PageIdType pageOffset = 0;
    
    Element *pTSE = getCachedTableSetElement(tabSetId);

    P();

    if ( pTSE )
    {
	pageOffset = pTSE->getAttributeValue(XML_TEMPPAGEOFFSET_ATTR).asUnsignedLongLong();  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset id ") + Chain(tabSetId); 
	throw Exception(EXLOC, msg);
    }
    V();

    return pageOffset;
}

char CegoXMLSpace::getCaseSensitiveFlag()
{
    P();
    Chain mode = _pDoc->getRootElement()->getAttributeValue(XML_CSMODE_ATTR);
    V();
    if ( mode == Chain(XML_NONE_VALUE) )
	return 2;
    if ( mode == Chain(XML_STR_VALUE) )
	return 1;
    return 0;
}

bool CegoXMLSpace::allowDuplicateNull()
{
    P();
    Chain mode = _pDoc->getRootElement()->getAttributeValue(XML_DUPLICATENULL_ATTR);
    V();
    if ( mode == Chain(XML_ON_VALUE) )
	return true;
    return false;    
}

void CegoXMLSpace::setQuoteEscapeMode(bool m)
{
    P();
    if ( m )
	_pDoc->getRootElement()->setAttribute(XML_QESCMODE_ATTR, XML_ON_VALUE);
    else 
	_pDoc->getRootElement()->setAttribute(XML_QESCMODE_ATTR, XML_OFF_VALUE);
    V();
}

bool CegoXMLSpace::isQuoteEscapeMode()
{
    P();
    Chain mode = _pDoc->getRootElement()->getAttributeValue(XML_QESCMODE_ATTR);
    V();
    if ( mode == Chain(XML_ON_VALUE) )
	return true;
    return false;    
}

Chain CegoXMLSpace::getDateTimeFormat()
{
    Chain dateTimeFormat;
    
    P();
    dateTimeFormat = _pDoc->getRootElement()->getAttributeValue(XML_DATETIMEFORMAT_ATTR);
    V();
    
    return dateTimeFormat;
}

BigDecimal::RoundMode CegoXMLSpace::getRoundMode()
{
    Chain roundMode;
    P();
    roundMode = _pDoc->getRootElement()->getAttributeValue(XML_ROUNDMODE_ATTR);
    V();

    if ( roundMode == Chain(XML_ROUND_UP) )
	return BigDecimal::UP;
    if ( roundMode == Chain(XML_ROUND_DOWN) )
	return BigDecimal::DOWN;
    if ( roundMode == Chain(XML_ROUND_HALFUP) )
	return BigDecimal::HALFUP;
    if ( roundMode == Chain(XML_ROUND_HALFDOWN) )
	return BigDecimal::HALFDOWN;
    
    // default value
    return BigDecimal::DOWN;
}

ListT<Chain> CegoXMLSpace::getDateFormatList()
{
    ListT<Chain> formatList;
    
    P();

    Element *pRoot = _pDoc->getRootElement();    
    if ( pRoot )
    {	
	ListT<Element*> formatElementList = pRoot->getChildren(XML_DATETIMEFORMAT_ELEMENT);
	
	Element **pFormat = formatElementList.First();
	while ( pFormat )
	{
	    formatList.Insert((*pFormat)->getAttributeValue(XML_VALUE_ATTR));
	    pFormat = formatElementList.Next();
	}	
    }
    V();

    return formatList;
}    

void CegoXMLSpace::setArchRestoreProg(const Chain& progName)
{
    P();
    _pDoc->getRootElement()->setAttribute(XML_LOGMNGPROG_ATTR, progName);
    V();
}

Chain CegoXMLSpace::getArchRestoreProg()
{
    P();
    Chain archRestoreProg = _pDoc->getRootElement()->getAttributeValue(XML_LOGMNGPROG_ATTR);
    V();
    return archRestoreProg;
}

void CegoXMLSpace::setArchRestoreTimeout(unsigned timeout)
{
    P();
    _pDoc->getRootElement()->setAttribute(XML_LOGMNGTIMEOUT_ATTR, Chain(timeout));
    V();
}

unsigned CegoXMLSpace::getArchRestoreTimeout()
{
    P();
    unsigned timeout = _pDoc->getRootElement()->getAttributeValue(XML_LOGMNGTIMEOUT_ATTR).asUnsigned();
    V();
    return timeout;
}

void CegoXMLSpace::setBackupProg(const Chain& progName)
{
    P();
    _pDoc->getRootElement()->setAttribute(XML_BACKUPMNGPROG_ATTR, progName);
    V();
}

Chain CegoXMLSpace::getBackupProg()
{
    P();
    Chain backupProg = _pDoc->getRootElement()->getAttributeValue(XML_BACKUPMNGPROG_ATTR);
    V();
    return backupProg;
}


unsigned CegoXMLSpace::getTabSetId(const Chain& tabSetName) const
{
    unsigned tabSetId;

    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {
	tabSetId = pTSE->getAttributeValue(XML_TSID_ATTR).asUnsigned();  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
    return tabSetId;
}

Chain CegoXMLSpace::getTabSetName(unsigned tabSetId)
{
    Chain tabSetName;
    
    Element *pTSE = getCachedTableSetElement(tabSetId);
    if ( pTSE == 0 )
    {
	Chain msg = Chain("Unknown tableset id ") + Chain(tabSetId); 
	throw Exception(EXLOC, msg);
    }
    P();
    tabSetName = pTSE->getAttributeValue(XML_NAME_ATTR);    
    V();
    return tabSetName;
}

unsigned CegoXMLSpace::getTmpFid(const Chain& tabSetName)
{
    unsigned tmpFid;

    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {
	tmpFid = pTSE->getAttributeValue(XML_TMPFID_ATTR).asUnsigned();  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
    return tmpFid;
}

void CegoXMLSpace::setTSSysSize(const Chain& tableSet, unsigned sysSize)
{
    P();
    Element *pTS = getTableSetElement(tableSet);

    if ( pTS )
    {
	pTS->setAttribute(XML_SYSSIZE_ATTR, Chain(sysSize));
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
}

unsigned CegoXMLSpace::getSysSize(const Chain& tabSetName)
{
    unsigned sysSize;

    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {
	sysSize = pTSE->getAttributeValue(XML_SYSSIZE_ATTR).asUnsigned();  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
    return sysSize;
}

void CegoXMLSpace::setTSTmpSize(const Chain& tableSet, unsigned tmpSize)
{
    P();
    Element *pTS = getTableSetElement(tableSet);

    if ( pTS )
    {
	pTS->setAttribute(XML_TMPSIZE_ATTR, Chain(tmpSize));
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
}

unsigned CegoXMLSpace::getTmpSize(const Chain& tabSetName)
{
    unsigned tmpSize;

    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {
	tmpSize =  pTSE->getAttributeValue(XML_TMPSIZE_ATTR).asUnsigned();  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
    return tmpSize;
}

void CegoXMLSpace::setTSLogNum(const Chain& tableSet, unsigned logNum)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
	Element **pTSE = tabSetList.First();
	while ( pTSE ) 
	{
	    if ( (*pTSE)->getAttributeValue(XML_NAME_ATTR) == tableSet )
	    {
		Chain tsRoot = (*pTSE)->getAttributeValue(XML_TSROOT_ATTR); 
		unsigned logSize=0;
		ListT<Element*> logFileList = (*pTSE)->getChildren(XML_LOGFILE_ELEMENT);
		Element **pLF = logFileList.First();
		while ( pLF )
		{
		    logSize = (*pLF)->getAttributeValue(XML_SIZE_ATTR).asUnsigned();
		    (*pTSE)->removeChild(*pLF);
		    pLF = logFileList.Next();
		}

		for ( unsigned i = 0 ; i < logNum ; i++ )
		{
		    Element *pLE = new Element(XML_LOGFILE_ELEMENT);
		    
		    Chain logName = tsRoot + Chain("/") + tableSet + Chain("redo") +  + Chain(i) + Chain(TABMNG_LOGSUFFIX);
		    pLE->setAttribute(XML_NAME_ATTR, logName);
		    pLE->setAttribute(XML_SIZE_ATTR, Chain(logSize));
		    pLE->setAttribute(XML_STATUS_ATTR, XML_FREE_VALUE);
		    
		    (*pTSE)->addContent(pLE);
		}

		V();
		return;
	    }
	    pTSE = tabSetList.Next();
	}
	
	V();
	Chain msg = Chain("Unknown tableset ") + tableSet; 
	throw Exception(EXLOC, msg);
    }
    V();
    throw Exception(EXLOC, "Root element not found");
}

void CegoXMLSpace::setTSLogSize(const Chain& tableSet, unsigned logSize)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
	Element **pTSE = tabSetList.First();
	while ( pTSE ) 
	{
	    if ( (*pTSE)->getAttributeValue(XML_NAME_ATTR) == tableSet )
	    {
		ListT<Element*> logFileList = (*pTSE)->getChildren(XML_LOGFILE_ELEMENT);
		Element **pLF = logFileList.First();
		while ( pLF )
		{
		    (*pLF)->setAttribute(XML_SIZE_ATTR, Chain(logSize));
		    pLF = logFileList.Next();
		}
		V();
		return;
	    }
	    pTSE = tabSetList.Next();
	}
	
	V();
	Chain msg = Chain("Unknown tableset ") + tableSet; 
	throw Exception(EXLOC, msg);
    }
    V();
    throw Exception(EXLOC, "Root element not found");    
}

void CegoXMLSpace::resetTSRoot(const Chain& tableSet, const Chain& tsRoot)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
	Element **pTSE = tabSetList.First();
	while ( pTSE ) 
	{
	    if ( (*pTSE)->getAttributeValue(XML_NAME_ATTR) == tableSet )
	    {
		ListT<Element*> logFileList = (*pTSE)->getChildren(XML_LOGFILE_ELEMENT);
		Element **pLF = logFileList.First();
		unsigned i=0;
		while ( pLF )
		{
		    Chain logName = tsRoot + Chain("/") + tableSet + Chain("redo") +  + Chain(i) + Chain(TABMNG_LOGSUFFIX);
		    (*pLF)->setAttribute(XML_NAME_ATTR, logName);
		    pLF = logFileList.Next();
		    i++;
		}

		(*pTSE)->setAttribute(XML_TSTICKET_ATTR, tsRoot + Chain("/") + tableSet + Chain("_ticket.xml"));
		
		(*pTSE)->setAttribute(XML_SYSNAME_ATTR, tsRoot + Chain("/") + tableSet + Chain(TABMNG_SYSSUFFIX));
		(*pTSE)->setAttribute(XML_TMPNAME_ATTR, tsRoot + Chain("/") + tableSet + Chain(TABMNG_TEMPSUFFIX));

		Chain oldTsRoot =  (*pTSE)->getAttributeValue(XML_TSROOT_ATTR);  

		ListT<Element*> fileList = (*pTSE)->getChildren(XML_DATAFILE_ELEMENT);
		Element **pFile = fileList.First();
		while ( pFile )
		{
		    Chain oldName = (*pFile)->getAttributeValue(XML_NAME_ATTR);
		    Chain newName;
		    oldName.replace(oldTsRoot, tsRoot, newName);
		    (*pFile)->setAttribute(XML_NAME_ATTR, newName);
		    
		    pFile = fileList.Next();
		}

		(*pTSE)->setAttribute(XML_TSROOT_ATTR, tsRoot);
						
		V();
		return;
	    }
	    pTSE = tabSetList.Next();
	}
	
	V();
	Chain msg = Chain("Unknown tableset ") + tableSet; 
	throw Exception(EXLOC, msg);
    }
    V();
    throw Exception(EXLOC, "Root element not found");    
}

void CegoXMLSpace::setTSSortAreaSize(const Chain& tableSet, unsigned long long sortAreaSize)
{
    P();
    Element *pTS = getTableSetElement(tableSet);

    if ( pTS )
    {
	pTS->setAttribute(XML_SORTAREASIZE_ATTR, Chain(sortAreaSize));
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
}

void CegoXMLSpace::setTSAppSize(const Chain& tableSet, unsigned appSize)
{
    P();
    Element *pTS = getTableSetElement(tableSet);

    if ( pTS )
    {
	ListT<Element*> fileList = pTS->getChildren(XML_DATAFILE_ELEMENT);
	Element **pFile = fileList.First();
	if ( pFile )
	{
	    if ( appSize > 0 )
	    {
		(*pFile)->setAttribute(XML_SIZE_ATTR, Chain(appSize));
	    }
	    else
	    {
		pTS->removeChild( *pFile );
	    }
	}
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
}

void CegoXMLSpace::setAppendMode(const Chain& tabSetName, bool isAppend)
{
    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {	
	if ( isAppend )
	    pTSE->setAttribute(XML_APPENDMODE_ATTR, XML_ON_VALUE);  
	else
	    pTSE->setAttribute(XML_APPENDMODE_ATTR, XML_OFF_VALUE);  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
}

bool CegoXMLSpace::getAppendMode(const Chain& tabSetName)
{
    bool isAppend=false;

    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {	
	if ( pTSE->getAttributeValue(XML_APPENDMODE_ATTR) == Chain(XML_ON_VALUE))
	    isAppend = true;
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
    return isAppend;
}

void CegoXMLSpace::setAutoCorrect(const Chain& tabSetName, const Chain& mode)
{
    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {	
	pTSE->setAttribute(XML_AUTOCORRECT_ATTR, mode);  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
}

Chain CegoXMLSpace::getAutoCorrect(const Chain& tabSetName)
{
    Chain mode;
    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {	
	mode = pTSE->getAttributeValue(XML_AUTOCORRECT_ATTR);
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
    return mode;
}

void CegoXMLSpace::setTableCacheMode(const Chain& tabSetName, bool isEnabled)
{
    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {
	Chain runState = pTSE->getAttributeValue(XML_RUNSTATE_ATTR);

	if ( runState != Chain(XML_OFFLINE_VALUE)
	     && runState != Chain(XML_DEFINED_VALUE) )
	{
	    V();
	    Chain msg = Chain("Tableset ") + tabSetName + Chain(" must be offline to enable/disable table cache ");
	    throw Exception(EXLOC, msg);
	}
	       
	if ( isEnabled )
	    pTSE->setAttribute(XML_TABLECACHE_ATTR, XML_ON_VALUE);  
	else
	    pTSE->setAttribute(XML_TABLECACHE_ATTR, XML_OFF_VALUE);  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
}

bool CegoXMLSpace::getTableCacheMode(const Chain& tabSetName)
{
    bool isEnabled=false;

    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {	
	if ( pTSE->getAttributeValue(XML_TABLECACHE_ATTR) == Chain(XML_ON_VALUE))
	    isEnabled = true;
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
    return isEnabled;
}

void CegoXMLSpace::setTableCacheFilter(const Chain& tableSet, const Chain& filter)
{
    P();
    Element *pTS = getTableSetElement(tableSet);

    if ( pTS )
    {
	pTS->setAttribute(XML_TABLECACHEFILTER_ATTR, filter);
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
}

Chain CegoXMLSpace::getTableCacheFilter(const Chain& tabSetName)
{
    Chain filter;

    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {
	filter =  pTSE->getAttributeValue(XML_TABLECACHEFILTER_ATTR);  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
    return filter;
}

void CegoXMLSpace::setTableCacheMaxSize(const Chain& tableSet, unsigned cacheSize)
{
    P();
    Element *pTS = getTableSetElement(tableSet);

    if ( pTS )
    {
	pTS->setAttribute(XML_TABLECACHEMAXSIZE_ATTR, Chain(cacheSize));
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
}

unsigned CegoXMLSpace::getTableCacheMaxSize(const Chain& tabSetName)
{
    unsigned cacheSize = 0;

    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {
	cacheSize =  pTSE->getAttributeValue(XML_TABLECACHEMAXSIZE_ATTR).asUnsigned();  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
    return cacheSize;
}

void CegoXMLSpace::setTableCacheMaxEntry(const Chain& tableSet, unsigned maxEntry)
{
    P();
    Element *pTS = getTableSetElement(tableSet);

    if ( pTS )
    {
	pTS->setAttribute(XML_TABLECACHEMAXENTRY_ATTR, Chain(maxEntry));
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
}

unsigned CegoXMLSpace::getTableCacheMaxEntry(const Chain& tabSetName)
{
    unsigned maxEntry = 0;

    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {
	maxEntry =  pTSE->getAttributeValue(XML_TABLECACHEMAXENTRY_ATTR).asUnsigned();  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
    return maxEntry;
}

void CegoXMLSpace::setTableCacheHashRange(const Chain& tableSet, unsigned hashRange)
{
    P();
    Element *pTS = getTableSetElement(tableSet);

    if ( pTS )
    {
	pTS->setAttribute(XML_TABLECACHEHASHRANGE_ATTR, Chain(hashRange));
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
}

unsigned CegoXMLSpace::getTableCacheHashRange(const Chain& tabSetName)
{
    unsigned hashRange = 0;

    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {
	hashRange =  pTSE->getAttributeValue(XML_TABLECACHEHASHRANGE_ATTR).asUnsigned();  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
    return hashRange;
}

void CegoXMLSpace::setMaxQueryCacheEntry(const Chain& tableSet, unsigned numEntry)
{
    P();
    Element *pTS = getTableSetElement(tableSet);

    if ( pTS )
    {
	pTS->setAttribute(XML_QUERYCACHEMAXENTRY_ATTR, Chain(numEntry));
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
}

unsigned CegoXMLSpace::getMaxQueryCacheEntry(const Chain& tabSetName)
{
    unsigned numEntry = 0;

    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {
	numEntry =  pTSE->getAttributeValue(XML_QUERYCACHEMAXENTRY_ATTR).asUnsigned();  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
    return numEntry;
}

void CegoXMLSpace::setMaxQueryCacheSize(const Chain& tableSet, unsigned cacheSize)
{
    P();
    Element *pTS = getTableSetElement(tableSet);

    if ( pTS )
    {
	pTS->setAttribute(XML_QUERYCACHEMAXSIZE_ATTR, Chain(cacheSize));
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
}

unsigned CegoXMLSpace::getMaxQueryCacheSize(const Chain& tabSetName)
{
    unsigned cacheSize = 0;

    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {
	cacheSize =  pTSE->getAttributeValue(XML_QUERYCACHEMAXSIZE_ATTR).asUnsigned();  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
    return cacheSize;
}

void CegoXMLSpace::setQueryCacheThreshold(const Chain& tableSet, unsigned threshold)
{
    P();
    Element *pTS = getTableSetElement(tableSet);

    if ( pTS )
    {
	pTS->setAttribute(XML_QUERYCACHETHRESHOLD_ATTR, Chain(threshold));
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
}

unsigned CegoXMLSpace::getQueryCacheThreshold(const Chain& tabSetName)
{
    unsigned threshold = 0;

    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {
	threshold =  pTSE->getAttributeValue(XML_QUERYCACHETHRESHOLD_ATTR).asUnsigned();  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
    return threshold;
}

void CegoXMLSpace::setQueryCacheHashRange(const Chain& tableSet, unsigned hashRange)
{
    P();
    Element *pTS = getTableSetElement(tableSet);

    if ( pTS )
    {
	pTS->setAttribute(XML_QUERYCACHEHASHRANGE_ATTR, Chain(hashRange));
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
}

unsigned CegoXMLSpace::getQueryCacheHashRange(const Chain& tabSetName)
{
    unsigned hashRange = 0;

    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {
	hashRange =  pTSE->getAttributeValue(XML_QUERYCACHEHASHRANGE_ATTR).asUnsigned();  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
    return hashRange;
}

void CegoXMLSpace::setQueryCacheMode(const Chain& tabSetName, bool isEnabled)
{
    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {
	Chain runState = pTSE->getAttributeValue(XML_RUNSTATE_ATTR);

	if ( runState != Chain(XML_OFFLINE_VALUE)
	     && runState != Chain(XML_DEFINED_VALUE) )
	{
	    V();
	    Chain msg = Chain("Tableset ") + tabSetName + Chain(" must be offline to enable/disable query cache ");
	    throw Exception(EXLOC, msg);
	}
		
	if ( isEnabled )
	    pTSE->setAttribute(XML_QUERYCACHE_ATTR, XML_ON_VALUE);  
	else
	    pTSE->setAttribute(XML_QUERYCACHE_ATTR, XML_OFF_VALUE);  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
}

bool CegoXMLSpace::getQueryCacheMode(const Chain& tabSetName)
{
    bool isEnabled=false;

    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {	
	if ( pTSE->getAttributeValue(XML_QUERYCACHE_ATTR) == Chain(XML_ON_VALUE))
	    isEnabled = true;
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
    return isEnabled;
}

void CegoXMLSpace::setCheckPointDump(const Chain& tabSetName, bool isEnabled)
{
    P();
    Element *pTSE = getTableSetElement(tabSetName);
    if ( pTSE )
    {		
	if ( isEnabled )
	    pTSE->setAttribute(XML_CPDUMP_ATTR, XML_ON_VALUE);  
	else
	    pTSE->setAttribute(XML_CPDUMP_ATTR, XML_OFF_VALUE);  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tabSetName; 
	throw Exception(EXLOC, msg);
    }
    V();
}

bool CegoXMLSpace::checkPointDumpEnabled(unsigned tabSetId)
{
    bool isEnabled=false;
    
    Element *pTSE = getCachedTableSetElement(tabSetId);

    if ( pTSE == 0)
    {
	Chain msg = "Unknown tableset id <" + Chain(tabSetId) + ">"; 
	throw Exception(EXLOC, msg);
    }

    P();    
    if ( pTSE->getAttributeValue(XML_CPDUMP_ATTR) == Chain(XML_ON_VALUE))
	isEnabled = true;
    V();
    
    return isEnabled;
}

void CegoXMLSpace::addTableSetDef(const Chain& tabSetName, 
				  const Chain& tsRoot, 
				  unsigned sysFileId, unsigned tempFileId, unsigned sysFileSize, unsigned tmpFileSize, unsigned appFileSize,
				  unsigned logFileSize, unsigned logFileNum, unsigned long long sortAreaSize, unsigned branchId)
{
    // first check some constraints here

    if ( logFileNum > LOGMNG_MAXNUMLOGFILE )
    {
	Chain msg = Chain("Too many logfiles, up to ") + Chain(LOGMNG_MAXNUMLOGFILE) + Chain(" logfiles allowed"); 
	throw Exception(EXLOC, msg);
    }

    Chain tsPath;
    if ( tsRoot.length() < 2 )
    {
	Directory d;
	d.setCurrent();
	tsPath = d.getName();
    }
    else
    {
	tsPath = tsRoot;
    }
    
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
	Element **pTSE = tabSetList.First();
	while ( pTSE ) 
	{
	    if ( (*pTSE)->getAttributeValue(XML_NAME_ATTR) == tabSetName )
	    {
		V();
		Chain msg = Chain("Tableset ") + Chain(tabSetName) + Chain(" already defined"); 
		throw Exception(EXLOC, msg);
	    }
	    pTSE = tabSetList.Next();
	}	
    }

    Element *pTSE = new Element(XML_TABLESET_ELEMENT);
    pTSE->setAttribute(XML_NAME_ATTR, tabSetName);
    
    pTSE->setAttribute(XML_TSROOT_ATTR, tsPath);
    
    pTSE->setAttribute(XML_RUNSTATE_ATTR, XML_DEFINED_VALUE);

    pTSE->setAttribute(XML_TSTICKET_ATTR, tsPath + Chain("/") + tabSetName + Chain("_ticket") + Chain(TABMNG_XMLSUFFIX));
    
    pTSE->setAttribute(XML_TSID_ATTR, Chain( sysFileId ) );
    pTSE->setAttribute(XML_TMPFID_ATTR, Chain( tempFileId ) );

    pTSE->setAttribute(XML_SYSSIZE_ATTR, Chain( sysFileSize ) );
    pTSE->setAttribute(XML_TMPSIZE_ATTR, Chain( tmpFileSize ) );

    pTSE->setAttribute(XML_SYSNAME_ATTR, tsPath + Chain("/") + tabSetName + Chain(TABMNG_SYSSUFFIX));
    pTSE->setAttribute(XML_TMPNAME_ATTR, tsPath + Chain("/") + tabSetName + Chain(TABMNG_TEMPSUFFIX));
    
    pTSE->setAttribute(XML_SORTAREASIZE_ATTR, Chain( sortAreaSize ) );
    pTSE->setAttribute(XML_BRANCHID_ATTR, Chain( branchId ) );

    /* default tableset values */ 
    pTSE->setAttribute(XML_AUTOCORRECT_ATTR, XML_POST_VALUE);
    pTSE->setAttribute(XML_ARCHMODE_ATTR, XML_OFF_VALUE);
    pTSE->setAttribute(XML_CHECKPOINT_ATTR, Chain(CHECKPOINTINTERVAL));
   
    for ( unsigned i = 0 ; i < logFileNum ; i++ )
    {
	Element *pLE = new Element(XML_LOGFILE_ELEMENT);

	Chain logName = tsPath + Chain("/") + tabSetName + Chain("_redo") +  Chain(i) + Chain(TABMNG_LOGSUFFIX);
	pLE->setAttribute(XML_NAME_ATTR, logName);
	pLE->setAttribute(XML_SIZE_ATTR, Chain(logFileSize));
	pLE->setAttribute(XML_STATUS_ATTR, XML_FREE_VALUE);
	
	pTSE->addContent(pLE);
    }

    _pDoc->getRootElement()->addContent(pTSE);

    V();

    if ( appFileSize > 0 )
    {
	unsigned appFid = nextFID();
	Chain appFileName = tsPath + Chain("/") + tabSetName + Chain("_data") + Chain(TABMNG_APPSUFFIX);
	addDataFile(tabSetName, Chain(XML_APPFILE_VALUE), appFid, appFileName, appFileSize);
    }
}

void CegoXMLSpace::rmTableSetDef(const Chain& tabSetName)
{
    P();
    
    ListT<Element*> tsList;    
    tsList = _pDoc->getRootElement()->getChildren(XML_TABLESET_ELEMENT);
    
    Element **pTS = tsList.First();
    while ( pTS ) 
    {
	if ( (*pTS)->getAttributeValue(XML_NAME_ATTR) == tabSetName )
	{
	    
	    unsigned tabSetId = (*pTS)->getAttributeValue(XML_TSID_ATTR).asUnsigned();
	    _tsCache[tabSetId] = 0;
	    _pDoc->getRootElement()->removeChild( *pTS );
	    V();
	    return;
	}
	pTS = tsList.Next();
    }
    
    V();
    Chain msg = Chain("Unknown tableset ") + Chain(tabSetName); 
    throw Exception(EXLOC, msg);
}

bool CegoXMLSpace::isArchiveMode(unsigned tabSetId)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
	Element **pTSE = tabSetList.First();
	while ( pTSE ) 
	{
	    if ( (*pTSE)->getAttributeValue(XML_TSID_ATTR).asUnsigned() == tabSetId )
	    {
		bool archMode=false;
		if ( (*pTSE)->getAttributeValue(XML_ARCHMODE_ATTR) == Chain(XML_ON_VALUE) )
		    archMode=true;
		V();
		return archMode;
	    }
	    pTSE = tabSetList.Next();
	}
    }
    
    V();
    Chain msg = Chain("Unknown tableset id ") + Chain(tabSetId); 
    throw Exception(EXLOC, msg);
}    

bool CegoXMLSpace::isArchiveMode(const Chain& tableSet)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
	Element **pTSE = tabSetList.First();
	while ( pTSE ) 
	{
	    if ( (*pTSE)->getAttributeValue(XML_NAME_ATTR) == tableSet )
	    {
		bool archMode=false;
		if ( (*pTSE)->getAttributeValue(XML_ARCHMODE_ATTR) == Chain(XML_ON_VALUE) )
		    archMode=true;
		V();
		return archMode;
	    }
	    pTSE = tabSetList.Next();
	}
    }
    V();
    Chain msg = Chain("Unknown tableset ") + tableSet; 
    throw Exception(EXLOC, msg);
}    

void CegoXMLSpace::enableArchLog(const Chain& tableSet)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
	Element **pTSE = tabSetList.First();
	while ( pTSE ) 
	{
	    if ( (*pTSE)->getAttributeValue(XML_NAME_ATTR) == tableSet )
	    {
		(*pTSE)->setAttribute(XML_ARCHMODE_ATTR, Chain(XML_ON_VALUE));
		V();
		return;
	    }
	    pTSE = tabSetList.Next();
	}
    }
    V();
    Chain msg = Chain("Unknown tableset ") + tableSet; 
    throw Exception(EXLOC, msg);
}    

void CegoXMLSpace::disableArchLog(const Chain& tableSet)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
	Element **pTSE = tabSetList.First();
	while ( pTSE ) 
	{
	    if ( (*pTSE)->getAttributeValue(XML_NAME_ATTR) == tableSet )
	    {
		(*pTSE)->setAttribute(XML_ARCHMODE_ATTR, Chain(XML_OFF_VALUE));
		V();
		return;
	    }
	    pTSE = tabSetList.Next();
	}
    }
    V();
    Chain msg = Chain("Unknown tableset ") + tableSet; 
    throw Exception(EXLOC, msg);
}    

void CegoXMLSpace::getArchLogInfo(unsigned tabSetId, ListT<Chain>& archIdList, ListT<Chain>& archPathList)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
	Element **pTSE = tabSetList.First();
	while ( pTSE ) 
	{
	    if ( (*pTSE)->getAttributeValue(XML_TSID_ATTR).asUnsigned() == tabSetId )
	    {
		ListT<Element*> archPathElementList = (*pTSE)->getChildren(XML_ARCHIVELOG_ELEMENT);
		Element **pAP = archPathElementList.First();
		while ( pAP )
		{
		    archPathList.Insert((*pAP)->getAttributeValue(XML_ARCHPATH_ATTR));
		    archIdList.Insert((*pAP)->getAttributeValue(XML_ARCHID_ATTR));

		    pAP = archPathElementList.Next();
		}
		V();
		return;
	    }
	    pTSE = tabSetList.Next();
	}
    }
    
    V();
    Chain msg = Chain("Unknown tableset id ") + Chain(tabSetId); 
    throw Exception(EXLOC, msg);
}    

void CegoXMLSpace::getArchLogInfo(const Chain& tableSet, ListT<Chain>& archIdList, ListT<Chain>& archPathList)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
	Element **pTSE = tabSetList.First();
	while ( pTSE ) 
	{
	    if ( (Chain)(*pTSE)->getAttributeValue(XML_NAME_ATTR) == (Chain)tableSet )
	    {
		ListT<Element*> archPathElementList = (*pTSE)->getChildren(XML_ARCHIVELOG_ELEMENT);
		Element **pAP = archPathElementList.First();
		while ( pAP )
		{
		    archPathList.Insert((*pAP)->getAttributeValue(XML_ARCHPATH_ATTR));
		    archIdList.Insert((*pAP)->getAttributeValue(XML_ARCHID_ATTR));
		    pAP = archPathElementList.Next();
		}
		V();
		return;
	    }
	    pTSE = tabSetList.Next();
	}
    }
    
    V();
    Chain msg = Chain("Unknown tableset ") + tableSet; 
    throw Exception(EXLOC, msg);
}    

void CegoXMLSpace::getOccupiedLogList(unsigned tabSetId, ListT<Chain>& occupiedLogList)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
	Element **pTSE = tabSetList.First();
	while ( pTSE ) 
	{
	    if ( (*pTSE)->getAttributeValue(XML_TSID_ATTR).asUnsigned() == tabSetId )
	    {
		ListT<Element*> logElementList = (*pTSE)->getChildren(XML_LOGFILE_ELEMENT);
		Element **pLE = logElementList.First();
		while ( pLE )
		{
		    if ( (*pLE)->getAttributeValue(XML_STATUS_ATTR) == Chain(XML_OCCUPIED_VALUE))	
			occupiedLogList.Insert((*pLE)->getAttributeValue(XML_NAME_ATTR));
		    pLE = logElementList.Next();
		}
		V();
		return;
	    }
	    pTSE = tabSetList.Next();
	}
    }
    V();
    Chain msg = Chain("Unknown tableset id ") + Chain(tabSetId); 
    throw Exception(EXLOC, msg);
}    

void CegoXMLSpace::setLogFileStatus(unsigned tabSetId, const Chain& logFile, const Chain& status)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
	Element **pTSE = tabSetList.First();
	while ( pTSE ) 
	{
	    if ( (*pTSE)->getAttributeValue(XML_TSID_ATTR).asUnsigned() == tabSetId )
	    {
		ListT<Element*> logElementList = (*pTSE)->getChildren(XML_LOGFILE_ELEMENT);
		Element **pLE = logElementList.First();
		while ( pLE )
		{
		    if ( (*pLE)->getAttributeValue(XML_NAME_ATTR) == logFile)	
		    {
			(*pLE)->setAttribute(XML_STATUS_ATTR, status);
			V();
			return;
		    }
		    pLE = logElementList.Next();
		}
	    }
	    pTSE = tabSetList.Next();
	}
    }
    V();
    Chain msg = Chain("Unknown tableset id ") + Chain(tabSetId); 
    throw Exception(EXLOC, msg);    
}

bool CegoXMLSpace::addArchLog(const Chain& tableSet, const Chain& archId, const Chain& archPath)
{
    Directory d(archPath);
    if ( d.exists() == false )
    {
	Chain msg = Chain("Archive path ") + archPath + Chain(" does not exist"); 
	throw Exception(EXLOC, msg);    
    }
    
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
	Element **pTSE = tabSetList.First();
	while ( pTSE ) 
	{
	    if ( (*pTSE)->getAttributeValue(XML_NAME_ATTR) == tableSet )
	    {

		ListT<Element*> archLogList = (*pTSE)->getChildren(XML_ARCHIVELOG_ELEMENT);
		Element **pAL = archLogList.First();
		while ( pAL )
		{
		    if ( (*pAL)->getAttributeValue(XML_ARCHID_ATTR) == archId )
		    {
			V();
			return false;
		    }
		    pAL = archLogList.Next();
		} 
		
		Element *pNAL = new Element(XML_ARCHIVELOG_ELEMENT);
		pNAL->setAttribute(XML_ARCHID_ATTR, archId);
		pNAL->setAttribute(XML_ARCHPATH_ATTR, archPath);
		
		(*pTSE)->addContent(pNAL);
		V();
		return true;
		
	    }
	    pTSE = tabSetList.Next();
	}
    }
    V();
    Chain msg = Chain("Unknown tableset ") + tableSet; 
    throw Exception(EXLOC, msg);    
}

bool CegoXMLSpace::removeArchLog(const Chain& tableSet, const Chain& archId)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
	Element **pTSE = tabSetList.First();
	while ( pTSE ) 
	{
	    if ( (*pTSE)->getAttributeValue(XML_NAME_ATTR) == tableSet )
	    {
		ListT<Element*> archLogList = (*pTSE)->getChildren(XML_ARCHIVELOG_ELEMENT);
		Element **pAL = archLogList.First();
		while ( pAL )
		{
		    if ( (*pAL)->getAttributeValue(XML_ARCHID_ATTR) == archId )
		    {
			(*pTSE)->removeChild(*pAL);
			V();
			return true;
		    }
		    pAL = archLogList.Next();
		} 
		V();
		return false;
	    }
	    pTSE = tabSetList.Next();
	}
	
	V();
	Chain msg = Chain("Unknown tableset ") + tableSet; 
	throw Exception(EXLOC, msg);
    }
    V();
    throw Exception(EXLOC, "Root element not found");
}

void CegoXMLSpace::setUserPwd(const Chain& user, const Chain& password)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {	
	ListT<Element*> userList = pRoot->getChildren(XML_USER_ELEMENT);
	Element **pUE = userList.First();
	while ( pUE )
	{
	    if ( (*pUE)->getAttributeValue(XML_NAME_ATTR) == user )
	    {
		(*pUE)->setAttribute(XML_PASSWD_ATTR, password);
		V();
		return;
	    }
	    pUE = userList.Next();
	} 
	
	V();
	Chain msg = Chain("Unknown user ") + user; 
	throw Exception(EXLOC, msg);
    }
    V();
}

Chain CegoXMLSpace::getUserPwd(const Chain& user)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {	
	ListT<Element*> userList = pRoot->getChildren(XML_USER_ELEMENT);
	Element **pUE = userList.First();
	while ( pUE )
	{
	    if ( (*pUE)->getAttributeValue(XML_NAME_ATTR) == user )
	    {
		Chain pwd = (*pUE)->getAttributeValue(XML_PASSWD_ATTR);
		V();
		return pwd;
	    }
	    pUE = userList.Next();
	} 
	
	V();
	Chain msg = Chain("Unknown user ") + user; 
	throw Exception(EXLOC, msg);
    }
    V();
    throw Exception(EXLOC, "Root element not found");
}

void CegoXMLSpace::addUser(const Chain& user, const Chain& password)
{
    if ( user == Chain() )
    {
	Chain msg = Chain("User cannot be empty"); 
	throw Exception(EXLOC, msg);
    }
    
    P();
    
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> userList = pRoot->getChildren(XML_USER_ELEMENT);
	Element **pUE = userList.First();
	while ( pUE )
	{
	    if ( (*pUE)->getAttributeValue(XML_NAME_ATTR) == user )
	    {
		V();
		Chain msg = Chain("User ") + user + Chain(" already defined "); 
		throw Exception(EXLOC, msg);
	    }
	    pUE = userList.Next();
	} 
		
	Element *pNUE = new Element(XML_USER_ELEMENT);
	pNUE->setAttribute(XML_NAME_ATTR, user);
	pNUE->setAttribute(XML_PASSWD_ATTR, password);
	pNUE->setAttribute(XML_TRACE_ATTR, XML_OFF_VALUE);
	
	pRoot->addContent(pNUE);
	V();
	return;
    }
    V();
}

void CegoXMLSpace::assignUserRole(const Chain& user, const Chain& role)
{
    P();
    Element *pRoot = _pDoc->getRootElement();

    if ( role != Chain(ROLE_ADMIN) && role != Chain(ROLE_JDBC) )
    {
	bool roleFound = false;
		    
	ListT<Element*> roleList = pRoot->getChildren(XML_ROLE_ELEMENT);
	Element **pRE = roleList.First();
	while ( pRE && roleFound == false)
	{
	    if ( (*pRE)->getAttributeValue(XML_NAME_ATTR) == role )
	    {	    
		roleFound=true;	    
	    }
	    else
	    {
		pRE = roleList.Next();
	    }
	}
	if ( roleFound == false )
	{
	    V();
	    Chain msg = Chain("Unknown role ") + role; 
	    throw Exception(EXLOC, msg);
	}
    }

    ListT<Element*> userList = pRoot->getChildren(XML_USER_ELEMENT);
    Element **pUE = userList.First();
    while ( pUE )
    {
	if ( (*pUE)->getAttributeValue(XML_NAME_ATTR) == user )
	{    
	    Chain roleString = (*pUE)->getAttributeValue(XML_ROLE_ATTR);	    
	    Tokenizer t(roleString, ",");

	    Chain assignedRole;
	    SetT<Chain> roleSet; 
	    while ( t.nextToken(assignedRole) )
	    {
		roleSet.Insert(assignedRole);
	    }
	    roleSet.Insert(role);

	    Chain newRoleString;
	    Chain *pRole = roleSet.First();
	    while ( pRole )
	    {
		newRoleString += *pRole;
		pRole = roleSet.Next();
		if ( pRole ) 
		    newRoleString += ",";
	    }
	    
	    (*pUE)->setAttribute(XML_ROLE_ATTR, newRoleString);
	    	    
	    V();
	    return;
	}
	pUE = userList.Next();
    } 
	
    V();
    Chain msg = Chain("Unknown user ") + user;
    throw Exception(EXLOC, msg);
}

void CegoXMLSpace::removeUserRole(const Chain& user, const Chain& role)
{
    P();

    Element *pRoot = _pDoc->getRootElement();
    
    ListT<Element*> userList = pRoot->getChildren(XML_USER_ELEMENT);
    Element **pUE = userList.First();
    while ( pUE )
    {
	if ( (*pUE)->getAttributeValue(XML_NAME_ATTR) == user )
	{   
	    Chain roleString = (*pUE)->getAttributeValue(XML_ROLE_ATTR);	    
	    Tokenizer t(roleString, ",");

	    Chain assignedRole;
	    SetT<Chain> roleSet; 
	    while ( t.nextToken(assignedRole) )
	    {
		roleSet.Insert(assignedRole);
	    }

	    roleSet.Remove(role);

	    Chain newRoleString;
	    Chain *pRole = roleSet.First();
	    while ( pRole )
	    {
		newRoleString += *pRole;
		pRole = roleSet.Next();
		if ( pRole ) 
		    newRoleString += ",";
	    }
	    
	    (*pUE)->setAttribute(XML_ROLE_ATTR, newRoleString);
	    
	    V();
	    return;
	}
	pUE = userList.Next();
    } 
	
    V();
    Chain msg = Chain("Unknown user ") + user;
    throw Exception(EXLOC, msg);
}

Chain CegoXMLSpace::getUserRole(const Chain& user)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    ListT<Element*> userList = pRoot->getChildren(XML_USER_ELEMENT);
    Element **pUE = userList.First();
    while ( pUE )
    {
	if ( (*pUE)->getAttributeValue(XML_NAME_ATTR) == user )
	{
	    Chain role = (*pUE)->getAttributeValue(XML_ROLE_ATTR);
	    V();
	    return role;
	}
	pUE = userList.Next();
    } 
    
    V();
    Chain msg = Chain("Unknown user ") + user;
    throw Exception(EXLOC, msg);
}

void CegoXMLSpace::createRole(const Chain& role)
{
    if ( role == Chain(ROLE_ADMIN) )
    {
	Chain msg = Chain("Role admin cannot be created"); 
	throw Exception(EXLOC, msg);
    }

    if ( role == Chain(ROLE_JDBC) )
    {
	Chain msg = Chain("Role jdbc cannot be created"); 
	throw Exception(EXLOC, msg);
    }

    if ( role == Chain() )
    {
	Chain msg = Chain("Role cannot be empty"); 
	throw Exception(EXLOC, msg);
    }

    P();
    
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> roleList = pRoot->getChildren(XML_ROLE_ELEMENT);
	Element **pRE = roleList.First();
	while ( pRE )
	{
	    if ( (*pRE)->getAttributeValue(XML_NAME_ATTR) == role )
	    {
		V();
		Chain msg = Chain("Role ") + role + Chain(" already defined "); 
		throw Exception(EXLOC, msg);
	    }
	    pRE = roleList.Next();
	} 
		
	Element *pNRE = new Element(XML_ROLE_ELEMENT);
	pNRE->setAttribute(XML_NAME_ATTR, role);	
	pRoot->addContent(pNRE);
	V();
	return;
    }
    V();
}

void CegoXMLSpace::dropRole(const Chain& role)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	// drop role from all users

	ListT<Element*> userList = pRoot->getChildren(XML_USER_ELEMENT);

	Element **pUser = userList.First();
	while ( pUser )
	{
	    Chain roleString = (*pUser)->getAttributeValue(XML_ROLE_ATTR);	    
	    Tokenizer t(roleString, ",");

	    Chain assignedRole;
	    SetT<Chain> roleSet; 
	    while ( t.nextToken(assignedRole) )
	    {
		roleSet.Insert(assignedRole);
	    }

	    roleSet.Remove(role);

	    Chain newRoleString;
	    Chain *pRole = roleSet.First();
	    while ( pRole )
	    {
		newRoleString += *pRole;
		pRole = roleSet.Next();
		if ( pRole ) 
		    newRoleString += ",";
	    }
	    
	    (*pUser)->setAttribute(XML_ROLE_ATTR, newRoleString);

	    pUser = userList.Next();
	}

	ListT<Element*> roleList = pRoot->getChildren(XML_ROLE_ELEMENT);
	Element **pRE = roleList.First();
	while ( pRE )
	{
	    if ( (*pRE)->getAttributeValue(XML_NAME_ATTR) == role )
	    {
		pRoot->removeChild(*pRE);
		V();
		return;
		
	    }
	    pRE = roleList.Next();
	}
	V();
	Chain msg = Chain("Unknown role ") + role; 
	throw Exception(EXLOC, msg);
    }
    V();
}

Element* CegoXMLSpace::getPermInfo(const Chain& role)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> roleList = pRoot->getChildren(XML_ROLE_ELEMENT);
	Element **pRE = roleList.First();
	while ( pRE )
	{
	    if ( (*pRE)->getAttributeValue(XML_NAME_ATTR) == role )
	    {    
		Element* pPermInfo = new Element(XML_PERMINFO_ELEMENT);
	
		ListT<Element*> permList = (*pRE)->getChildren(XML_PERM_ELEMENT);
		Element **pPE = permList.First();
		while ( pPE )
		{

		    pPermInfo->addContent((*pPE)->createClone() );
		    pPE = permList.Next();
		}
		V();

		return pPermInfo;
	    }
	    pRE = roleList.Next();
	}
	V();
	Chain msg = Chain("Unknown role ") + role; 
	throw Exception(EXLOC, msg);
    }
    V();
    Chain msg = Chain("Cannot get role info ") + role; 
    throw Exception(EXLOC, msg);
}

void CegoXMLSpace::setPerm(const Chain& role, const Chain& permid, const Chain& tableset, const Chain& filter, const Chain& perm)
{    
    if ( role == Chain(ROLE_ADMIN) )
    {
	Chain msg = Chain("Permission canot be added to admin role"); 
	throw Exception(EXLOC, msg);
    }

    if ( role == Chain(ROLE_JDBC) )
    {
	Chain msg = Chain("Permission canot be added to jdbc role"); 
	throw Exception(EXLOC, msg);
    }

    Chain uperm = perm.toUpper();

    if ( uperm != Chain()
	 && uperm != Chain("READ") 
	 && uperm != Chain("WRITE")
	 && uperm != Chain("MODIFY")
	 && uperm != Chain("EXEC")
	 && uperm != Chain("ALL") )
    {
	Chain msg = Chain("Invalid permission ") + perm; 
	throw Exception(EXLOC, msg);
    }

    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> roleList = pRoot->getChildren(XML_ROLE_ELEMENT);
	Element **pRE = roleList.First();
	while ( pRE )
	{
	    if ( (*pRE)->getAttributeValue(XML_NAME_ATTR) == role )
	    {
		ListT<Element*> permList = (*pRE)->getChildren(XML_PERM_ELEMENT);
		Element **pPE = permList.First();
		while ( pPE )
		{
		    if ( (*pPE)->getAttributeValue(XML_PERMID_ATTR) == permid )
		    {
			if ( tableset != Chain() )
			    (*pPE)->setAttribute(XML_TABLESET_ATTR, tableset);
			if ( filter != Chain() )
			    (*pPE)->setAttribute(XML_FILTER_ATTR, filter);
			if ( uperm != Chain() )
			    (*pPE)->setAttribute(XML_PERM_ATTR, uperm);
			V();
			return;		       
		    }
		    pPE = permList.Next();
		}

		// new permission entry
		if ( tableset == Chain()
		     || filter == Chain()
		     || uperm == Chain() )
		{
		    V();
		    Chain msg = Chain("Incomplete permission definition");
		    throw Exception(EXLOC, msg);
		}
		Element *pNPE = new Element(XML_PERM_ELEMENT);

		pNPE->setAttribute(XML_TABLESET_ATTR, tableset);
		pNPE->setAttribute(XML_FILTER_ATTR, filter);
		pNPE->setAttribute(XML_PERM_ATTR, uperm);
		pNPE->setAttribute(XML_PERMID_ATTR, permid);
	
		(*pRE)->addContent(pNPE);
		V();

		return;
		
	    }
	    pRE = roleList.Next();
	}
	V();
	Chain msg = Chain("Unknown role ") + role; 
	throw Exception(EXLOC, msg);
    }
    V();
}

void CegoXMLSpace::removePerm(const Chain& role, const Chain& permid)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> roleList = pRoot->getChildren(XML_ROLE_ELEMENT);
	Element **pRE = roleList.First();
	while ( pRE )
	{
	    if ( (*pRE)->getAttributeValue(XML_NAME_ATTR) == role )
	    {
		ListT<Element*> permList = (*pRE)->getChildren(XML_PERM_ELEMENT);
		Element **pPE = permList.First();
		while ( pPE )
		{
		    if ( (*pPE)->getAttributeValue(XML_PERMID_ATTR) == permid ) 
		    {		
			(*pRE)->removeChild(*pPE);			
			V();
			return;	
		    }
		    pPE = permList.Next();
		}

		V();
		Chain msg = Chain("Unknown permission for role ") + role; 
		throw Exception(EXLOC, msg);
	    }
	    pRE = roleList.Next();
	}
	V();
	Chain msg = Chain("Unknown role ") + role; 
	throw Exception(EXLOC, msg);
    }
    V();
}

void CegoXMLSpace::setUserTrace(const Chain& user, bool isOn)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    ListT<Element*> userList = pRoot->getChildren(XML_USER_ELEMENT);
    Element **pUE = userList.First();
    while ( pUE )
    {
	if ( (*pUE)->getAttributeValue(XML_NAME_ATTR) == user )
	{
	    if ( isOn )
		(*pUE)->setAttribute(XML_TRACE_ATTR, XML_ON_VALUE);
	    else
		(*pUE)->setAttribute(XML_TRACE_ATTR, XML_OFF_VALUE);
	    V();
	    return;
	}
	pUE = userList.Next();
    } 
    
    V();
    Chain msg = Chain("Unknown user ") + user;
    throw Exception(EXLOC, msg);
}

void CegoXMLSpace::removeUser(const Chain& user)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> userList = pRoot->getChildren(XML_USER_ELEMENT);
	Element **pUE = userList.First();
	while ( pUE )
	{
	    if ( (*pUE)->getAttributeValue(XML_NAME_ATTR) == user )
	    {
		pRoot->removeChild(*pUE);
		V();
		return;		
	    }
	    pUE = userList.Next();
	}
	V();
	Chain msg = Chain("Unknown user ") + user; 
	throw Exception(EXLOC, msg);
    }
    V();
}

bool CegoXMLSpace::checkAdminUser(const Chain& user, const Chain& password, bool& isTrace)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> userList = pRoot->getChildren(XML_USER_ELEMENT);
	Element **pUE = userList.First();
	while ( pUE )
	{
	    if ( (*pUE)->getAttributeValue(XML_NAME_ATTR) == user )
	    {
		Chain roleString = (*pUE)->getAttributeValue(XML_ROLE_ATTR);
		
		Tokenizer t(roleString, ",");
		Chain role;
		bool adminFound=false;

		while ( t.nextToken(role) && adminFound == false )
		{
		    if ( role == Chain(ROLE_ADMIN) )
			adminFound = true;       
		}

		bool ret = false;

		if ( adminFound && (*pUE)->getAttributeValue(XML_PASSWD_ATTR) == password )
		{
		    ret = true;
		}

		if ( (*pUE)->getAttributeValue(XML_TRACE_ATTR) == Chain(XML_ON_VALUE) )
		{
		    unsigned long long numReq = (*pUE)->getAttributeValue(XML_NUMREQUEST_ATTR).asUnsignedLongLong();
		    numReq++;
		    (*pUE)->setAttribute(XML_NUMREQUEST_ATTR, Chain(numReq));
		    isTrace=true;
		}
		else
		    isTrace=false;
		
		V();
		return ret;
	    }
	    pUE = userList.Next();
	}
    }
    V();
    return false;
}

void CegoXMLSpace::getAdminUser(Chain& user, Chain& password)
{
    P();

    bool adminFound=false;
    
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot && adminFound == false ) 
    {
	ListT<Element*> userList = pRoot->getChildren(XML_USER_ELEMENT);
	Element **pUE = userList.First();
	if ( pUE )
	{
	    Chain roleString = (*pUE)->getAttributeValue(XML_ROLE_ATTR);
	    
	    Tokenizer t(roleString, ",");
	    Chain role;
	    	    
	    while ( t.nextToken(role) && adminFound == false )
	    {
		if ( role == Chain(ROLE_ADMIN) )
		    adminFound = true;       
	    }
	    
	    if ( adminFound == true )
	    {
		user = (*pUE)->getAttributeValue(XML_NAME_ATTR);	    
		password = (*pUE)->getAttributeValue(XML_PASSWD_ATTR);
	    }
	}
    }
    V();
    return;
}

bool CegoXMLSpace::checkUser(const Chain& user, const Chain& password, Chain& msg, bool& isTrace)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {	
	ListT<Element*> userList = pRoot->getChildren(XML_USER_ELEMENT);
	Element **pUE = userList.First();
	while ( pUE )
	{
	    if ( (*pUE)->getAttributeValue(XML_NAME_ATTR) == user )
	    {
		bool ret;
		
		if ( (*pUE)->getAttributeValue(XML_PASSWD_ATTR) == password )
		{
		    ret = true;
		}
		else
		{
		    msg = Chain("Invalid password for user ") + user;
		    ret = false;
		}
		
		if ( (*pUE)->getAttributeValue(XML_TRACE_ATTR) == Chain(XML_ON_VALUE) )
		{
		    unsigned long long numReq = (*pUE)->getAttributeValue(XML_NUMREQUEST_ATTR).asUnsignedLongLong();
		    numReq++;
		    (*pUE)->setAttribute(XML_NUMREQUEST_ATTR, Chain(numReq));
		    isTrace=true;
		}
		else
		    isTrace=false;
				
		V();
		return ret;
	    }
	    pUE = userList.Next();
	} 
	msg = Chain("Unknown user ") + user;
	V();
	return false;
    }
    V();
    return false;
}

void CegoXMLSpace::changePassword(const Chain& user, const Chain& password)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> userList = pRoot->getChildren(XML_USER_ELEMENT);
	Element **pUE = userList.First();
	while ( pUE )
	{
	    if ( (*pUE)->getAttributeValue(XML_NAME_ATTR) == user )
	    {			
		(*pUE)->setAttribute(XML_PASSWD_ATTR, password);
		V();
		return;
	    }
	    pUE = userList.Next();
	} 
	V();
	Chain msg = Chain("Unknown user \"") + user + Chain("\""); 
	throw Exception(EXLOC, msg);
    }
    V();
}

void CegoXMLSpace::incUserQuery(const Chain& user)
{
    P();

    Element *pRoot = _pDoc->getRootElement();    
    if ( pRoot )
    {
	ListT<Element*> userList = pRoot->getChildren(XML_USER_ELEMENT);
	Element **pUE = userList.First();
	while ( pUE )
	{
	    if ( (*pUE)->getAttributeValue(XML_NAME_ATTR) == user )
	    {
		unsigned long long numQuery = (*pUE)->getAttributeValue(XML_NUMQUERY_ATTR).asUnsignedLongLong();
		numQuery++;
		(*pUE)->setAttribute(XML_NUMQUERY_ATTR, Chain(numQuery));
		V();
		return;
	    }
	    pUE = userList.Next();
	} 
	
	V();
	Chain msg = Chain("Unknown user ") + user;
	throw Exception(EXLOC, msg);
    }
    V();
}

Element* CegoXMLSpace::getUserList()
{
    P();

    Element *pRoot = _pDoc->getRootElement();    
    if ( pRoot )
    {	
	ListT<Element*> userList = pRoot->getChildren(XML_USER_ELEMENT);
	Element *pUserInfo = new Element(XML_USERINFO_ELEMENT);
	
	Element **pUser = userList.First();
	while ( pUser )
	{
	    Element *pN = new Element(XML_USER_ELEMENT);
	    pN->setAttribute(XML_NAME_ATTR, (*pUser)->getAttributeValue(XML_NAME_ATTR));
	    pN->setAttribute(XML_TRACE_ATTR, (*pUser)->getAttributeValue(XML_TRACE_ATTR));
	    pN->setAttribute(XML_NUMREQUEST_ATTR, (*pUser)->getAttributeValue(XML_NUMREQUEST_ATTR));
	    pN->setAttribute(XML_NUMQUERY_ATTR, (*pUser)->getAttributeValue(XML_NUMQUERY_ATTR));
	    pN->setAttribute(XML_ROLE_ATTR, (*pUser)->getAttributeValue(XML_ROLE_ATTR));
	    pUserInfo->addContent(pN);
	    pUser = userList.Next();
	}
	V();
	
	return pUserInfo;
    }
    V();

    return 0;
}    

Element* CegoXMLSpace::getRoleList()
{
    P();

    Element *pRoot = _pDoc->getRootElement();    
    if ( pRoot )
    {	
	ListT<Element*> roleList = pRoot->getChildren(XML_ROLE_ELEMENT);
	Element *pRoleList = new Element(XML_ROLELIST_ELEMENT);
	
	Element **pRE = roleList.First();
	while ( pRE )
	{
	    Element *pN = new Element(XML_ROLE_ELEMENT);
	    pN->setAttribute(XML_NAME_ATTR, (*pRE)->getAttributeValue(XML_NAME_ATTR));
	    pRoleList->addContent(pN);
	    pRE = roleList.Next();
	}
	V();
	
	return pRoleList;
    }
    V();

    return 0;
}    

void CegoXMLSpace::getDataPort(unsigned& dataPort)
{
    P();
    dataPort = _pDoc->getRootElement()->getAttributeValue(XML_DATAPORT_ATTR).asUnsigned();
    V();
}

void CegoXMLSpace::setDBHost(const Chain& dbHost)
{
    P();
    _pDoc->getRootElement()->setAttribute(XML_HOSTNAME_ATTR, dbHost);
    V();
}

void CegoXMLSpace::getDBHost(Chain& dbHost)
{
    P();
    getDBHostLocked(dbHost);
    V();
}

void CegoXMLSpace::getDBHostLocked(Chain& dbHost)
{
    dbHost = _pDoc->getRootElement()->getAttributeValue(XML_HOSTNAME_ATTR);
}

void CegoXMLSpace::getAdminPort(unsigned& adminPort)
{
    P();
    adminPort = _pDoc->getRootElement()->getAttributeValue(XML_ADMINPORT_ATTR).asUnsigned();
    V();
}

void CegoXMLSpace::getLogPort(unsigned& logPort)
{
    P();
    logPort = _pDoc->getRootElement()->getAttributeValue(XML_LOGPORT_ATTR).asUnsigned();
    V();
}

void CegoXMLSpace::setTSRoot(const Chain& tableSet, const Chain& tsRoot)
{
    P();
    Element *pTS = getTableSetElement(tableSet);

    if ( pTS )
    {
	pTS->setAttribute(XML_TSROOT_ATTR, tsRoot);
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
}

Chain CegoXMLSpace::getTSRoot(const Chain& tableSet) const
{
    Chain tsRoot;

    P();
    
    Element *pTSE = getTableSetElement(tableSet);
    if ( pTSE )
    {
	tsRoot =  pTSE->getAttributeValue(XML_TSROOT_ATTR);  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tableSet; 
	throw Exception(EXLOC, msg);
    }
    V();
    return tsRoot;
}

void CegoXMLSpace::nextTableSetBackupBranch(const Chain& tableSet)
{
    P();

    Element *pRoot = _pDoc->getRootElement();
    
    Element *pTS = getTableSetElement(tableSet);

    if ( pTS )
    {	
	unsigned branchId = pRoot->getAttributeValue(XML_NEXTBRANCHID_ATTR).asUnsigned();

	// if branchId still not setup, we use current tableset branchId 
	if ( branchId == 0 )
	{
	    branchId = pTS->getAttributeValue(XML_BRANCHID_ATTR).asUnsigned();
	    branchId++;
	}
	
	pTS->setAttribute(XML_BRANCHID_ATTR, branchId);
	
	branchId++;	
	pRoot->setAttribute(XML_NEXTBRANCHID_ATTR, Chain(branchId)); 
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
}

Chain CegoXMLSpace::getTableSetBackupBranch(const Chain& tableSet)
{
    Chain branchId;

    P();
    
    Element *pTSE = getTableSetElement(tableSet);
    if ( pTSE )
    {
	branchId =  pTSE->getAttributeValue(XML_BRANCHID_ATTR);  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tableSet; 
	throw Exception(EXLOC, msg);
    }
    V();
    return branchId;
}

Chain CegoXMLSpace::getDbName()
{
    P();
    Chain dbName = _pDoc->getRootElement()->getAttributeValue(XML_NAME_ATTR);
    V();
    return dbName;
}

unsigned CegoXMLSpace::getPageSize()
{
    P();
    unsigned pageSize = _pDoc->getRootElement()->getAttributeValue(XML_PAGESIZE_ATTR).asUnsigned();
    V();
    return pageSize;
}

void CegoXMLSpace::initDoc()
{
    P();
    ListT<Element*> nodeList;
    Chain dbHost;

    nodeList = _pDoc->getRootElement()->getChildren(XML_NODE_ELEMENT);
    Element **pNode = nodeList.First();
    while ( pNode ) 
    {
	_pDoc->getRootElement()->removeChild(*pNode);
	nodeList = _pDoc->getRootElement()->getChildren(XML_NODE_ELEMENT);
	pNode = nodeList.First();
    }

    dbHost = _pDoc->getRootElement()->getAttributeValue(XML_HOSTNAME_ATTR);    

    V();
        
    addHost(dbHost, XML_ONLINE_VALUE);
   
    return;
}

void CegoXMLSpace::setXmlDef(const Chain& xmlDef)
{
    _xmlDef = xmlDef;
}

void CegoXMLSpace::initXml(const Chain& dbName, unsigned pageSize, const Chain& hostName,
			   unsigned dbPort, unsigned admPort, unsigned logPort,
			   const Chain& logLevel, const Chain& csmode, bool qescmode)
{
    P();

    try
    {	
	XMLSuite xml;
	xml.setDocument(_pDoc);
	
	_pDoc->setDocType(Chain(CEGO_DB_DOC));
	_pDoc->setAttribute(XML_VERSION_ATTR, XML_VERSION_VALUE);
	
	Element *pElement = new Element(XML_DATABASE_ELEMENT);
	pElement->setAttribute(XML_NAME_ATTR, dbName);

	pElement->setAttribute(XML_PAGESIZE_ATTR, Chain(pageSize));
	pElement->setAttribute(XML_HOSTNAME_ATTR, hostName);
	pElement->setAttribute(XML_DATAPORT_ATTR, Chain(dbPort));
	pElement->setAttribute(XML_ADMINPORT_ATTR, Chain(admPort));
	pElement->setAttribute(XML_LOGPORT_ATTR, Chain(logPort));
	pElement->setAttribute(XML_CSMODE_ATTR, csmode);
	
	if ( qescmode )
	    pElement->setAttribute(XML_QESCMODE_ATTR, XML_ON_VALUE);
	else 
	    pElement->setAttribute(XML_QESCMODE_ATTR, XML_OFF_VALUE);

	Element *pLog = new Element(XML_MODULE_ELEMENT);
	pLog->setAttribute(XML_NAME_ATTR, Chain("ALL"));
	pLog->setAttribute(XML_LEVEL_ATTR, logLevel);	
	pElement->addContent(pLog);

	_pDoc->setRootElement(pElement);

	Chain xmlChain;
	xml.getXMLChain(xmlChain);
	
	File xmlFile(_xmlDef);
	
	xmlFile.open(File::WRITE);
	
	xmlFile.writeChain(xmlChain);
	
	xmlFile.close();
    }
    catch ( Exception e )
    {
	V();
	throw Exception(EXLOC, Chain("Cannot write file ") + _xmlDef, e);
    }
    V();
}

void CegoXMLSpace::xml2Doc()
{
    P();

    Chain xmlString;

    try
    {
	File xmlFile(_xmlDef);
	
	xmlFile.open(File::READ);
	
	Chain line;
	while (xmlFile.readLine(line))
	{
	    
	    xmlString = xmlString + line + Chain("\n");
	    xmlString = xmlString.cutTrailing(" \t");
	    
	}

	xmlFile.close();	
    }
    catch ( Exception e )
    {
	V();
	throw Exception(EXLOC, Chain("Cannot read file ") + _xmlDef, e);
    }

    XMLSuite xml(xmlString);
    xml.setDocument(_pDoc);
    
    try
    {
	xml.parse();
    }
    catch ( Exception e )
    {
	V();
	Chain xmlmsg;
	e.pop(xmlmsg);
	Chain msg = Chain("XML parse error at line ") + Chain( xml.getLineNo()) + Chain(" : ") + xmlmsg;
	throw Exception(EXLOC, msg);
    }
    V();
}

void CegoXMLSpace::doc2Xml()
{
    P();

    try
    {	
	Timer t(6,3);
	t.start();
	
	XMLSuite xml;
	xml.setDocument(_pDoc);
	
	Chain xmlChain;
	xml.getXMLChain(xmlChain);
	
	File xmlFile(_xmlDef);
	
	xmlFile.open(File::WRITE);
	
	xmlFile.writeChain(xmlChain);
	if ( __fsyncOn )
	    xmlFile.flush();
	xmlFile.close();

	t.stop();      	

	log(_modId, Logger::NOTICE, Chain("Database xml file written in ") + t.getUsed() + Chain(" sec"));
    }
    catch ( Exception e )
    {
	V();
	throw Exception(EXLOC, Chain("Cannot write file ") + _xmlDef, e);
    }
    V();
}

unsigned long long CegoXMLSpace::getTID(const Chain& tableSet)
{
    P();
    Element *pE = getTableSetElement(tableSet);
    unsigned long long tid = pE->getAttributeValue(XML_TID_ATTR).asUnsignedLongLong();
    V();
    return tid;
}

bool CegoXMLSpace::tableSetExists(const Chain& tableSet)
{
    P();
    Element *pE = getTableSetElement(tableSet);
    V();
    if ( pE )
	return true;
    return false;
}

unsigned long long CegoXMLSpace::getTSSortAreaSize(unsigned tabSetId)
{
    Element *pE = getCachedTableSetElement(tabSetId);

    if ( pE == 0 )
    {
	Chain msg = Chain("Unknown tableset id ") + Chain(tabSetId); 
	throw Exception(EXLOC, msg);
    }

    P();
    unsigned long long sortAreaSize = pE->getAttributeValue(XML_SORTAREASIZE_ATTR).asUnsignedLongLong();
    V();
    return sortAreaSize;
}

unsigned long long CegoXMLSpace::nextTID(unsigned tabSetId)
{
    Element *pE = getCachedTableSetElement(tabSetId);

    if ( pE == 0 )
    {
	Chain msg = Chain("Unknown tableset id ") + Chain(tabSetId); 
	throw Exception(EXLOC, msg);
    }
   
    P();
    unsigned long long tid = pE->getAttributeValue(XML_TID_ATTR).asUnsignedLongLong();
    tid++;
    pE->setAttribute(XML_TID_ATTR, Chain(tid));
    V();
    return tid;
}

unsigned CegoXMLSpace::nextFID()
{
    P();

    Element *pRoot = _pDoc->getRootElement();

    SetT<unsigned> fidSet;
    
    ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
    Element **pTSE = tabSetList.First();
    while ( pTSE ) 
    {
	unsigned tmpFid = (*pTSE)->getAttributeValue(XML_TMPFID_ATTR).asUnsigned();  
	fidSet.Insert(tmpFid);
	
	ListT<Element*> fileList = (*pTSE)->getChildren(XML_DATAFILE_ELEMENT);
	Element **pFile = fileList.First();
	while ( pFile )
	{
	    unsigned appFid = (*pFile)->getAttributeValue(XML_FILEID_ATTR).asUnsigned();
	    fidSet.Insert(appFid);	    
	    pFile = fileList.Next();
	}

	pTSE = tabSetList.Next();
    }

    V();
    
    unsigned nextFid = TABMNG_MAXTABSET + 1; // values <= MAXTABSET are reserved for system files

    while ( nextFid < FILMNG_MAXDATAFILE )
    {
	if ( fidSet.Find(nextFid) )
	    nextFid++;
	else
	    return nextFid;
    }

    throw Exception(EXLOC, Chain("File Id exceeded"));    
}

unsigned CegoXMLSpace::nextTSID()
{
    P();


    Element *pRoot = _pDoc->getRootElement();

    SetT<unsigned> idSet;
    
    ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
    Element **pTSE = tabSetList.First();
    while ( pTSE ) 
    {
	unsigned tsId = (*pTSE)->getAttributeValue(XML_TSID_ATTR).asUnsigned();  
	idSet.Insert(tsId);
	
	pTSE = tabSetList.Next();
    }

    V();
    
    unsigned nextId = 1;

    while ( nextId < TABMNG_MAXTABSET )
    {
	if ( idSet.Find(nextId) )
	    nextId++;
	else
	    return nextId;
    }

    throw Exception(EXLOC, Chain("Tableset Id exceeded"));    
}


void CegoXMLSpace::setCommittedLSN(unsigned tabSetId, unsigned long long lsn)
{   
    Element *pTS = getCachedTableSetElement(tabSetId);

    if ( pTS == 0)
    {
	Chain msg = "Unknown tableset id <" + Chain(tabSetId) + ">"; 
	throw Exception(EXLOC, msg);
    }   
    P();
    pTS->setAttribute(XML_LSN_ATTR, Chain(lsn));
    V();
}

void CegoXMLSpace::setCommittedLSN(const Chain& tableSet, unsigned long long lsn)
{  
    P();
    Element *pTS = getTableSetElement(tableSet);

    if ( pTS == 0)
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    
    pTS->setAttribute(XML_LSN_ATTR, Chain(lsn));
    V();
}

unsigned long long CegoXMLSpace::getCommittedLSN(const Chain& tableSet)
{
    unsigned long long lsn;

    P();
    Element *pTS = getTableSetElement(tableSet);
    if ( pTS )
    {
	lsn = pTS->getAttributeValue(XML_LSN_ATTR).asUnsignedLongLong() ;
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
    return lsn;
}

void CegoXMLSpace::getAllActiveTableSet(ListT<Chain>& tsList)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
	Element **pTSE = tabSetList.First();
	while ( pTSE ) 
	{
	    if ( (*pTSE)->getAttributeValue(XML_RUNSTATE_ATTR) 
		 == Chain(XML_ONLINE_VALUE) )
	    {
		tsList.Insert((*pTSE)->getAttributeValue(XML_NAME_ATTR));
	    }
	    pTSE = tabSetList.Next();
	}	
    }
    V();
}

void CegoXMLSpace::getActiveTableSet(ListT<Chain>& tsList, bool includeRecovery, bool includeOffline)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
	Element **pTSE = tabSetList.First();
	while ( pTSE ) 
	{
	    if (  (*pTSE)->getAttributeValue(XML_RUNSTATE_ATTR) == Chain(XML_ONLINE_VALUE)  
		  || (*pTSE)->getAttributeValue(XML_RUNSTATE_ATTR) == Chain(XML_BACKUP_VALUE)
		  || ( (*pTSE)->getAttributeValue(XML_RUNSTATE_ATTR) == Chain(XML_OFFLINE_VALUE) && includeOffline )
		  || ( (*pTSE)->getAttributeValue(XML_RUNSTATE_ATTR) == Chain(XML_RECOVERY_VALUE) && includeRecovery ) )
	    {
		tsList.Insert((*pTSE)->getAttributeValue(XML_NAME_ATTR));
	    }
	    pTSE = tabSetList.Next();
	}	
    }
    V();
}

ListT<unsigned> CegoXMLSpace::getOnlineTableSet() const
{
    ListT<unsigned> tsList;
    
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
	Element **pTSE = tabSetList.First();
	while ( pTSE ) 
	{	    
	    if ( (*pTSE)->getAttributeValue(XML_RUNSTATE_ATTR) == Chain(XML_ONLINE_VALUE)  
		      || (*pTSE)->getAttributeValue(XML_RUNSTATE_ATTR) == Chain(XML_BACKUP_VALUE))
	    {
		tsList.Insert((*pTSE)->getAttributeValue(XML_TSID_ATTR).asUnsigned());
	    }
	    pTSE = tabSetList.Next();
	}	
    }
    V();
    
    return tsList;
}

Chain CegoXMLSpace::getTableSetRunState(unsigned tabSetId)
{   
    Element *pTS = getCachedTableSetElement(tabSetId);

    if ( pTS == 0)
    {
	Chain msg = "Unknown tableset id <" + Chain(tabSetId) + ">"; 
	throw Exception(EXLOC, msg);
    }
    P();
    Chain runState = pTS->getAttributeValue(XML_RUNSTATE_ATTR);
    V();
    return runState;
}

void CegoXMLSpace::setTableSetRunState(unsigned tabSetId, const Chain& status)
{
    Element *pTS = getCachedTableSetElement(tabSetId);

    if ( pTS == 0)
    {
	Chain msg = "Unknown tableset id <" + Chain(tabSetId) + ">"; 
	throw Exception(EXLOC, msg);
    }    
    P();
    pTS->setAttribute(XML_RUNSTATE_ATTR, status);    
    V();
}

Chain CegoXMLSpace::getTableSetRunState(const Chain& tableSet)
{
    Chain status;

    P();
    Element *pTS = getTableSetElement(tableSet);
    if ( pTS )
    {
	status = pTS->getAttributeValue(XML_RUNSTATE_ATTR);
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
    return status;
}

void CegoXMLSpace::setTableSetRunState(const Chain& tableSet, const Chain& status)
{
    P();
    Element *pTS = getTableSetElement(tableSet);

    if ( pTS )
    {
	pTS->setAttribute(XML_RUNSTATE_ATTR, status);
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
}

void CegoXMLSpace::addDataFile(const Chain& tableSet, const Chain& type, unsigned fileId, const Chain& fileName, unsigned fileSize)
{
    P();
    Element *pTS = getTableSetElement(tableSet);

    if ( pTS )
    {
	Element *pDataFile = new Element(XML_DATAFILE_ELEMENT);
	pDataFile->setAttribute(XML_TYPE_ATTR, type);
	pDataFile->setAttribute(XML_FILEID_ATTR, Chain(fileId));
	pDataFile->setAttribute(XML_NAME_ATTR, fileName);
	pDataFile->setAttribute(XML_SIZE_ATTR, Chain(fileSize));
	pTS->addContent(pDataFile);
    }
    V();
}

void CegoXMLSpace::getDataFileInfo(const Chain& tableSet, ListT<Chain>& dfList)
{
    P();    
    Element *pTS = getTableSetElement(tableSet);   
    if ( pTS )
    {
	ListT<Element*> fileList = pTS->getChildren(XML_DATAFILE_ELEMENT);
	Element **pFile = fileList.First();
	while ( pFile )
	{
	    dfList.Insert( (*pFile)->getAttributeValue(XML_NAME_ATTR) );
	    pFile = fileList.Next();
	}
    }
    V();
}

void CegoXMLSpace::getDataFileInfo(const Chain& tableSet, const Chain& type, ListT<Chain>& dfList, ListT<unsigned>& fidList, ListT<unsigned>& sizeList)
{
    P();    
    Element *pTS = getTableSetElement(tableSet);   
    if ( pTS )
    {
	ListT<Element*> fileList = pTS->getChildren(XML_DATAFILE_ELEMENT);
	Element **pFile = fileList.First();
	while ( pFile )
	{
	    if ( (*pFile)->getAttributeValue(XML_TYPE_ATTR) == Chain(type) )
	    {
		dfList.Insert( (*pFile)->getAttributeValue(XML_NAME_ATTR) );
		fidList.Insert( (*pFile)->getAttributeValue(XML_FILEID_ATTR).asUnsigned());
		sizeList.Insert( (*pFile)->getAttributeValue(XML_SIZE_ATTR).asUnsigned());
	    }
	    pFile = fileList.Next();
	}
    }
    V();
}

void CegoXMLSpace::getLogFileInfo(const Chain& tableSet, ListT<Chain>& lfList, ListT<unsigned>& sizeList, ListT<Chain>& statusList)
{
    P();
    Element *pTS = getTableSetElement(tableSet);
    
    if ( pTS )
    {
	ListT<Element*> fileList = pTS->getChildren(XML_LOGFILE_ELEMENT);
	Element **pFile = fileList.First();
	while ( pFile )
	{
	   lfList.Insert( (*pFile)->getAttributeValue(XML_NAME_ATTR) );
	   sizeList.Insert( (*pFile)->getAttributeValue(XML_SIZE_ATTR).asUnsigned());
	   statusList.Insert( (*pFile)->getAttributeValue(XML_STATUS_ATTR) );
	   pFile = fileList.Next();
	}
    }
    V();
}

void CegoXMLSpace::setLogFileStatus(const Chain& tableSet, const Chain& logFile, const Chain& status)
{
    P();
    Element *pTS = getTableSetElement(tableSet);
    if ( pTS )
    {
	ListT<Element*> fileList = pTS->getChildren(XML_LOGFILE_ELEMENT);
	Element **pFile = fileList.First();
	while ( pFile )
	{
	    if ( (*pFile)->getAttributeValue(XML_NAME_ATTR) == logFile)
	    {
		(*pFile)->setAttribute(XML_STATUS_ATTR, status);
		V();
		return;
	    }	    
	    pFile = fileList.Next();
	}
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
}

void CegoXMLSpace::getXMLLockStat(Chain& lockName, unsigned& lockCount, unsigned long long &numRdLock, unsigned long long &numWrLock, unsigned long long &sumRdDelay, unsigned long long &sumWrDelay)
{
    lockName = xmlLock.getId();
    lockCount = xmlLock.numLockTry();
    numRdLock = xmlLock.numReadLock();
    numWrLock = xmlLock.numWriteLock();
    sumRdDelay = 0;
    sumWrDelay = 0;

    if ( xmlLock.numReadLock() > 0 )
	sumRdDelay = xmlLock.sumReadDelay() / LCKMNG_DELRES;
    if ( xmlLock.numWriteLock() > 0 )
	sumWrDelay = xmlLock.sumWriteDelay() / LCKMNG_DELRES;
}

void CegoXMLSpace::addCounter(unsigned tabSetId, const Chain& counterName, unsigned long long initValue, bool forceSet)
{
    Element *pTS = getCachedTableSetElement(tabSetId);

    if ( pTS == 0)
    {
	Chain msg = "Unknown tableset id <" + Chain(tabSetId) + ">"; 
	throw Exception(EXLOC, msg);
    }
    P();
    ListT<Element*> counterList = pTS->getChildren(XML_COUNTER_ELEMENT);
    Element **pCE = counterList.First();
    while ( pCE )
    {
	if ( (*pCE)->getAttributeValue(XML_NAME_ATTR) == counterName )
	{
	    if ( forceSet )
	    {
		(*pCE)->setAttribute(XML_VALUE_ATTR, Chain(initValue));
		V();
		return;
	    }
	    else
	    {		
		V();
		Chain msg = Chain("Counter ") + counterName + Chain(" already defined "); 
		throw Exception(EXLOC, msg);		
	    }
	}
	pCE = counterList.Next();
    } 
    
    Element *pNCE = new Element(XML_COUNTER_ELEMENT);
    pNCE->setAttribute(XML_NAME_ATTR, counterName);
    pNCE->setAttribute(XML_VALUE_ATTR, Chain(initValue));
    
    pTS->addContent(pNCE);
    V();
}

unsigned long long CegoXMLSpace::getCounterValue(unsigned tabSetId, const Chain& counterName, unsigned long long incValue)
{   
    Element *pTS = getCachedTableSetElement(tabSetId);

    if ( pTS == 0)
    {
	Chain msg = "Unknown tableset id <" + Chain(tabSetId) + ">"; 
	throw Exception(EXLOC, msg);
    }
    P();   
    ListT<Element*> counterList = pTS->getChildren(XML_COUNTER_ELEMENT);
    Element **pCE = counterList.First();
    while ( pCE )
    {
	if ( (*pCE)->getAttributeValue(XML_NAME_ATTR) == counterName )
	{	    
	    Chain counterVal = (*pCE)->getAttributeValue(XML_VALUE_ATTR);
	    
	    unsigned long long v = counterVal.asUnsignedLongLong();
	    
	    if ( incValue > 0 )
	    {
		v+=incValue;
		(*pCE)->setAttribute(XML_VALUE_ATTR, Chain(v));		
	    }
	    V();
	    return v;
	}
	pCE = counterList.Next();
    } 
    V();
    Chain msg = Chain("Unknown counter ") + counterName;
    throw Exception(EXLOC, msg);
}

unsigned long long CegoXMLSpace::setCounterValue(unsigned tabSetId, const Chain& counterName, unsigned long long value)
{
    Element *pTS = getCachedTableSetElement(tabSetId);

    if ( pTS == 0)
    {
	Chain msg = "Unknown tableset id <" + Chain(tabSetId) + ">"; 
	throw Exception(EXLOC, msg);
    }    
    P();    
    ListT<Element*> counterList = pTS->getChildren(XML_COUNTER_ELEMENT);
    Element **pCE = counterList.First();
    while ( pCE )
    {
	if ( (*pCE)->getAttributeValue(XML_NAME_ATTR) == counterName )
	{	    
	    Chain counterVal = (*pCE)->getAttributeValue(XML_VALUE_ATTR);   
	    unsigned long long v = counterVal.asUnsignedLongLong();
	    (*pCE)->setAttribute(XML_VALUE_ATTR, Chain(value));
	    
	    V();
	    return v;
	}
	pCE = counterList.Next();
    }     
    V();
    Chain msg = Chain("Unknown counter ") + counterName;
    throw Exception(EXLOC, msg);
}

void CegoXMLSpace::getCounterList(unsigned tabSetId, ListT<Chain>& counterNameList)
{
    Element *pTS = getCachedTableSetElement(tabSetId);

    if ( pTS == 0)
    {
	Chain msg = "Unknown tableset id <" + Chain(tabSetId) + ">"; 
	throw Exception(EXLOC, msg);
    }
    P();
    ListT<Element*> counterList = pTS->getChildren(XML_COUNTER_ELEMENT);
    Element **pCE = counterList.First();
    while ( pCE )
    {
	counterNameList.Insert(  (*pCE)->getAttributeValue(XML_NAME_ATTR));
	pCE = counterList.Next();
    } 
    V();
}

void CegoXMLSpace::removeCounter(unsigned tabSetId, const Chain& counterName)
{
    Element *pTS = getCachedTableSetElement(tabSetId);

    if ( pTS == 0)
    {
	Chain msg = "Unknown tableset id <" + Chain(tabSetId) + ">"; 
	throw Exception(EXLOC, msg);
    }
    P();
    ListT<Element*> counterList = pTS->getChildren(XML_COUNTER_ELEMENT);
    Element **pCE = counterList.First();
    while ( pCE )
    {
	if ( (*pCE)->getAttributeValue(XML_NAME_ATTR) == counterName )
	{
	    pTS->removeChild(*pCE);
	    V();
	    return;	    
	}
	pCE = counterList.Next();
    }
    V();
    Chain msg = Chain("Unknown counter ") + counterName; 
    throw Exception(EXLOC, msg);
}

void CegoXMLSpace::setCheckpointInterval(const Chain& tableSet, unsigned timeout)
{
    P();
    Element *pTS = getTableSetElement(tableSet);

    if ( pTS )
    {
	pTS->setAttribute(XML_CHECKPOINT_ATTR, Chain(timeout));
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
}

unsigned CegoXMLSpace::getCheckpointInterval(const Chain& tableSet)
{
    unsigned checkpoint;

    P();
    Element *pTS = getTableSetElement(tableSet);
    if ( pTS )
    {
	checkpoint = pTS->getAttributeValue(XML_CHECKPOINT_ATTR).asUnsigned();
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
    return checkpoint;
}

void CegoXMLSpace::setTSInitFile(const Chain& tableSet, const Chain& initFile)
{
    P();
    Element *pTS = getTableSetElement(tableSet);

    if ( pTS )
    {
	pTS->setAttribute(XML_TSINITFILE_ATTR, initFile);
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
}

Chain CegoXMLSpace::getTSInitFile(const Chain& tableSet)
{
    Chain initFile;

    P();
    Element *pTS = getTableSetElement(tableSet);
    if ( pTS )
    {
	initFile = pTS->getAttributeValue(XML_TSINITFILE_ATTR);
    }
    else
    {
	V();
	Chain msg = "Unknown tableset <" + tableSet + ">"; 
	throw Exception(EXLOC, msg);
    }
    V();
    return initFile;
}

bool CegoXMLSpace::getProcCacheEnabled(unsigned tabSetId)
{
    Element *pTS = getCachedTableSetElement(tabSetId);
    
    if ( pTS == 0)
    {
	Chain msg = "Unknown tableset id <" + Chain(tabSetId) + ">"; 
	throw Exception(EXLOC, msg);
    }
    
    P();
    Chain mode = pTS->getAttributeValue(XML_PROCCACHE_ATTR);
    V();

    if ( mode == Chain(XML_ON_VALUE) )
	return true;
    return false;
}

void CegoXMLSpace::setProcCacheEnabled(unsigned tabSetId, const bool isEnabled)
{
    Element *pTS = getCachedTableSetElement(tabSetId);

    if ( pTS == 0)
    {
	Chain msg = "Unknown tableset id <" + Chain(tabSetId) + ">"; 
	throw Exception(EXLOC, msg);
    }
    P();
    
    if ( isEnabled )
	pTS->setAttribute(XML_PROCCACHE_ATTR, XML_ON_VALUE);
    else
	pTS->setAttribute(XML_PROCCACHE_ATTR, XML_OFF_VALUE);
    
    V();
}

// private methods

void CegoXMLSpace::P() const
{    
    xmlLock.writeLock(XS_LOCKTIMEOUT);
}

void CegoXMLSpace::V() const
{
    xmlLock.unlock();
}

void CegoXMLSpace::getRoleSet(const Chain& user, SetT<Chain>& roleSet)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {	
	ListT<Element*> userList = pRoot->getChildren(XML_USER_ELEMENT);
	Element **pUE = userList.First();
	while ( pUE )
	{
	    if ( (*pUE)->getAttributeValue(XML_NAME_ATTR) == user )
	    {		
		Chain roleString = (*pUE)->getAttributeValue(XML_ROLE_ATTR);
		
		Tokenizer t(roleString, ",");
		Chain role;
		while ( t.nextToken(role) )
		{
		    roleSet.Insert(role);
		}
	    }
	    pUE = userList.Next();
	}
    }
    V();
}

bool CegoXMLSpace::matchRole(const Chain& role, const Chain tableSet, const Chain& objPattern, AccessMode perm)
{   
    // admin is allowed anyway
    if ( role == Chain(ROLE_ADMIN) )
	return true;

    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> roleElementList = pRoot->getChildren(XML_ROLE_ELEMENT);
	Element **pRE = roleElementList.First();
	while ( pRE ) 
	{
	    if ( (*pRE)->getAttributeValue(XML_NAME_ATTR) == role )
	    {
		ListT<Element*> permElementList = (*pRE)->getChildren(XML_PERM_ELEMENT);
		Element **pPE = permElementList.First();
		while ( pPE ) 
		{
		    Chain actTableSet = (*pPE)->getAttributeValue(XML_TABLESET_ATTR);
		    Chain filter = (*pPE)->getAttributeValue(XML_FILTER_ATTR);
		    Chain actPerm = (*pPE)->getAttributeValue(XML_PERM_ATTR);

		    if ( actTableSet == tableSet && fitsPerm(actPerm, perm) )
		    {
			if ( filter == Chain("ALL") )
			{
			    V();
			    return true;
			}
			else
			{
			    Matcher m(filter);			
			    m.prepare();
			    
			    if ( m.match(objPattern) )
			    {			    
				V();
				return true;
			    }
			}
		    }
		    pPE = permElementList.Next();
		}
	    }
	    pRE = roleElementList.Next();
	}
    }
    V();
    return false;
}

bool CegoXMLSpace::fitsPerm(const Chain& perm, AccessMode req)
{
    Chain uperm = perm.toUpper();

    if ( uperm == Chain("ALL") )
	return true;
    else if ( req == READ )
    {
	if ( uperm == Chain("READ") || uperm == Chain("WRITE") || uperm == Chain("MODIFY") )
	    return true;
	else
	    return false;
    }
    else if ( req == WRITE )
    {
	if ( uperm == Chain("WRITE") || uperm == Chain("MODIFY") )
	    return true;
	else
	    return false;	
    }
    else if ( req == MODIFY )
    {
	if ( uperm == Chain("MODIFY") )
	    return true;
	else
	    return false;	
    }
    else if ( req == EXEC )
    {
	if ( uperm == Chain("EXEC") )
	    return true;
	else
	    return false;	
    }

    return false;
}

Element* CegoXMLSpace::getTableSetElement(const Chain& tableSet) const
{  
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
	Element **pTSE = tabSetList.First();
	while ( pTSE ) 
	{	    
	    bool isEqual;
	    if ( __caseSensitiveFlag == 0 )
		isEqual = (*pTSE)->getAttributeValue(XML_NAME_ATTR) == tableSet;
	    else
		isEqual = (*pTSE)->getAttributeValue(XML_NAME_ATTR).toUpper() == tableSet.toUpper();
	    
	    if ( isEqual )
	    {
		return (*pTSE);
	    }
	    pTSE = tabSetList.Next();
	}	
    }
    return 0;
}

Element* CegoXMLSpace::getCachedTableSetElement(unsigned tabSetId)
{
    if ( _tsCache[tabSetId] != 0 )
	return _tsCache[tabSetId];
    
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot ) 
    {
	ListT<Element*> tabSetList = pRoot->getChildren(XML_TABLESET_ELEMENT);
	Element **pTSE = tabSetList.First();
	while ( pTSE ) 
	{
	    if ( (*pTSE)->getAttributeValue(XML_TSID_ATTR).asUnsigned() == tabSetId )
	    {
		_tsCache[tabSetId] = *pTSE;
		V();
		return (*pTSE);
	    }
	    pTSE = tabSetList.Next();
	}	
    }
    V();
    return 0;
}

bool CegoXMLSpace::getModuleList(ListT<Chain> &modList)
{
    bool isConfigured=false;

    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot )
    {
	ListT<Element*> modElementList = pRoot->getChildren(XML_MODULE_ELEMENT);
	Element **pMod = modElementList.First();
	while ( pMod ) 
	{
	    modList.Insert ( (*pMod)->getAttributeValue(XML_NAME_ATTR) );
	    pMod = modElementList.Next();	
	}
	isConfigured = true;
    }
    else
    {
	isConfigured = false;
    }
	
    V();

    return isConfigured;
}

Logger::LogLevel CegoXMLSpace::getLogLevel(const Chain& module)
{
    P();
    Element *pRoot = _pDoc->getRootElement();
    if ( pRoot )
    {
	ListT<Element*> modElementList = pRoot->getChildren(XML_MODULE_ELEMENT);
	Element **pMod = modElementList.First();
	while  ( pMod ) 
	{
	    if ( (*pMod)->getAttributeValue(XML_NAME_ATTR) == module )
	    {
		Logger::LogLevel logLevel = Logger::NONE;
		
		Chain levelString = (*pMod)->getAttributeValue(XML_LEVEL_ATTR);
		
		if ( levelString == Chain(XML_NOTICE_VALUE) )
		    logLevel = Logger::NOTICE;
		else if ( levelString == Chain(XML_LOGERR_VALUE) )
		    logLevel = Logger::LOGERR;
		else if ( levelString == Chain(XML_DEBUG_VALUE) )
		    logLevel = Logger::DEBUG;
		else if ( levelString == Chain(XML_NONE_VALUE) )
		    logLevel = Logger::NONE;
		
		V();
		
		return logLevel;
	    }
	    pMod = modElementList.Next();
	}
    }
    V();
    return Logger::NONE;
}

Chain CegoXMLSpace::getSysFileName(const Chain& tableSet)
{
    Chain sysFileName;

    P();

    Element *pTSE = getTableSetElement(tableSet);
    if ( pTSE )
    {
	sysFileName = pTSE->getAttributeValue(XML_SYSNAME_ATTR);  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tableSet; 
	throw Exception(EXLOC, msg);
    }
    V();
    return sysFileName;   
}

Chain CegoXMLSpace::getTmpFileName(const Chain& tableSet)
{
    Chain tmpFileName;

    P();

    Element *pTSE = getTableSetElement(tableSet);
    if ( pTSE )
    {
	tmpFileName = pTSE->getAttributeValue(XML_TMPNAME_ATTR);  
    }
    else
    {
	V();
	Chain msg = Chain("Unknown tableset name ") + tableSet; 
	throw Exception(EXLOC, msg);
    }
    V();
    return tmpFileName;
}

void CegoXMLSpace::verifyXMLLock(CegoAdminHandler* pAH)
{
    unsigned timeout = 3000;
    
    Chain info;

    info = Chain("XML Lock - Read ...");
    if ( pAH )
	pAH->sendInfo(info);
	
    xmlLock.readLock(timeout);
    xmlLock.unlock();

    if ( pAH )
	pAH->sendInfo(Chain("ok\n"));

    info = Chain("XML Lock - Write ...");
    if ( pAH )
	pAH->sendInfo(info);
    
    xmlLock.writeLock(timeout);
    xmlLock.unlock();
    
    if ( pAH )
	pAH->sendInfo(Chain("ok\n"));

}
