tdaq-develop-2025-02-12
ConfigurationHandler.cc
1 #include "otsdaq/ConfigurationInterface/ConfigurationHandler.h"
2 #include "otsdaq/ConfigurationInterface/TimeFormatter.h"
3 
4 #include "otsdaq/Macros/CoutMacros.h"
5 #include "otsdaq/XmlUtilities/ConvertFromXML.h"
6 #include "otsdaq/XmlUtilities/ConvertToXML.h"
7 #include "otsdaq/XmlUtilities/DOMTreeErrorReporter.h"
8 
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>
18 // #include <xercesc/dom/DOMWriter.hpp>
19 
20 #include <xercesc/framework/LocalFileFormatTarget.hpp>
21 #include <xercesc/util/OutOfMemoryException.hpp>
22 
23 #include <sys/types.h>
24 #include <iostream>
25 #include <sstream>
26 #include <stdexcept>
27 
28 #include <errno.h>
29 #include <sys/stat.h>
30 
31 #include "otsdaq/TableCore/TableBase.h"
32 
33 using namespace ots;
34 
35 #undef __COUT_HDR__
36 #define __COUT_HDR__ "ConfigHandler"
37 
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;
58 
59 //==============================================================================
60 ConfigurationHandler::ConfigurationHandler(void) {}
61 
62 //==============================================================================
63 ConfigurationHandler::~ConfigurationHandler(void) {}
64 
65 //==============================================================================
66 void ConfigurationHandler::initPlatform(void)
67 {
68  try
69  {
70  xercesc::XMLPlatformUtils::Initialize(); // Initialize Xerces infrastructure
71  }
72  catch(xercesc::XMLException& e)
73  {
74  __COUT_ERR__ << "XML toolkit initialization error: "
75  << XML_TO_CHAR(e.getMessage()) << std::endl;
76  // throw exception here to return ERROR_XERCES_INIT
77  }
78 
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");
97 }
98 
99 //==============================================================================
100 void ConfigurationHandler::terminatePlatform(void)
101 {
102  try
103  {
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_);
122  }
123  catch(...)
124  {
125  __COUT_ERR__ << "Unknown exception encountered in TagNames destructor"
126  << std::endl;
127  }
128 
129  try
130  {
131  xercesc::XMLPlatformUtils::Terminate(); // Terminate after release of memory
132  }
133  catch(xercesc::XMLException& e)
134  {
135  __COUT_ERR__ << "XML ttolkit teardown error: " << XML_TO_CHAR(e.getMessage())
136  << std::endl;
137  }
138 }
139 
140 //==============================================================================
141 bool ConfigurationHandler::validateNode(XMLCh* tagName,
142  xercesc::DOMNode* node,
143  const std::string& expectedValue)
144 {
145  if(node->getFirstChild() == 0)
146  {
147  __COUT__ << "Tag " << XML_TO_CHAR(tagName) << " doesn't have a value!"
148  << std::endl;
149  return false;
150  }
151 
152  if(XML_TO_STRING(node->getFirstChild()->getNodeValue()) != expectedValue)
153  {
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;
157  return false;
158  }
159 
160  return true;
161 }
162 
163 //==============================================================================
164 xercesc::DOMNode* ConfigurationHandler::getNode(XMLCh* tagName,
165  xercesc::DOMNode* parent,
166  unsigned int itemNumber)
167 {
168  return getNode(tagName, dynamic_cast<xercesc::DOMElement*>(parent), itemNumber);
169 }
170 
171 //==============================================================================
172 xercesc::DOMNode* ConfigurationHandler::getNode(XMLCh* tagName,
173  xercesc::DOMElement* parent,
174  unsigned int itemNumber)
175 {
176  xercesc::DOMNodeList* nodeList = parent->getElementsByTagName(tagName);
177 
178  if(!nodeList)
179  {
180  throw(std::runtime_error(std::string("Can't find ") + XML_TO_STRING(tagName) +
181  " tag!"));
182  __COUT__ << (std::string("Can't find ") + XML_TO_STRING(tagName) + " tag!")
183  << std::endl;
184  }
185 
186  // __COUT__<< "Name: " << XML_TO_CHAR(nodeList->item(itemNumber)->getNodeName())
187  // << std::endl; if( nodeList->item(itemNumber)->getFirstChild() != 0 )
188  // __COUT__<< "Value: " <<
189  // XML_TO_CHAR(nodeList->item(itemNumber)->getFirstChild()->getNodeValue()) <<
190  // std::endl;
191  return nodeList->item(itemNumber);
192 }
193 
194 //==============================================================================
195 xercesc::DOMElement* ConfigurationHandler::getElement(XMLCh* tagName,
196  xercesc::DOMNode* parent,
197  unsigned int itemNumber)
198 {
199  return dynamic_cast<xercesc::DOMElement*>(getNode(tagName, parent, itemNumber));
200 }
201 
202 //==============================================================================
203 xercesc::DOMElement* ConfigurationHandler::getElement(XMLCh* tagName,
204  xercesc::DOMElement* parent,
205  unsigned int itemNumber)
206 {
207  return dynamic_cast<xercesc::DOMElement*>(getNode(tagName, parent, itemNumber));
208 }
209 
210 //==============================================================================
211 void ConfigurationHandler::readXML(TableBase* table, TableVersion version)
212 {
213  readXML(*table, version);
214 }
215 
216 //==============================================================================
217 void ConfigurationHandler::readXML(TableBase& table, TableVersion version)
218 {
219  initPlatform();
220  std::string configFile = getXMLFileName(table, version);
221 
222  __COUT__ << "Reading: " << configFile << std::endl;
223  __COUT__ << "Into View with Table Name: " << table.getViewP()->getTableName()
224  << std::endl;
225  __COUT__ << "Into View with version: " << table.getViewP()->getVersion()
226  << " and version-to-read: " << version << std::endl;
227 
228  struct stat fileStatus;
229  // stat returns -1 on error, status in errno
230  if(stat(configFile.c_str(), &fileStatus) < 0)
231  {
232  __COUT__ << "Error reading path: " << configFile << std::endl;
233  std::stringstream ss;
234  ss << __COUT_HDR__;
235  if(errno == ENOENT)
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.");
245  else
246  ss << ("File can not be read.");
247  ss << std::endl;
248  __COUT_ERR__ << ss.str();
249  __SS_THROW__;
250  }
251 
252  xercesc::XercesDOMParser* parser = new xercesc::XercesDOMParser;
253 
254  // Configure DOM parser.
255  parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto); // Val_Never
256  parser->setDoNamespaces(true);
257  parser->setDoSchema(
258  false); // RAR set to false to get rid of "error reading primary document *.xsd"
259  // uses if true:
260  // rootElement->setAttribute(CONVERT_TO_XML("xsi:noNamespaceSchemaLocation"),CONVERT_TO_XML("TableBase.xsd"));
261  parser->useCachedGrammarInParse(false);
262  DOMTreeErrorReporter* errorHandler = new DOMTreeErrorReporter();
263  parser->setErrorHandler(errorHandler);
264 
265  //__COUT__ << configFile << std::endl;
266  try
267  {
268  //__COUT__ << "Parsing" << std::endl;
269  parser->parse(configFile.c_str());
270  //__COUT__ << "Parsed" << std::endl;
271 
272  // no need to free this pointer - owned by the parent parser object
273  xercesc::DOMDocument* document = parser->getDocument();
274 
275  // Get the top-level element: Name is "root". No attributes for "root"
276  xercesc::DOMElement* elementRoot = document->getDocumentElement();
277 
278  if(!elementRoot)
279  throw(std::runtime_error("empty XML document"));
280  //<HEADER>
281  //__COUT__ << "Reading header" << std::endl;
282  xercesc::DOMNode* headerNode = getNode(headerTag_, elementRoot, 0);
283  if(!headerNode)
284  throw(std::runtime_error(
285  std::string("The document is missing the mandatory tag: ") +
286  XML_TO_STRING(headerTag_)));
287 
288  //<TYPE>
289  //__COUT__ << "Reading type" << std::endl;
290  xercesc::DOMElement* typeElement = getElement(typeTag_, headerNode, 0);
291  if(!typeElement)
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_)));
308 
309  //__COUT__ << configFile << std::endl;
310  //</TYPE>
311  //<RUN>
312  //__COUT__ << "Reading run" << std::endl;
313  xercesc::DOMElement* runElement = getElement(runTag_, headerNode, 0);
314  if(!runElement)
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);
322  if(!runNumberNode)
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);
333  if(!locationNode)
334  throw(std::runtime_error(
335  std::string("The document is missing the mandatory tag: ") +
336  XML_TO_STRING(locationTag_)));
337 
338  //__COUT__ << configFile << std::endl;
339  //</RUN>
340  //</HEADER>
341 
342  //<DATA_SET>
343  //__COUT__ << "Reading Data Set" << std::endl;
344  xercesc::DOMElement* datasetElement = getElement(datasetTag_, elementRoot, 0);
345  if(!datasetElement)
346  throw(std::runtime_error(
347  std::string("The document is missing the mandatory tag: ") +
348  XML_TO_STRING(datasetTag_)));
349 
350  // <PART>
351  //__COUT__ << "Reading Part" << std::endl;
352  // xercesc::DOMNode* partNode = getNode(partTag_, datasetElement, 0);
353  // xercesc::DOMNode* nameLabelNode = getNode(nameLabelTag_, partNode, 0);
354  // xercesc::DOMNode* kindOfPartNode = getNode(kindOfPartTag_, partNode, 0);
355 
356  // </PART>
357  xercesc::DOMNode* versionNode = getNode(versionTag_, datasetElement, 0);
358 
359  if(versionNode->getFirstChild() == 0) // if version tag is missing
360  {
361  throw(std::runtime_error(
362  std::string("Missing version tag: ") +
363  XML_TO_CHAR(versionNode->getFirstChild()->getNodeValue())));
364  }
365  else // else verify version tag matches parameter version
366  {
367  char tmpVersionStr[100];
368  sprintf(tmpVersionStr, "%d", version.version());
369  __COUT__ << version << "-"
370  << XML_TO_CHAR(versionNode->getFirstChild()->getNodeValue())
371  << std::endl;
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 " +
377  tmpVersionStr));
378  }
379  // version is valid
380  table.getViewP()->setVersion(
381  XML_TO_CHAR(versionNode->getFirstChild()->getNodeValue()));
382 
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()));
388 
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()));
394 
395  //<DATA>
396  //__COUT__ << "Reading Data" << std::endl;
397  xercesc::DOMNodeList* dataNodeList =
398  datasetElement->getElementsByTagName(dataTag_);
399 
400  if(!dataNodeList)
401  throw(std::runtime_error(std::string("Can't find ") +
402  XML_TO_STRING(dataTag_) + " tag!"));
403 
404  //__COUT__ << "Number of data nodes: " << dataNodeList->getLength() << std::endl;
405  // First I need to setup the data container which is a [row][col] matrix where
406  // each <dataTag_> is a row and row 0 has the names of the column which will go
407  // in the columnInfo container
408  if(!dataNodeList->getLength()) // I must have at least 1 data!
409  {
410  __SS__ << "Must be non-empty data set!";
411  __SS_THROW__;
412  }
413 
414  //__COUT__ << table.getView().getColumnsInfo().size() << std::endl;
415  // First I can build the matrix and then fill it since I know the number of rows
416  // and columns
417  table.getViewP()->resizeDataView(dataNodeList->getLength(),
418  table.getView().getNumberOfColumns());
419 
420  for(XMLSize_t row = 0; row < dataNodeList->getLength(); row++)
421  {
422  // DOMElement* dataElement = dynamic_cast< xercesc::DOMElement* >(
423  // dataNodeList->item(row) );
424  xercesc::DOMNodeList* columnNodeList =
425  dataNodeList->item(row)->getChildNodes();
426  unsigned int colNumber = 0;
427 
428  //__COUT__ << "Row: " << row << " w " << columnNodeList->getLength() <<
429  // std::endl;
430  for(XMLSize_t col = 0; col < columnNodeList->getLength(); col++)
431  {
432  //__COUT__ << "Col: " << col << std::endl;
433 
434  if(!columnNodeList->item(col)->getNodeType() ||
435  columnNodeList->item(col)->getNodeType() !=
436  xercesc::DOMNode::ELEMENT_NODE) // true is not 0 && is element
437  continue;
438 
439  xercesc::DOMElement* columnElement =
440  dynamic_cast<xercesc::DOMElement*>(columnNodeList->item(col));
441 
442  if(table.getView().getColumnInfo(colNumber).getStorageName() !=
443  XML_TO_STRING(columnElement->getTagName()))
444  {
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 "
451  << colNumber + 1
452  << (colNumber == 0
453  ? "st"
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()));
461  }
462 
463  // if( row==0 )
464  // {
465  // table.getViewP()->getDataViewP()->push_back(vector<string>(dataNodeList->getLength()+1));//#
466  // of data + names
467  // (*table.getViewP()->getDataViewP())[colNumber][0]
468  // = XML_TO_STRING(columnElement->getTagName());
469  // }
470  table.getViewP()->setValueAsString(
471  XML_TO_STRING(
472  columnNodeList->item(col)->getFirstChild()->getNodeValue()),
473  row,
474  colNumber);
475  //(*table.getViewP()->getDataViewP())[row][colNumber] =
476  // XML_TO_STRING(columnNodeList->item(col)->getFirstChild()->getNodeValue());
477  ++colNumber;
478  }
479  }
480  }
481  catch(xercesc::XMLException& e)
482  {
483  __COUT__ << "Error parsing file: " << configFile << std::endl;
484  std::ostringstream errBuf;
485  errBuf << "Error parsing file: " << XML_TO_CHAR(e.getMessage()) << std::flush;
486  }
487 
488  __COUT__ << "Done with table file: " << configFile << std::endl;
489 
490  delete parser;
491  delete errorHandler;
492  terminatePlatform();
493 }
494 
495 //==============================================================================
496 std::string ConfigurationHandler::writeXML(const TableBase& table)
497 {
498  initPlatform();
499 
500  std::string configFile = getXMLFileName(
501  table,
502  table.getViewVersion()); // std::string(__ENV__("CONFIGURATION_DATA_PATH")) + "/"
503  // + table.getTableName() + "_write.xml";
504 
505  xercesc::DOMImplementation* implementation =
506  xercesc::DOMImplementationRegistry::getDOMImplementation(CONVERT_TO_XML("Core"));
507  if(implementation != 0)
508  {
509  try
510  {
511  //<ROOT>
512  xercesc::DOMDocument* document =
513  implementation->createDocument(0, // root element namespace URI.
514  rootTag_, // root element name
515  0); // document type object (DTD).
516 
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"),
523  CONVERT_TO_XML(
524  "TableBase.xsd")); // configFile.substr(configFile.rfind("/")+1).c_str()));
525  // //put the file name here..? TableBase.xsd"));
526  //${OTSDAQ_DIR}/otsdaq/ConfigurationDataFormats/TableInfo.xsd
527  // now moved to $USER_DATA/TableInfo/TableInfo.xsd
528 
529  //<HEADER>
530  xercesc::DOMElement* headerElement = document->createElement(headerTag_);
531  rootElement->appendChild(headerElement);
532 
533  //<TYPE>
534  xercesc::DOMElement* typeElement = document->createElement(typeTag_);
535  headerElement->appendChild(typeElement);
536 
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);
543 
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);
549  //</TYPE>
550 
551  //<RUN>
552  xercesc::DOMElement* runElement = document->createElement(runTag_);
553  headerElement->appendChild(runElement);
554 
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);
560 
561  xercesc::DOMElement* runNumberElement =
562  document->createElement(runNumberTag_);
563  runElement->appendChild(runNumberElement);
564  xercesc::DOMText* runNumberValue = document->createTextNode(CONVERT_TO_XML(
565  "1")); // This is dynamic and need to be created when I write the file
566  runNumberElement->appendChild(runNumberValue);
567 
568  xercesc::DOMElement* runBeginTimestampElement =
569  document->createElement(runBeginTimestampTag_);
570  runElement->appendChild(runBeginTimestampElement);
571  xercesc::DOMText* runBeginTimestampValue = document->createTextNode(
572  CONVERT_TO_XML(TimeFormatter::getTime().c_str())); // This is dynamic and
573  // need to be created
574  // when I write the
575  // files
576  runBeginTimestampElement->appendChild(runBeginTimestampValue);
577 
578  xercesc::DOMElement* locationElement = document->createElement(locationTag_);
579  runElement->appendChild(locationElement);
580  xercesc::DOMText* locationValue = document->createTextNode(
581  CONVERT_TO_XML("CERN P5")); // This is dynamic and need to be created
582  // when I write the file
583  locationElement->appendChild(locationValue);
584  //</RUN>
585 
586  xercesc::DOMElement* datasetElement = document->createElement(datasetTag_);
587  rootElement->appendChild(datasetElement);
588  //<PART>
589  xercesc::DOMElement* partElement = document->createElement(partTag_);
590  datasetElement->appendChild(partElement);
591 
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);
598 
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);
605 
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);
611 
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);
618 
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);
625  // for(TableView::iterator it=table.getView().begin();
626  // it!=table.getView().end(); it++)
627 
628  for(unsigned int row = 0; row < table.getView().getNumberOfRows(); row++)
629  {
630  xercesc::DOMElement* dataElement = document->createElement(dataTag_);
631  datasetElement->appendChild(dataElement);
632 
633  for(unsigned int col = 0; col < table.getView().getNumberOfColumns();
634  col++)
635  {
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);
642  }
643  }
644 
645  outputXML(document, configFile);
646 
647  document->release();
648  }
649  catch(const xercesc::OutOfMemoryException&)
650  {
651  XERCES_STD_QUALIFIER cerr << "OutOfMemoryException"
652  << XERCES_STD_QUALIFIER endl;
653  // errorCode = 5;
654  }
655  catch(const xercesc::DOMException& e)
656  {
657  XERCES_STD_QUALIFIER cerr << "DOMException code is: " << e.code
658  << XERCES_STD_QUALIFIER endl;
659  // errorCode = 2;
660  }
661  catch(const xercesc::XMLException& e)
662  {
663  std::string message = XML_TO_STRING(e.getMessage());
664  __COUT__ << "Error Message: " << message << std::endl;
665  // return 1;
666  return message;
667  }
668  catch(...)
669  {
670  XERCES_STD_QUALIFIER cerr << "An error occurred creating the document"
671  << XERCES_STD_QUALIFIER endl;
672  // errorCode = 3;
673  }
674  } // (inpl != 0)
675  else
676  {
677  XERCES_STD_QUALIFIER cerr << "Requested implementation is not supported"
678  << XERCES_STD_QUALIFIER endl;
679  // errorCode = 4;
680  }
681 
682  terminatePlatform();
683  return configFile;
684 }
685 
688 //==============================================================================
689 void ConfigurationHandler::outputXML(xercesc::DOMDocument* pmyDOMDocument,
690  std::string fileName)
691 {
692  std::string directory = fileName.substr(0, fileName.rfind("/") + 1);
693  __COUT__ << "Saving XML to " << fileName << " in directory: " << directory
694  << std::endl;
695 
696  mkdir(directory.c_str(), 0755);
697 
698  // Return the first registered implementation that has the desired features. In this
699  // case, we are after a DOM implementation that has the LS feature... or Load/Save.
700  // DOMImplementation *implementation =
701  // DOMImplementationRegistry::getDOMImplementation(L"LS");
702  xercesc::DOMImplementation* implementation =
703  xercesc::DOMImplementationRegistry::getDOMImplementation(CONVERT_TO_XML("LS"));
704 
705 #if _XERCES_VERSION >= 30000
706  // Create a DOMLSSerializer which is used to serialize a DOM tree into an XML
707  // document.
708  xercesc::DOMLSSerializer* serializer =
709  ((xercesc::DOMImplementationLS*)implementation)->createLSSerializer();
710 
711  // Make the output more human readable by inserting line feeds.
712 
713  if(serializer->getDomConfig()->canSetParameter(
714  xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true))
715  serializer->getDomConfig()->setParameter(
716  xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true);
717 
718  // The end-of-line sequence of characters to be used in the XML being written out.
719  // serializer->setNewLine(CONVERT_TO_XML("\r\n"));
720 
721  // Convert the path into Xerces compatible XMLCh*.
722 
723  // Specify the target for the XML output.
724  xercesc::XMLFormatTarget* formatTarget =
725  new xercesc::LocalFileFormatTarget(CONVERT_TO_XML(fileName));
726 
727  // Create a new empty output destination object.
728  xercesc::DOMLSOutput* output =
729  ((xercesc::DOMImplementationLS*)implementation)->createLSOutput();
730 
731  // Set the stream to our target.
732  output->setByteStream(formatTarget);
733 
734  // Write the serialized output to the destination.
735  serializer->write(pmyDOMDocument, output);
736 
737 #else
738  xercesc::DOMWriter* serializer =
739  ((xercesc::DOMImplementationLS*)implementation)->createDOMWriter();
740 
741  serializer->setFeature(xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true);
742 
743  /*
744  Choose a location for the serialized output. The 3 options are:
745  1) StdOutFormatTarget (std output stream - good for debugging)
746  2) MemBufFormatTarget (to Memory)
747  3) LocalFileFormatTarget (save to file)
748  (Note: You'll need a different header file for each one)
749  */
750  // XMLFormatTarget* pTarget = new StdOutFormatTarget();
751  // Convert the path into Xerces compatible XMLCh*.
752 
753  xercesc::XMLFormatTarget* formatTarget =
754  new xercesc::LocalFileFormatTarget(CONVERT_TO_XML(fileName.c_str()));
755 
756  // Write the serialized output to the target.
757  serializer->writeNode(formatTarget, *pmyDOMDocument);
758 
759 #endif
760 
761  // Cleanup.
762  serializer->release();
763 
764  delete formatTarget;
765 
766 #if _XERCES_VERSION >= 30000
767 
768  output->release();
769 
770 #endif
771  __COUT__ << "Done writing " << std::endl;
772 }
773 
774 //==============================================================================
775 std::string ConfigurationHandler::writeXML(const TableBase* table)
776 {
777  return writeXML(*table);
778 }
779 
780 //==============================================================================
781 std::string ConfigurationHandler::getXMLFileName(const TableBase& table,
782  TableVersion version)
783 {
784  std::stringstream fileName;
785  fileName << getXMLDir(&table) << version << '/' << table.getTableName() << "_v"
786  << version << ".xml";
787  return fileName.str();
788 }
789 
790 //==============================================================================
792 {
793  return std::string(__ENV__("CONFIGURATION_DATA_PATH")) + '/' + table->getTableName() +
794  '/';
795 }
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.
Definition: TableBase.cc:681
const TableVersion & getViewVersion(void) const
always the active one
Definition: TableBase.cc:690
unsigned int version(void) const
Definition: TableVersion.cc:29
void setValueAsString(const std::string &value, unsigned int row, unsigned int col)
Definition: TableView.cc:1078
void setVersion(const T &version)
< in included .icc source
static std::string getTime(void)
Static memebers.