1 #include "otsdaq/TableCore/TableInfoReader.h"
3 #include "otsdaq/Macros/StringMacros.h"
4 #include "otsdaq/XmlUtilities/ConvertFromXML.h"
5 #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/DOMNodeList.hpp>
13 #include <xercesc/dom/DOMText.hpp>
14 #include <xercesc/parsers/XercesDOMParser.hpp>
17 #include <xercesc/framework/LocalFileFormatTarget.hpp>
18 #include <xercesc/util/OutOfMemoryException.hpp>
27 #include "otsdaq/TableCore/TableBase.h"
32 #define __COUT_HDR__ "TableInfoReader <>"
36 #define CONFIGURATION_BACKEND_TYPE_ __ENV__("CONFIGURATION_TYPE")
39 TableInfoReader::TableInfoReader(
bool allowIllegalColumns)
40 : allowIllegalColumns_(allowIllegalColumns)
43 rootTag_ = xercesc::XMLString::transcode(
"ROOT");
44 tableTag_ = xercesc::XMLString::transcode(
"TABLE");
45 tableNameAttributeTag_ = xercesc::XMLString::transcode(
"Name");
46 viewTag_ = xercesc::XMLString::transcode(
"VIEW");
47 viewNameAttributeTag_ = xercesc::XMLString::transcode(
"Name");
48 viewTypeAttributeTag_ = xercesc::XMLString::transcode(
"Type");
49 viewDescriptionAttributeTag_ = xercesc::XMLString::transcode(
"Description");
50 columnTag_ = xercesc::XMLString::transcode(
"COLUMN");
51 columnTypeAttributeTag_ = xercesc::XMLString::transcode(
"Type");
52 columnNameAttributeTag_ = xercesc::XMLString::transcode(
"Name");
53 columnStorageNameAttributeTag_ = xercesc::XMLString::transcode(
"StorageName");
54 columnDataTypeAttributeTag_ = xercesc::XMLString::transcode(
"DataType");
55 columnDataChoicesAttributeTag_ = xercesc::XMLString::transcode(
"DataChoices");
56 columnDefaultValueAttributeTag_ = xercesc::XMLString::transcode(
"DefaultValue");
57 columnMinValueAttributeTag_ = xercesc::XMLString::transcode(
"MinValue");
58 columnMaxValueAttributeTag_ = xercesc::XMLString::transcode(
"MaxValue");
62 TableInfoReader::~TableInfoReader(
void)
66 xercesc::XMLString::release(&rootTag_);
67 xercesc::XMLString::release(&tableTag_);
68 xercesc::XMLString::release(&tableNameAttributeTag_);
69 xercesc::XMLString::release(&viewTag_);
70 xercesc::XMLString::release(&viewNameAttributeTag_);
71 xercesc::XMLString::release(&viewTypeAttributeTag_);
72 xercesc::XMLString::release(&viewDescriptionAttributeTag_);
73 xercesc::XMLString::release(&columnTag_);
74 xercesc::XMLString::release(&columnTypeAttributeTag_);
75 xercesc::XMLString::release(&columnNameAttributeTag_);
76 xercesc::XMLString::release(&columnStorageNameAttributeTag_);
77 xercesc::XMLString::release(&columnDataTypeAttributeTag_);
78 xercesc::XMLString::release(&columnDataChoicesAttributeTag_);
79 xercesc::XMLString::release(&columnDefaultValueAttributeTag_);
80 xercesc::XMLString::release(&columnMinValueAttributeTag_);
81 xercesc::XMLString::release(&columnMaxValueAttributeTag_);
85 __COUT_ERR__ <<
"Unknown exception encountered in TagNames destructor" << __E__;
91 void TableInfoReader::initPlatform(
void)
95 xercesc::XMLPlatformUtils::Initialize();
97 catch(xercesc::XMLException& e)
99 __COUT_ERR__ <<
"XML toolkit initialization error: "
100 << XML_TO_CHAR(e.getMessage()) << __E__;
106 void TableInfoReader::terminatePlatform(
void)
110 xercesc::XMLPlatformUtils::Terminate();
112 catch(xercesc::XMLException& e)
114 __COUT_ERR__ <<
"XML tolkit teardown error: " << XML_TO_CHAR(e.getMessage())
120 void TableInfoReader::setAllowColumnErrors(
bool setValue)
122 allowIllegalColumns_ = setValue;
125 const bool& TableInfoReader::getAllowColumnErrors(
void) {
return allowIllegalColumns_; }
128 bool TableInfoReader::checkViewType(std::string type)
130 std::vector<std::string> types;
131 int currentIndex = 0;
132 while(type.find(
',', currentIndex) != std::string::npos)
135 type.substr(currentIndex, type.find(
',', currentIndex) - currentIndex));
136 currentIndex = type.find(
',', currentIndex) + 1;
138 types.push_back(type.substr(currentIndex, type.size()));
140 const std::string systemType = CONFIGURATION_BACKEND_TYPE_;
142 for(
unsigned int i = 0; i < types.size(); i++)
144 if(types[i] == systemType)
149 const unsigned int allowedNamesSize = 3;
150 const std::string allowedNames[allowedNamesSize] = {
151 "File",
"Database",
"DatabaseTest"};
152 if(systemType != allowedNames[0] && systemType != allowedNames[1] &&
153 systemType != allowedNames[2])
155 __COUT__ <<
"The type defined in CONFIGURATION_BACKEND_TYPE (" << systemType
156 <<
") doesn't match with any of the allowed types: File,Database or "
160 throw(std::runtime_error(
"Illegal table type"));
162 for(
unsigned int i = 0; i < types.size(); i++)
164 if(types[i] != allowedNames[0] && types[i] != allowedNames[1] &&
165 types[i] != allowedNames[2])
167 __COUT__ <<
"The type defined in the info file (" << types[i]
168 <<
") doesn't match with any of the allowed types: "
169 << allowedNames[0] <<
", " << allowedNames[1] <<
" or "
170 << allowedNames[2] << __E__;
171 throw(std::runtime_error(
"Illegal Type!"));
179 xercesc::DOMNode* TableInfoReader::getNode(XMLCh* tagName,
180 xercesc::DOMNode* parent,
181 unsigned int itemNumber)
183 return getNode(tagName,
dynamic_cast<xercesc::DOMElement*
>(parent), itemNumber);
187 xercesc::DOMNode* TableInfoReader::getNode(XMLCh* tagName,
188 xercesc::DOMElement* parent,
189 unsigned int itemNumber)
191 xercesc::DOMNodeList* nodeList = parent->getElementsByTagName(tagName);
194 throw(std::runtime_error(std::string(
"Can't find ") + XML_TO_CHAR(tagName) +
196 __COUT__ << (std::string(
"Can't find ") + XML_TO_CHAR(tagName) +
" tag!")
204 return nodeList->item(itemNumber);
208 xercesc::DOMElement* TableInfoReader::getElement(XMLCh* tagName,
209 xercesc::DOMNode* parent,
210 unsigned int itemNumber)
212 return dynamic_cast<xercesc::DOMElement*
>(getNode(tagName, parent, itemNumber));
216 xercesc::DOMElement* TableInfoReader::getElement(XMLCh* tagName,
217 xercesc::DOMElement* parent,
218 unsigned int itemNumber)
220 return dynamic_cast<xercesc::DOMElement*
>(getNode(tagName, parent, itemNumber));
224 std::string TableInfoReader::read(
TableBase& table)
226 std::string accumulatedExceptions =
"";
237 if(__ENV__(
"CONFIGURATION_TYPE") == NULL)
238 __COUT__ <<
"Missing env variable: CONFIGURATION_TYPE. It must be set!" << __E__;
241 if(__ENV__(
"TABLE_INFO_PATH") == NULL)
242 __COUT__ <<
"Missing env variable: TABLE_INFO_PATH. It must be set!" << __E__;
251 std::string tableDataDir = std::string(__ENV__(
"TABLE_INFO_PATH")) +
"/";
252 std::string tableFile = tableDataDir + table.
getTableName() +
"Info.xml";
254 struct stat fileStatus;
256 int iretStat = stat(tableFile.c_str(), &fileStatus);
257 if(iretStat == ENOENT)
259 __SS__ << (
"Path file_name does not exist, or path is an empty std::string.")
261 __COUT_ERR__ << ss.str();
264 else if(iretStat == ENOTDIR)
266 __SS__ << (
"A component of the path is not a directory.") << __E__;
267 __COUT_ERR__ << ss.str();
270 else if(iretStat == ELOOP)
272 __SS__ << (
"Too many symbolic links encountered while traversing the path.")
274 __COUT_ERR__ << ss.str();
277 else if(iretStat == EACCES)
279 __SS__ << (
"Permission denied.") << __E__;
280 __COUT_ERR__ << ss.str();
283 else if(iretStat == ENAMETOOLONG)
285 __SS__ << (
"File can not be read. Name too long.") << __E__;
286 __COUT_ERR__ << ss.str();
290 xercesc::XercesDOMParser* parser =
new xercesc::XercesDOMParser;
292 parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto);
293 parser->setDoNamespaces(
true);
294 parser->setDoSchema(
true);
295 parser->useCachedGrammarInParse(
false);
298 parser->setErrorHandler(errorHandler);
301 parser->parse(tableFile.c_str());
304 xercesc::DOMDocument* xmlDocument = parser->getDocument();
307 xercesc::DOMElement* elementRoot = xmlDocument->getDocumentElement();
312 throw(std::runtime_error(
"empty XML document"));
316 xercesc::DOMElement* tableElement = getElement(tableTag_, elementRoot, 0);
318 XML_TO_CHAR(tableElement->getAttribute(tableNameAttributeTag_)))
320 __SS__ <<
"In " << tableFile <<
" the table name "
321 << XML_TO_CHAR(tableElement->getAttribute(tableNameAttributeTag_))
322 <<
" doesn't match the the class table name " << table.
getTableName()
327 __COUT_ERR__ <<
"\n" << ss.str();
328 throw(std::runtime_error(ss.str()));
331 xercesc::DOMNodeList* viewNodeList = tableElement->getElementsByTagName(viewTag_);
332 bool storageTypeFound =
false;
334 if(viewNodeList->getLength() != 1)
336 __SS__ <<
"In " << tableFile <<
" the table name "
337 << XML_TO_CHAR(tableElement->getAttribute(tableNameAttributeTag_))
338 <<
" there must only be one view. There were "
339 << viewNodeList->getLength() <<
" found." << __E__;
343 __COUT_ERR__ <<
"\n" << ss.str();
344 throw(std::runtime_error(ss.str()));
347 for(XMLSize_t view = 0; view < viewNodeList->getLength(); view++)
349 if(!viewNodeList->item(view)->getNodeType() ||
350 viewNodeList->item(view)->getNodeType() !=
351 xercesc::DOMNode::ELEMENT_NODE)
353 xercesc::DOMElement* viewElement =
354 dynamic_cast<xercesc::DOMElement*
>(viewNodeList->item(view));
355 std::string viewType =
356 XML_TO_CHAR(viewElement->getAttribute(viewTypeAttributeTag_));
357 if(!checkViewType(viewType))
359 storageTypeFound =
true;
364 if(std::string(XML_TO_CHAR(viewElement->getAttribute(
365 viewNameAttributeTag_))) != table.getMockupViewP()->getTableName())
366 __COUT_WARN__ <<
"Table Info name mismatch: "
367 << std::string(XML_TO_CHAR(
368 viewElement->getAttribute(viewNameAttributeTag_)))
369 <<
" vs " << table.getMockupViewP()->getTableName()
372 xercesc::DOMNodeList* columnNodeList =
373 viewElement->getElementsByTagName(columnTag_);
375 for(XMLSize_t column = 0; column < columnNodeList->getLength(); column++)
378 xercesc::DOMElement* columnElement =
379 dynamic_cast<xercesc::DOMElement*
>(columnNodeList->item(column));
386 std::string defaultValue;
387 bool isDefaultValue =
388 columnElement->getAttributeNode(columnDefaultValueAttributeTag_)
394 columnElement->getAttribute(columnDefaultValueAttributeTag_)));
398 std::string minValue;
400 columnElement->getAttributeNode(columnMinValueAttributeTag_) ? true
405 columnElement->getAttribute(columnMinValueAttributeTag_)));
409 std::string maxValue;
411 columnElement->getAttributeNode(columnMaxValueAttributeTag_) ? true
416 columnElement->getAttribute(columnMaxValueAttributeTag_)));
427 std::string capturedException;
430 XML_TO_CHAR(columnElement->getAttribute(columnTypeAttributeTag_)),
431 XML_TO_CHAR(columnElement->getAttribute(columnNameAttributeTag_)),
433 columnElement->getAttribute(columnStorageNameAttributeTag_)),
434 XML_TO_CHAR(columnElement->getAttribute(columnDataTypeAttributeTag_)),
435 isDefaultValue ? &defaultValue : 0,
437 columnElement->getAttribute(columnDataChoicesAttributeTag_)),
438 isMinValue ? &minValue : 0,
439 isMaxValue ? &maxValue : 0,
446 if(capturedException !=
"")
447 accumulatedExceptions +=
448 std::string(
"\n\nColumn Error:") + capturedException;
455 std::string tableDescription =
456 XML_TO_CHAR(viewElement->getAttribute(viewDescriptionAttributeTag_));
463 if(!storageTypeFound)
465 __COUT__ <<
"The type defined in CONFIGURATION_BACKEND_TYPE ("
466 << CONFIGURATION_BACKEND_TYPE_
467 <<
") doesn't match with any of the types defined in " << tableFile
472 throw(std::runtime_error(
"Table Type mismatch!"));
477 catch(xercesc::XMLException& e)
479 std::ostringstream errBuf;
480 errBuf <<
"Error parsing file: " << XML_TO_CHAR(e.getMessage()) << std::flush;
490 return accumulatedExceptions;
496 std::string TableInfoReader::read(
TableBase* table) {
return read(*table); }
const std::string & getTableName(void) const
Getters.
static std::string decodeURIComponent(const std::string &data)