1 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationInfoReader.h"
2 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationBase.h"
3 #include "otsdaq-core/XmlUtilities/DOMTreeErrorReporter.h"
4 #include "otsdaq-core/XmlUtilities/ConvertFromXML.h"
8 #include <xercesc/parsers/XercesDOMParser.hpp>
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>
16 #include <xercesc/util/OutOfMemoryException.hpp>
17 #include <xercesc/framework/LocalFileFormatTarget.hpp>
29 #define __COUT_HDR__ "ConfigInfoReader"
33 ConfigurationInfoReader::ConfigurationInfoReader(
bool allowIllegalColumns)
34 : allowIllegalColumns_(allowIllegalColumns)
37 rootTag_ = xercesc::XMLString::transcode(
"ROOT");
38 configurationTag_ = xercesc::XMLString::transcode(
"CONFIGURATION");
39 configurationNameAttributeTag_ = xercesc::XMLString::transcode(
"Name");
40 viewTag_ = xercesc::XMLString::transcode(
"VIEW");
41 viewNameAttributeTag_ = xercesc::XMLString::transcode(
"Name");
42 viewTypeAttributeTag_ = xercesc::XMLString::transcode(
"Type");
43 viewDescriptionAttributeTag_ = xercesc::XMLString::transcode(
"Description");
44 columnTag_ = xercesc::XMLString::transcode(
"COLUMN");
45 columnTypeAttributeTag_ = xercesc::XMLString::transcode(
"Type");
46 columnNameAttributeTag_ = xercesc::XMLString::transcode(
"Name");
47 columnStorageNameAttributeTag_ = xercesc::XMLString::transcode(
"StorageName");
48 columnDataTypeAttributeTag_ = xercesc::XMLString::transcode(
"DataType");
49 columnDataChoicesAttributeTag_ = xercesc::XMLString::transcode(
"DataChoices");
53 ConfigurationInfoReader::~ConfigurationInfoReader(
void)
57 xercesc::XMLString::release( &rootTag_ );
58 xercesc::XMLString::release( &configurationTag_ );
59 xercesc::XMLString::release( &configurationNameAttributeTag_ );
60 xercesc::XMLString::release( &viewTag_ );
61 xercesc::XMLString::release( &viewNameAttributeTag_ );
62 xercesc::XMLString::release( &viewTypeAttributeTag_ );
63 xercesc::XMLString::release( &viewDescriptionAttributeTag_ );
64 xercesc::XMLString::release( &columnTag_ );
65 xercesc::XMLString::release( &columnTypeAttributeTag_ );
66 xercesc::XMLString::release( &columnNameAttributeTag_ );
67 xercesc::XMLString::release( &columnStorageNameAttributeTag_ );
68 xercesc::XMLString::release( &columnDataTypeAttributeTag_ );
69 xercesc::XMLString::release( &columnDataChoicesAttributeTag_ );
74 mf::LogError(__FILE__) <<
"Unknown exception encountered in TagNames destructor" << std::endl;
80 void ConfigurationInfoReader::initPlatform(
void)
84 xercesc::XMLPlatformUtils::Initialize();
86 catch( xercesc::XMLException& e )
88 mf::LogError(__FILE__) <<
"XML toolkit initialization error: " << XML_TO_CHAR(e.getMessage()) << std::endl;
94 void ConfigurationInfoReader::terminatePlatform(
void)
98 xercesc::XMLPlatformUtils::Terminate();
100 catch( xercesc::XMLException& e )
102 mf::LogError(__FILE__) <<
"XML tolkit teardown error: " << XML_TO_CHAR(e.getMessage()) << std::endl;
108 void ConfigurationInfoReader::setAllowColumnErrors(
bool setValue)
110 allowIllegalColumns_ = setValue;
113 const bool& ConfigurationInfoReader::getAllowColumnErrors(
void)
115 return allowIllegalColumns_;
119 bool ConfigurationInfoReader::checkViewType(std::string type)
121 std::vector<std::string> types;
122 int currentIndex = 0;
123 while( type.find(
',',currentIndex) != std::string::npos )
125 types.push_back(type.substr(currentIndex,type.find(
',',currentIndex)-currentIndex));
126 currentIndex = type.find(
',',currentIndex)+1;
128 types.push_back(type.substr(currentIndex,type.size()));
130 std::string systemType = getenv(
"CONFIGURATION_TYPE");
131 for(
unsigned int i=0; i<types.size(); i++)
133 if( types[i] == systemType )
137 const unsigned int allowedNamesSize = 3;
138 const std::string allowedNames[allowedNamesSize] =
139 {
"File",
"Database",
"DatabaseTest"
141 if(systemType != allowedNames[0] && systemType != allowedNames[1] && systemType != allowedNames[2] )
143 __COUT__ <<
"The type defined in CONFIGURATION_TYPE ("
144 << systemType <<
") doesn't match with any of the allowed types: File,Database or DatabaseTest"
147 throw(std::runtime_error(
"Illegal configuration type" ));
149 for(
unsigned int i=0; i<types.size(); i++)
151 if(types[i] != allowedNames[0] && types[i] != allowedNames[1] && types[i] != allowedNames[2] )
153 __COUT__ <<
"The type defined in the info file ("
154 << types[i] <<
") doesn't match with any of the allowed types: "
155 << allowedNames[0] <<
", " << allowedNames[1] <<
" or " << allowedNames[2]
157 throw(std::runtime_error(
"Illegal Type!" ));
165 xercesc::DOMNode* ConfigurationInfoReader::getNode(XMLCh* tagName, xercesc::DOMNode* parent,
unsigned int itemNumber)
167 return getNode(tagName, dynamic_cast< xercesc::DOMElement* >(parent), itemNumber);
171 xercesc::DOMNode* ConfigurationInfoReader::getNode(XMLCh* tagName, xercesc::DOMElement* parent,
unsigned int itemNumber)
173 xercesc::DOMNodeList* nodeList = parent->getElementsByTagName(tagName);
176 throw(std::runtime_error( std::string(
"Can't find ") + XML_TO_CHAR(tagName) +
" tag!"));
177 __COUT__ << (std::string(
"Can't find ") + XML_TO_CHAR(tagName) +
" tag!") << std::endl;
182 return nodeList->item(itemNumber);
186 xercesc::DOMElement* ConfigurationInfoReader::getElement(XMLCh* tagName, xercesc::DOMNode* parent,
unsigned int itemNumber)
188 return dynamic_cast< xercesc::DOMElement*
>(getNode(tagName,parent,itemNumber));
192 xercesc::DOMElement* ConfigurationInfoReader::getElement(XMLCh* tagName, xercesc::DOMElement* parent,
unsigned int itemNumber)
194 return dynamic_cast< xercesc::DOMElement*
>(getNode(tagName,parent,itemNumber));
200 std::string accumulatedExceptions =
"";
211 if(getenv(
"CONFIGURATION_TYPE" ) == NULL) __COUT__ <<
"Missing env variable: CONFIGURATION_TYPE. It must be set!" << std::endl;
212 if(getenv(
"CONFIGURATION_DATA_PATH") == NULL) __COUT__ <<
"Missing env variable: CONFIGURATION_DATA_PATH. It must be set!" << std::endl;
213 if(getenv(
"CONFIGURATION_INFO_PATH") == NULL) __COUT__ <<
"Missing env variable: CONFIGURATION_INFO_PATH. It must be set!" << std::endl;
222 std::string configurationDataDir = std::string(getenv(
"CONFIGURATION_INFO_PATH")) +
"/";
223 std::string configFile = configurationDataDir + configuration.getConfigurationName() +
"Info.xml";
225 struct stat fileStatus;
227 int iretStat = stat(configFile.c_str(), &fileStatus);
228 if( iretStat == ENOENT )
230 __SS__ << (
"Path file_name does not exist, or path is an empty std::string.") << std::endl;
231 __COUT_ERR__ << ss.str();
232 throw std::runtime_error(ss.str());
234 else if( iretStat == ENOTDIR )
236 __SS__ << (
"A component of the path is not a directory.") << std::endl;
237 __COUT_ERR__ << ss.str();
238 throw std::runtime_error(ss.str());
240 else if( iretStat == ELOOP )
242 __SS__ << (
"Too many symbolic links encountered while traversing the path.") << std::endl;
243 __COUT_ERR__ << ss.str();
244 throw std::runtime_error(ss.str());
246 else if( iretStat == EACCES )
248 __SS__ << (
"Permission denied.") << std::endl;
249 __COUT_ERR__ << ss.str();
250 throw std::runtime_error(ss.str());
252 else if( iretStat == ENAMETOOLONG )
254 __SS__ << (
"File can not be read. Name too long.") << std::endl;
255 __COUT_ERR__ << ss.str();
256 throw std::runtime_error(ss.str());
259 xercesc::XercesDOMParser* parser =
new xercesc::XercesDOMParser;
261 parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto);
262 parser->setDoNamespaces (
true );
263 parser->setDoSchema (
true );
264 parser->useCachedGrammarInParse (
false );
267 parser->setErrorHandler(errorHandler);
270 parser->parse( configFile.c_str() );
273 xercesc::DOMDocument* xmlDocument = parser->getDocument();
276 xercesc::DOMElement* elementRoot = xmlDocument->getDocumentElement();
281 throw(std::runtime_error(
"empty XML document" ));
285 xercesc::DOMElement* configurationElement = getElement(configurationTag_, elementRoot, 0);
286 if( configuration.getConfigurationName() != XML_TO_CHAR(configurationElement->getAttribute(configurationNameAttributeTag_)) )
289 __SS__ <<
"In " << configFile <<
" the configuration name " << XML_TO_CHAR(configurationElement->getAttribute(configurationNameAttributeTag_))
290 <<
" doesn't match the the class configuration name " << configuration.getConfigurationName() << std::endl;
294 __COUT_ERR__ <<
"\n" << ss.str();
295 throw(std::runtime_error( ss.str()));
298 xercesc::DOMNodeList* viewNodeList = configurationElement->getElementsByTagName(viewTag_);
299 bool storageTypeFound =
false;
301 if(viewNodeList->getLength() != 1)
304 __SS__ <<
"In " << configFile <<
" the configuration name " << XML_TO_CHAR(configurationElement->getAttribute(configurationNameAttributeTag_))
305 <<
" there must only be one view. There were " <<
306 viewNodeList->getLength() <<
" found." << std::endl;
310 __COUT_ERR__ <<
"\n" << ss.str();
311 throw(std::runtime_error( ss.str()));
314 for( XMLSize_t view = 0; view < viewNodeList->getLength(); view++ )
316 if( !viewNodeList->item(view)->getNodeType() || viewNodeList->item(view)->getNodeType() != xercesc::DOMNode::ELEMENT_NODE )
318 xercesc::DOMElement* viewElement =
dynamic_cast< xercesc::DOMElement*
>( viewNodeList->item(view) );
319 std::string viewType = XML_TO_CHAR(viewElement->getAttribute(viewTypeAttributeTag_));
320 if(!checkViewType(viewType))
322 storageTypeFound =
true;
323 configuration.getMockupViewP()->setTableName(XML_TO_CHAR(viewElement->getAttribute(viewNameAttributeTag_)));
324 xercesc::DOMNodeList* columnNodeList = viewElement->getElementsByTagName(columnTag_);
325 for( XMLSize_t column = 0; column < columnNodeList->getLength(); column++ )
328 xercesc::DOMElement* columnElement =
dynamic_cast< xercesc::DOMElement*
>( columnNodeList->item(column) );
332 std::string capturedException;
333 configuration.getMockupViewP()->getColumnsInfoP()->push_back(
335 XML_TO_CHAR(columnElement->getAttribute(columnTypeAttributeTag_)),
336 XML_TO_CHAR(columnElement->getAttribute(columnNameAttributeTag_)),
337 XML_TO_CHAR(columnElement->getAttribute(columnStorageNameAttributeTag_)),
338 XML_TO_CHAR(columnElement->getAttribute(columnDataTypeAttributeTag_)),
339 XML_TO_CHAR(columnElement->getAttribute(columnDataChoicesAttributeTag_)),
340 allowIllegalColumns_?&capturedException:0));
344 if(capturedException !=
"")
345 accumulatedExceptions += std::string(
"\n\nColumn Error:") + capturedException;
352 std::string configurationDescription = XML_TO_CHAR(viewElement->getAttribute(
353 viewDescriptionAttributeTag_));
355 configuration.setConfigurationDescription(
356 ConfigurationView::decodeURIComponent(configurationDescription));
361 if( !storageTypeFound )
363 __COUT__ <<
"The type defined in CONFIGURATION_TYPE ("
364 << getenv(
"CONFIGURATION_TYPE") <<
") doesn't match with any of the types defined in " << configFile << std::endl;
368 throw(std::runtime_error(
"Configuration Type mismatch!" ));
373 catch( xercesc::XMLException& e )
375 std::ostringstream errBuf;
376 errBuf <<
"Error parsing file: " << XML_TO_CHAR(e.getMessage()) << std::flush;
386 return accumulatedExceptions;
394 return read(*configuration);