1 #include "otsdaq/ConfigurationInterface/ConfigurationHandler.h"
2 #include "otsdaq/ConfigurationInterface/TimeFormatter.h"
4 #include "otsdaq/Macros/CoutMacros.h"
5 #include "otsdaq/XmlUtilities/ConvertFromXML.h"
6 #include "otsdaq/XmlUtilities/ConvertToXML.h"
7 #include "otsdaq/XmlUtilities/DOMTreeErrorReporter.h"
9 #include <xercesc/dom/DOMElement.hpp>
10 #include <xercesc/dom/DOMImplementation.hpp>
11 #include <xercesc/dom/DOMImplementationRegistry.hpp>
12 #include <xercesc/dom/DOMLSOutput.hpp>
13 #include <xercesc/dom/DOMLSSerializer.hpp>
14 #include <xercesc/dom/DOMNodeList.hpp>
15 #include <xercesc/dom/DOMText.hpp>
16 #include <xercesc/parsers/XercesDOMParser.hpp>
17 #include <xercesc/util/XMLUni.hpp>
20 #include <xercesc/framework/LocalFileFormatTarget.hpp>
21 #include <xercesc/util/OutOfMemoryException.hpp>
23 #include <sys/types.h>
31 #include "otsdaq/TableCore/TableBase.h"
36 #define __COUT_HDR__ "ConfigHandler"
40 XMLCh* ConfigurationHandler::rootTag_ = 0;
41 XMLCh* ConfigurationHandler::headerTag_ = 0;
42 XMLCh* ConfigurationHandler::typeTag_ = 0;
43 XMLCh* ConfigurationHandler::extensionTableNameTag_ = 0;
44 XMLCh* ConfigurationHandler::nameTag_ = 0;
45 XMLCh* ConfigurationHandler::runTag_ = 0;
46 XMLCh* ConfigurationHandler::runTypeTag_ = 0;
47 XMLCh* ConfigurationHandler::runNumberTag_ = 0;
48 XMLCh* ConfigurationHandler::runBeginTimestampTag_ = 0;
49 XMLCh* ConfigurationHandler::locationTag_ = 0;
50 XMLCh* ConfigurationHandler::datasetTag_ = 0;
51 XMLCh* ConfigurationHandler::versionTag_ = 0;
52 XMLCh* ConfigurationHandler::commentDescriptionTag_ = 0;
53 XMLCh* ConfigurationHandler::createdByUserTag_ = 0;
54 XMLCh* ConfigurationHandler::partTag_ = 0;
55 XMLCh* ConfigurationHandler::nameLabelTag_ = 0;
56 XMLCh* ConfigurationHandler::kindOfPartTag_ = 0;
57 XMLCh* ConfigurationHandler::dataTag_ = 0;
60 ConfigurationHandler::ConfigurationHandler(
void) {}
63 ConfigurationHandler::~ConfigurationHandler(
void) {}
66 void ConfigurationHandler::initPlatform(
void)
70 xercesc::XMLPlatformUtils::Initialize();
72 catch(xercesc::XMLException& e)
74 __COUT_ERR__ <<
"XML toolkit initialization error: "
75 << XML_TO_CHAR(e.getMessage()) << std::endl;
79 rootTag_ = xercesc::XMLString::transcode(
"ROOT");
80 headerTag_ = xercesc::XMLString::transcode(
"HEADER");
81 typeTag_ = xercesc::XMLString::transcode(
"TYPE");
82 extensionTableNameTag_ = xercesc::XMLString::transcode(
"EXTENSION_TABLE_NAME");
83 nameTag_ = xercesc::XMLString::transcode(
"NAME");
84 runTag_ = xercesc::XMLString::transcode(
"RUN");
85 runTypeTag_ = xercesc::XMLString::transcode(
"RUN_TYPE");
86 runNumberTag_ = xercesc::XMLString::transcode(
"RUN_NUMBER");
87 runBeginTimestampTag_ = xercesc::XMLString::transcode(
"RUN_BEGIN_TIMESTAMP");
88 locationTag_ = xercesc::XMLString::transcode(
"LOCATION");
89 datasetTag_ = xercesc::XMLString::transcode(
"DATA_SET");
90 versionTag_ = xercesc::XMLString::transcode(
"VERSION");
91 commentDescriptionTag_ = xercesc::XMLString::transcode(
"COMMENT_DESCRIPTION");
92 createdByUserTag_ = xercesc::XMLString::transcode(
"CREATED_BY_USER");
93 partTag_ = xercesc::XMLString::transcode(
"PART");
94 nameLabelTag_ = xercesc::XMLString::transcode(
"NAME_LABEL");
95 kindOfPartTag_ = xercesc::XMLString::transcode(
"KIND_OF_PART");
96 dataTag_ = xercesc::XMLString::transcode(
"DATA");
100 void ConfigurationHandler::terminatePlatform(
void)
104 xercesc::XMLString::release(&rootTag_);
105 xercesc::XMLString::release(&headerTag_);
106 xercesc::XMLString::release(&typeTag_);
107 xercesc::XMLString::release(&extensionTableNameTag_);
108 xercesc::XMLString::release(&nameTag_);
109 xercesc::XMLString::release(&runTag_);
110 xercesc::XMLString::release(&runTypeTag_);
111 xercesc::XMLString::release(&runNumberTag_);
112 xercesc::XMLString::release(&runBeginTimestampTag_);
113 xercesc::XMLString::release(&locationTag_);
114 xercesc::XMLString::release(&datasetTag_);
115 xercesc::XMLString::release(&versionTag_);
116 xercesc::XMLString::release(&commentDescriptionTag_);
117 xercesc::XMLString::release(&createdByUserTag_);
118 xercesc::XMLString::release(&partTag_);
119 xercesc::XMLString::release(&nameLabelTag_);
120 xercesc::XMLString::release(&kindOfPartTag_);
121 xercesc::XMLString::release(&dataTag_);
125 __COUT_ERR__ <<
"Unknown exception encountered in TagNames destructor"
131 xercesc::XMLPlatformUtils::Terminate();
133 catch(xercesc::XMLException& e)
135 __COUT_ERR__ <<
"XML ttolkit teardown error: " << XML_TO_CHAR(e.getMessage())
141 bool ConfigurationHandler::validateNode(XMLCh* tagName,
142 xercesc::DOMNode* node,
143 const std::string& expectedValue)
145 if(node->getFirstChild() == 0)
147 __COUT__ <<
"Tag " << XML_TO_CHAR(tagName) <<
" doesn't have a value!"
152 if(XML_TO_STRING(node->getFirstChild()->getNodeValue()) != expectedValue)
154 __COUT__ <<
"The tag " << XML_TO_CHAR(tagName) <<
" with value "
155 << XML_TO_CHAR(node->getFirstChild()->getNodeValue())
156 <<
" doesn't match the expected value " << expectedValue << std::endl;
164 xercesc::DOMNode* ConfigurationHandler::getNode(XMLCh* tagName,
165 xercesc::DOMNode* parent,
166 unsigned int itemNumber)
168 return getNode(tagName,
dynamic_cast<xercesc::DOMElement*
>(parent), itemNumber);
172 xercesc::DOMNode* ConfigurationHandler::getNode(XMLCh* tagName,
173 xercesc::DOMElement* parent,
174 unsigned int itemNumber)
176 xercesc::DOMNodeList* nodeList = parent->getElementsByTagName(tagName);
180 throw(std::runtime_error(std::string(
"Can't find ") + XML_TO_STRING(tagName) +
182 __COUT__ << (std::string(
"Can't find ") + XML_TO_STRING(tagName) +
" tag!")
191 return nodeList->item(itemNumber);
195 xercesc::DOMElement* ConfigurationHandler::getElement(XMLCh* tagName,
196 xercesc::DOMNode* parent,
197 unsigned int itemNumber)
199 return dynamic_cast<xercesc::DOMElement*
>(getNode(tagName, parent, itemNumber));
203 xercesc::DOMElement* ConfigurationHandler::getElement(XMLCh* tagName,
204 xercesc::DOMElement* parent,
205 unsigned int itemNumber)
207 return dynamic_cast<xercesc::DOMElement*
>(getNode(tagName, parent, itemNumber));
213 readXML(*table, version);
220 std::string configFile = getXMLFileName(table, version);
222 __COUT__ <<
"Reading: " << configFile << std::endl;
223 __COUT__ <<
"Into View with Table Name: " << table.getViewP()->getTableName()
225 __COUT__ <<
"Into View with version: " << table.getViewP()->getVersion()
226 <<
" and version-to-read: " << version << std::endl;
228 struct stat fileStatus;
230 if(stat(configFile.c_str(), &fileStatus) < 0)
232 __COUT__ <<
"Error reading path: " << configFile << std::endl;
233 std::stringstream ss;
236 ss << (
"Path file_name does not exist.");
237 else if(errno == ENOTDIR)
238 ss << (
"A component of the path is not a directory.");
239 else if(errno == ELOOP)
240 ss << (
"Too many symbolic links encountered while traversing the path.");
241 else if(errno == EACCES)
242 ss << (
"Permission denied.");
243 else if(errno == ENAMETOOLONG)
244 ss << (
"File name too long.");
246 ss << (
"File can not be read.");
248 __COUT_ERR__ << ss.str();
252 xercesc::XercesDOMParser* parser =
new xercesc::XercesDOMParser;
255 parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto);
256 parser->setDoNamespaces(
true);
261 parser->useCachedGrammarInParse(
false);
263 parser->setErrorHandler(errorHandler);
269 parser->parse(configFile.c_str());
273 xercesc::DOMDocument* document = parser->getDocument();
276 xercesc::DOMElement* elementRoot = document->getDocumentElement();
279 throw(std::runtime_error(
"empty XML document"));
282 xercesc::DOMNode* headerNode = getNode(headerTag_, elementRoot, 0);
284 throw(std::runtime_error(
285 std::string(
"The document is missing the mandatory tag: ") +
286 XML_TO_STRING(headerTag_)));
290 xercesc::DOMElement* typeElement = getElement(typeTag_, headerNode, 0);
292 throw(std::runtime_error(
293 std::string(
"The document is missing the mandatory tag: ") +
294 XML_TO_STRING(typeTag_)));
295 xercesc::DOMNode* extensionTableNameNode =
296 getNode(extensionTableNameTag_, typeElement, 0);
297 if(!validateNode(extensionTableNameTag_,
298 extensionTableNameNode,
299 table.getView().getTableName()))
300 throw(std::runtime_error(
301 std::string(
"The document is missing the mandatory tag: ") +
302 XML_TO_STRING(extensionTableNameTag_)));
303 xercesc::DOMNode* nameNode = getNode(nameTag_, typeElement, 0);
304 if(!validateNode(nameTag_, nameNode, table.
getTableName()))
305 throw(std::runtime_error(
306 std::string(
"The document is missing the mandatory tag: ") +
307 XML_TO_STRING(nameTag_)));
313 xercesc::DOMElement* runElement = getElement(runTag_, headerNode, 0);
315 throw(std::runtime_error(
316 std::string(
"The document is missing the mandatory tag: ") +
317 XML_TO_STRING(runTag_)));
318 [[maybe_unused]] xercesc::DOMNode* runTypeNode =
319 getNode(runTypeTag_, runElement, 0);
320 assert(validateNode(runTypeTag_, runTypeNode, table.
getTableName()));
321 xercesc::DOMNode* runNumberNode = getNode(runNumberTag_, runElement, 0);
323 throw(std::runtime_error(
324 std::string(
"The document is missing the mandatory tag: ") +
325 XML_TO_STRING(runNumberTag_)));
326 xercesc::DOMNode* runBeginTimestampNode =
327 getNode(runBeginTimestampTag_, runElement, 0);
328 if(!runBeginTimestampNode)
329 throw(std::runtime_error(
330 std::string(
"The document is missing the mandatory tag: ") +
331 XML_TO_STRING(runBeginTimestampTag_)));
332 xercesc::DOMNode* locationNode = getNode(locationTag_, runElement, 0);
334 throw(std::runtime_error(
335 std::string(
"The document is missing the mandatory tag: ") +
336 XML_TO_STRING(locationTag_)));
344 xercesc::DOMElement* datasetElement = getElement(datasetTag_, elementRoot, 0);
346 throw(std::runtime_error(
347 std::string(
"The document is missing the mandatory tag: ") +
348 XML_TO_STRING(datasetTag_)));
357 xercesc::DOMNode* versionNode = getNode(versionTag_, datasetElement, 0);
359 if(versionNode->getFirstChild() == 0)
361 throw(std::runtime_error(
362 std::string(
"Missing version tag: ") +
363 XML_TO_CHAR(versionNode->getFirstChild()->getNodeValue())));
367 char tmpVersionStr[100];
368 sprintf(tmpVersionStr,
"%d", version.
version());
369 __COUT__ << version <<
"-"
370 << XML_TO_CHAR(versionNode->getFirstChild()->getNodeValue())
372 if(strcmp(tmpVersionStr,
373 XML_TO_CHAR(versionNode->getFirstChild()->getNodeValue())) != 0)
374 throw(std::runtime_error(
375 std::string(
"Mis-matched version tag: ") +
376 XML_TO_CHAR(versionNode->getFirstChild()->getNodeValue()) +
" vs " +
381 XML_TO_CHAR(versionNode->getFirstChild()->getNodeValue()));
383 xercesc::DOMNode* commentDescriptionNode =
384 getNode(commentDescriptionTag_, datasetElement, 0);
385 if(commentDescriptionNode->getFirstChild() != 0)
386 table.getViewP()->setComment(
387 XML_TO_CHAR(commentDescriptionNode->getFirstChild()->getNodeValue()));
389 xercesc::DOMNode* createdByUserNode =
390 getNode(createdByUserTag_, datasetElement, 0);
391 if(createdByUserNode->getFirstChild() != 0)
392 table.getViewP()->setAuthor(
393 XML_TO_CHAR(createdByUserNode->getFirstChild()->getNodeValue()));
397 xercesc::DOMNodeList* dataNodeList =
398 datasetElement->getElementsByTagName(dataTag_);
401 throw(std::runtime_error(std::string(
"Can't find ") +
402 XML_TO_STRING(dataTag_) +
" tag!"));
408 if(!dataNodeList->getLength())
410 __SS__ <<
"Must be non-empty data set!";
417 table.getViewP()->resizeDataView(dataNodeList->getLength(),
418 table.getView().getNumberOfColumns());
420 for(XMLSize_t row = 0; row < dataNodeList->getLength(); row++)
424 xercesc::DOMNodeList* columnNodeList =
425 dataNodeList->item(row)->getChildNodes();
426 unsigned int colNumber = 0;
430 for(XMLSize_t col = 0; col < columnNodeList->getLength(); col++)
434 if(!columnNodeList->item(col)->getNodeType() ||
435 columnNodeList->item(col)->getNodeType() !=
436 xercesc::DOMNode::ELEMENT_NODE)
439 xercesc::DOMElement* columnElement =
440 dynamic_cast<xercesc::DOMElement*
>(columnNodeList->item(col));
442 if(table.getView().getColumnInfo(colNumber).getStorageName() !=
443 XML_TO_STRING(columnElement->getTagName()))
445 std::stringstream error;
446 error << __COUT_HDR__ << std::endl
447 <<
"The column number " << colNumber <<
" named "
448 << table.getView().getColumnInfo(colNumber).getStorageName()
449 <<
" defined in the view " << table.getView().getTableName()
450 <<
" doesn't match the file column order, since the "
454 : (colNumber == 1 ?
"nd"
455 : (colNumber == 2 ?
"rd" :
"th")))
456 <<
" element found in the file at " << XML_TO_CHAR(dataTag_)
457 <<
" tag number " << row <<
" is "
458 << XML_TO_CHAR(columnElement->getTagName());
459 __COUT_ERR__ << error.str();
460 throw(std::runtime_error(error.str()));
472 columnNodeList->item(col)->getFirstChild()->getNodeValue()),
481 catch(xercesc::XMLException& e)
483 __COUT__ <<
"Error parsing file: " << configFile << std::endl;
484 std::ostringstream errBuf;
485 errBuf <<
"Error parsing file: " << XML_TO_CHAR(e.getMessage()) << std::flush;
488 __COUT__ <<
"Done with table file: " << configFile << std::endl;
500 std::string configFile = getXMLFileName(
505 xercesc::DOMImplementation* implementation =
506 xercesc::DOMImplementationRegistry::getDOMImplementation(CONVERT_TO_XML(
"Core"));
507 if(implementation != 0)
512 xercesc::DOMDocument* document =
513 implementation->createDocument(0,
517 xercesc::DOMElement* rootElement = document->getDocumentElement();
518 rootElement->setAttribute(
519 CONVERT_TO_XML(
"xmlns:xsi"),
520 CONVERT_TO_XML(
"http://www.w3.org/2001/XMLSchema-instance"));
521 rootElement->setAttribute(
522 CONVERT_TO_XML(
"xsi:noNamespaceSchemaLocation"),
530 xercesc::DOMElement* headerElement = document->createElement(headerTag_);
531 rootElement->appendChild(headerElement);
534 xercesc::DOMElement* typeElement = document->createElement(typeTag_);
535 headerElement->appendChild(typeElement);
537 xercesc::DOMElement* extensionTableNameElement =
538 document->createElement(extensionTableNameTag_);
539 typeElement->appendChild(extensionTableNameElement);
540 xercesc::DOMText* extensionTableNameValue = document->createTextNode(
541 CONVERT_TO_XML(table.getView().getTableName().c_str()));
542 extensionTableNameElement->appendChild(extensionTableNameValue);
544 xercesc::DOMElement* nameElement = document->createElement(nameTag_);
545 typeElement->appendChild(nameElement);
546 xercesc::DOMText* nameValue =
547 document->createTextNode(CONVERT_TO_XML(table.
getTableName().c_str()));
548 nameElement->appendChild(nameValue);
552 xercesc::DOMElement* runElement = document->createElement(runTag_);
553 headerElement->appendChild(runElement);
555 xercesc::DOMElement* runTypeElement = document->createElement(runTypeTag_);
556 runElement->appendChild(runTypeElement);
557 xercesc::DOMText* runTypeValue =
558 document->createTextNode(CONVERT_TO_XML(table.
getTableName().c_str()));
559 runTypeElement->appendChild(runTypeValue);
561 xercesc::DOMElement* runNumberElement =
562 document->createElement(runNumberTag_);
563 runElement->appendChild(runNumberElement);
564 xercesc::DOMText* runNumberValue = document->createTextNode(CONVERT_TO_XML(
566 runNumberElement->appendChild(runNumberValue);
568 xercesc::DOMElement* runBeginTimestampElement =
569 document->createElement(runBeginTimestampTag_);
570 runElement->appendChild(runBeginTimestampElement);
571 xercesc::DOMText* runBeginTimestampValue = document->createTextNode(
576 runBeginTimestampElement->appendChild(runBeginTimestampValue);
578 xercesc::DOMElement* locationElement = document->createElement(locationTag_);
579 runElement->appendChild(locationElement);
580 xercesc::DOMText* locationValue = document->createTextNode(
581 CONVERT_TO_XML(
"CERN P5"));
583 locationElement->appendChild(locationValue);
586 xercesc::DOMElement* datasetElement = document->createElement(datasetTag_);
587 rootElement->appendChild(datasetElement);
589 xercesc::DOMElement* partElement = document->createElement(partTag_);
590 datasetElement->appendChild(partElement);
592 xercesc::DOMElement* nameLabelElement =
593 document->createElement(nameLabelTag_);
594 partElement->appendChild(nameLabelElement);
595 xercesc::DOMText* nameLabelValue =
596 document->createTextNode(CONVERT_TO_XML(
"CMS--ROOT"));
597 nameLabelElement->appendChild(nameLabelValue);
599 xercesc::DOMElement* kindOfPartElement =
600 document->createElement(kindOfPartTag_);
601 partElement->appendChild(kindOfPartElement);
602 xercesc::DOMText* kindOfPartValue =
603 document->createTextNode(CONVERT_TO_XML(
"Detector ROOT"));
604 kindOfPartElement->appendChild(kindOfPartValue);
606 xercesc::DOMElement* versionElement = document->createElement(versionTag_);
607 datasetElement->appendChild(versionElement);
608 xercesc::DOMText* versionValue = document->createTextNode(
609 CONVERT_TO_XML(table.getView().getVersion().
version()));
610 versionElement->appendChild(versionValue);
612 xercesc::DOMElement* commentDescriptionElement =
613 document->createElement(commentDescriptionTag_);
614 datasetElement->appendChild(commentDescriptionElement);
615 xercesc::DOMText* commentDescriptionValue = document->createTextNode(
616 CONVERT_TO_XML(table.getView().getComment().c_str()));
617 commentDescriptionElement->appendChild(commentDescriptionValue);
619 xercesc::DOMElement* createdByUserElement =
620 document->createElement(createdByUserTag_);
621 datasetElement->appendChild(createdByUserElement);
622 xercesc::DOMText* createdByUserValue = document->createTextNode(
623 CONVERT_TO_XML(table.getView().getAuthor().c_str()));
624 createdByUserElement->appendChild(createdByUserValue);
628 for(
unsigned int row = 0; row < table.getView().getNumberOfRows(); row++)
630 xercesc::DOMElement* dataElement = document->createElement(dataTag_);
631 datasetElement->appendChild(dataElement);
633 for(
unsigned int col = 0; col < table.getView().getNumberOfColumns();
636 xercesc::DOMElement* element = document->createElement(CONVERT_TO_XML(
637 table.getView().getColumnInfo(col).getStorageName().c_str()));
638 dataElement->appendChild(element);
639 xercesc::DOMText* value = document->createTextNode(
640 CONVERT_TO_XML(table.getView().getDataView()[row][col].c_str()));
641 element->appendChild(value);
645 outputXML(document, configFile);
649 catch(
const xercesc::OutOfMemoryException&)
651 XERCES_STD_QUALIFIER cerr <<
"OutOfMemoryException"
652 << XERCES_STD_QUALIFIER endl;
655 catch(
const xercesc::DOMException& e)
657 XERCES_STD_QUALIFIER cerr <<
"DOMException code is: " << e.code
658 << XERCES_STD_QUALIFIER endl;
661 catch(
const xercesc::XMLException& e)
663 std::string message = XML_TO_STRING(e.getMessage());
664 __COUT__ <<
"Error Message: " << message << std::endl;
670 XERCES_STD_QUALIFIER cerr <<
"An error occurred creating the document"
671 << XERCES_STD_QUALIFIER endl;
677 XERCES_STD_QUALIFIER cerr <<
"Requested implementation is not supported"
678 << XERCES_STD_QUALIFIER endl;
689 void ConfigurationHandler::outputXML(xercesc::DOMDocument* pmyDOMDocument,
690 std::string fileName)
692 std::string directory = fileName.substr(0, fileName.rfind(
"/") + 1);
693 __COUT__ <<
"Saving XML to " << fileName <<
" in directory: " << directory
696 mkdir(directory.c_str(), 0755);
702 xercesc::DOMImplementation* implementation =
703 xercesc::DOMImplementationRegistry::getDOMImplementation(CONVERT_TO_XML(
"LS"));
705 #if _XERCES_VERSION >= 30000
708 xercesc::DOMLSSerializer* serializer =
709 ((xercesc::DOMImplementationLS*)implementation)->createLSSerializer();
713 if(serializer->getDomConfig()->canSetParameter(
714 xercesc::XMLUni::fgDOMWRTFormatPrettyPrint,
true))
715 serializer->getDomConfig()->setParameter(
716 xercesc::XMLUni::fgDOMWRTFormatPrettyPrint,
true);
724 xercesc::XMLFormatTarget* formatTarget =
725 new xercesc::LocalFileFormatTarget(CONVERT_TO_XML(fileName));
728 xercesc::DOMLSOutput* output =
729 ((xercesc::DOMImplementationLS*)implementation)->createLSOutput();
732 output->setByteStream(formatTarget);
735 serializer->write(pmyDOMDocument, output);
738 xercesc::DOMWriter* serializer =
739 ((xercesc::DOMImplementationLS*)implementation)->createDOMWriter();
741 serializer->setFeature(xercesc::XMLUni::fgDOMWRTFormatPrettyPrint,
true);
753 xercesc::XMLFormatTarget* formatTarget =
754 new xercesc::LocalFileFormatTarget(CONVERT_TO_XML(fileName.c_str()));
757 serializer->writeNode(formatTarget, *pmyDOMDocument);
762 serializer->release();
766 #if _XERCES_VERSION >= 30000
771 __COUT__ <<
"Done writing " << std::endl;
781 std::string ConfigurationHandler::getXMLFileName(
const TableBase& table,
784 std::stringstream fileName;
786 << version <<
".xml";
787 return fileName.str();
793 return std::string(__ENV__(
"CONFIGURATION_DATA_PATH")) +
'/' + table->
getTableName() +
static std::string writeXML(const TableBase &configuration)
returns the file name
static std::string getXMLDir(const TableBase *configuration)
const std::string & getTableName(void) const
Getters.
const TableVersion & getViewVersion(void) const
always the active one
unsigned int version(void) const
void setValueAsString(const std::string &value, unsigned int row, unsigned int col)
void setVersion(const T &version)
< in included .icc source