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 __MOUT_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 __MOUT__ <<
"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 __MOUT__ <<
"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 __MOUT__ << (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) __MOUT__ <<
"Missing env variable: CONFIGURATION_TYPE. It must be set!" << std::endl;
212 if(getenv(
"CONFIGURATION_DATA_PATH") == NULL) __MOUT__ <<
"Missing env variable: CONFIGURATION_DATA_PATH. It must be set!" << std::endl;
213 if(getenv(
"CONFIGURATION_INFO_PATH") == NULL) __MOUT__ <<
"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 )
229 throw ( std::runtime_error(
"Path file_name does not exist, or path is an empty std::string.") );
230 else if( iretStat == ENOTDIR )
231 throw ( std::runtime_error(
"A component of the path is not a directory."));
232 else if( iretStat == ELOOP )
233 throw ( std::runtime_error(
"Too many symbolic links encountered while traversing the path."));
234 else if( iretStat == EACCES )
235 throw ( std::runtime_error(
"Permission denied."));
236 else if( iretStat == ENAMETOOLONG )
237 throw ( std::runtime_error(
"File can not be read\n"));
239 xercesc::XercesDOMParser* parser =
new xercesc::XercesDOMParser;
241 parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto);
242 parser->setDoNamespaces (
true );
243 parser->setDoSchema (
true );
244 parser->useCachedGrammarInParse (
false );
247 parser->setErrorHandler(errorHandler);
250 parser->parse( configFile.c_str() );
253 xercesc::DOMDocument* xmlDocument = parser->getDocument();
256 xercesc::DOMElement* elementRoot = xmlDocument->getDocumentElement();
261 throw(std::runtime_error(
"empty XML document" ));
265 xercesc::DOMElement* configurationElement = getElement(configurationTag_, elementRoot, 0);
266 if( configuration.getConfigurationName() != XML_TO_CHAR(configurationElement->getAttribute(configurationNameAttributeTag_)) )
269 __SS__ <<
"In " << configFile <<
" the configuration name " << XML_TO_CHAR(configurationElement->getAttribute(configurationNameAttributeTag_))
270 <<
" doesn't match the the class configuration name " << configuration.getConfigurationName() << std::endl;
274 __MOUT_ERR__ <<
"\n" << ss.str();
275 throw(std::runtime_error( ss.str()));
278 xercesc::DOMNodeList* viewNodeList = configurationElement->getElementsByTagName(viewTag_);
279 bool storageTypeFound =
false;
281 if(viewNodeList->getLength() != 1)
284 __SS__ <<
"In " << configFile <<
" the configuration name " << XML_TO_CHAR(configurationElement->getAttribute(configurationNameAttributeTag_))
285 <<
" there must only be one view. There were " <<
286 viewNodeList->getLength() <<
" found." << std::endl;
290 __MOUT_ERR__ <<
"\n" << ss.str();
291 throw(std::runtime_error( ss.str()));
294 for( XMLSize_t view = 0; view < viewNodeList->getLength(); view++ )
296 if( !viewNodeList->item(view)->getNodeType() || viewNodeList->item(view)->getNodeType() != xercesc::DOMNode::ELEMENT_NODE )
298 xercesc::DOMElement* viewElement =
dynamic_cast< xercesc::DOMElement*
>( viewNodeList->item(view) );
299 std::string viewType = XML_TO_CHAR(viewElement->getAttribute(viewTypeAttributeTag_));
300 if(!checkViewType(viewType))
302 storageTypeFound =
true;
303 configuration.getMockupViewP()->setTableName(XML_TO_CHAR(viewElement->getAttribute(viewNameAttributeTag_)));
304 xercesc::DOMNodeList* columnNodeList = viewElement->getElementsByTagName(columnTag_);
305 for( XMLSize_t column = 0; column < columnNodeList->getLength(); column++ )
308 xercesc::DOMElement* columnElement =
dynamic_cast< xercesc::DOMElement*
>( columnNodeList->item(column) );
312 std::string capturedException;
313 configuration.getMockupViewP()->getColumnsInfoP()->push_back(
315 XML_TO_CHAR(columnElement->getAttribute(columnTypeAttributeTag_)),
316 XML_TO_CHAR(columnElement->getAttribute(columnNameAttributeTag_)),
317 XML_TO_CHAR(columnElement->getAttribute(columnStorageNameAttributeTag_)),
318 XML_TO_CHAR(columnElement->getAttribute(columnDataTypeAttributeTag_)),
319 XML_TO_CHAR(columnElement->getAttribute(columnDataChoicesAttributeTag_)),
320 allowIllegalColumns_?&capturedException:0));
324 if(capturedException !=
"")
325 accumulatedExceptions += std::string(
"\n\nColumn Error:") + capturedException;
332 std::string configurationDescription = XML_TO_CHAR(viewElement->getAttribute(
333 viewDescriptionAttributeTag_));
335 configuration.setConfigurationDescription(
336 ConfigurationView::decodeURIComponent(configurationDescription));
341 if( !storageTypeFound )
343 __MOUT__ <<
"The type defined in CONFIGURATION_TYPE ("
344 << getenv(
"CONFIGURATION_TYPE") <<
") doesn't match with any of the types defined in " << configFile << std::endl;
348 throw(std::runtime_error(
"Configuration Type mismatch!" ));
353 catch( xercesc::XMLException& e )
355 std::ostringstream errBuf;
356 errBuf <<
"Error parsing file: " << XML_TO_CHAR(e.getMessage()) << std::flush;
366 return accumulatedExceptions;
374 return read(*configuration);