/DetectorDescription/Parser/src/DDLParser.cc

https://github.com/aivanov-cern/cmssw · C++ · 401 lines · 226 code · 47 blank · 128 comment · 33 complexity · fb56be528db7dc02f90876721ecbc4cd MD5 · raw file

  1. /***************************************************************************
  2. DDLParser.cc - description
  3. -------------------
  4. begin : Mon Oct 22 2001
  5. email : case@ucdhep.ucdavis.edu
  6. ***************************************************************************/
  7. /***************************************************************************
  8. * *
  9. * DDDParser sub-component of DDD *
  10. * *
  11. ***************************************************************************/
  12. #include "DetectorDescription/Parser/interface/DDLParser.h"
  13. #include "DetectorDescription/Parser/interface/DDLDocumentProvider.h"
  14. #include "DetectorDescription/Base/interface/DDdebug.h"
  15. #include <xercesc/framework/MemBufInputSource.hpp>
  16. #include "FWCore/ParameterSet/interface/FileInPath.h"
  17. #include "FWCore/Concurrency/interface/Xerces.h"
  18. #include <iostream>
  19. using namespace std;
  20. using namespace XERCES_CPP_NAMESPACE;
  21. /// Constructor MUST associate a DDCompactView storage.
  22. DDLParser::DDLParser( DDCompactView& cpv )
  23. : cpv_( cpv ),
  24. nFiles_( 0 )
  25. {
  26. cms::concurrency::xercesInitialize();
  27. SAX2Parser_ = XMLReaderFactory::createXMLReader();
  28. SAX2Parser_->setFeature(XMLUni::fgSAX2CoreValidation, false); // optional
  29. SAX2Parser_->setFeature(XMLUni::fgSAX2CoreNameSpaces, false); // optional
  30. // Specify other parser features, e.g.
  31. // SAX2Parser_->setFeature(XMLUni::fgXercesSchemaFullChecking, false);
  32. expHandler_ = new DDLSAX2ExpressionHandler(cpv);
  33. fileHandler_ = new DDLSAX2FileHandler(cpv);
  34. errHandler_ = new DDLSAX2Handler();
  35. SAX2Parser_->setErrorHandler(errHandler_);
  36. SAX2Parser_->setContentHandler(fileHandler_);
  37. DCOUT_V('P', "DDLParser::DDLParser(): new (and only) DDLParser");
  38. }
  39. /// Destructor terminates the XMLPlatformUtils (as required by Xerces)
  40. DDLParser::~DDLParser( void )
  41. {
  42. // clean up and leave
  43. delete expHandler_;
  44. delete fileHandler_;
  45. delete errHandler_;
  46. cms::concurrency::xercesTerminate();
  47. DCOUT_V('P', "DDLParser::~DDLParser(): destruct DDLParser");
  48. }
  49. /** This method allows external "users" to use the current DDLParser on their own.
  50. * by giving them access to the SAX2XMLReader. This may not be a good idea! The
  51. * reason that I
  52. */
  53. SAX2XMLReader*
  54. DDLParser::getXMLParser( void )
  55. {
  56. return SAX2Parser_;
  57. }
  58. DDLSAX2FileHandler*
  59. DDLParser::getDDLSAX2FileHandler( void )
  60. {
  61. return fileHandler_;
  62. }
  63. size_t
  64. DDLParser::isFound( const std::string& filename )
  65. {
  66. FileNameHolder::const_iterator it = fileNames_.begin();
  67. size_t i = 1;
  68. bool foundFile = false;
  69. while( it != fileNames_.end() && !foundFile )
  70. {
  71. if( it->second.first == filename )
  72. {
  73. foundFile = true;
  74. }
  75. else ++i;
  76. ++it;
  77. }
  78. if( foundFile )
  79. return i;
  80. return 0;
  81. }
  82. bool
  83. DDLParser::isParsed( const std::string& filename )
  84. {
  85. size_t found = isFound(filename);
  86. if (found)
  87. return parsed_[found];
  88. return false;
  89. }
  90. // Must receive a filename and path relative to the src directory of a CMSSW release
  91. // e.g. DetectorDescription/test/myfile.xml
  92. bool
  93. DDLParser::parseOneFile( const std::string& fullname ) //, const std::string& url)
  94. {
  95. // std::string filename = expHandler_->extractFileName(fullname);
  96. std::string filename = extractFileName(fullname);
  97. // std::cout << "parseOneFile - fullname = " << fullname << std::endl;
  98. // std::cout << "parseOneFile - filename = " << filename << std::endl;
  99. edm::FileInPath fp(fullname);
  100. std::string absoluteFileName = fp.fullPath();
  101. size_t foundFile = isFound(filename);
  102. if (!foundFile)
  103. {
  104. pair <std::string, std::string> pss;
  105. pss.first = filename;
  106. pss.second = absoluteFileName; //url+filename;
  107. int fIndex = nFiles_;
  108. fileNames_[nFiles_] = pss;
  109. ++nFiles_;
  110. parsed_[fIndex]=false;
  111. currFileName_ = fileNames_[fIndex].second;
  112. // in cleaning up try-catch blocks 2007-06-26 I decided to remove
  113. // this because of CMSSW rules. but keep the commented way I used to
  114. // do it...
  115. // DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! try
  116. // {
  117. SAX2Parser_->setContentHandler(expHandler_);
  118. expHandler_->setNameSpace( getNameSpace(filename) );
  119. // std::cout << "0) namespace = " << getNameSpace(filename) << std::endl;
  120. LogDebug ("DDLParser") << "ParseOneFile() Parsing: " << fileNames_[fIndex].second << std::endl;
  121. parseFile ( fIndex );
  122. // }
  123. // DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! catch (const XMLException& toCatch) {
  124. // edm::LogError ("DDLParser") << "\nDDLParser::ParseOneFile, PASS1: XMLException while processing files... \n"
  125. // << "Exception message is: \n"
  126. // << StrX(toCatch.getMessage()) << "\n" ;
  127. // cms::concurrency::xercesTerminate();
  128. // throw (DDException(" See XMLException above. "));
  129. // }
  130. // PASS 2:
  131. DCOUT_V('P', "DDLParser::ParseOneFile(): PASS2: Just before setting Xerces content and error handlers... ");
  132. // DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! try
  133. // {
  134. SAX2Parser_->setContentHandler(fileHandler_);
  135. // std::cout << "currFileName = " << currFileName_ << std::endl;
  136. fileHandler_->setNameSpace( getNameSpace(extractFileName(currFileName_)) );
  137. // std::cout << "1) namespace = " << getNameSpace(currFileName_) << std::endl;
  138. parseFile ( fIndex );
  139. parsed_[fIndex] = true;
  140. // }
  141. // DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! catch (const XMLException& toCatch) {
  142. // edm::LogError ("DDLParser") << "\nDDLParser::ParseOneFile, PASS2: XMLException while processing files... \n"
  143. // << "Exception message is: \n"
  144. // << StrX(toCatch.getMessage()) << "\n" ;
  145. // cms::concurrency::xercesTerminate();
  146. // throw (DDException(" See XMLException above."));
  147. // }
  148. }
  149. else // was found and is parsed...
  150. {
  151. DCOUT('P', " WARNING: DDLParser::ParseOneFile() file " + filename
  152. + " was already parsed as " + fileNames_[foundFile].second);
  153. return true;
  154. }
  155. return false;
  156. }
  157. // This is for parsing the content of a blob stored in the conditions system of CMS.
  158. void
  159. DDLParser::parse( const std::vector<unsigned char>& ablob, unsigned int bsize )
  160. {
  161. char* dummy(0);
  162. MemBufInputSource mbis( &*ablob.begin(), bsize, dummy );
  163. SAX2Parser_->parse(mbis);
  164. }
  165. std::vector < std::string >
  166. DDLParser::getFileList( void )
  167. {
  168. std::vector<std::string> flist;
  169. for (FileNameHolder::const_iterator fit = fileNames_.begin(); fit != fileNames_.end(); ++fit)
  170. {
  171. flist.push_back(fit->second.first); // was .second (mec: 2003:02:19
  172. }
  173. return flist;
  174. }
  175. int
  176. DDLParser::parse( const DDLDocumentProvider& dp )
  177. {
  178. // edm::LogInfo ("DDLParser") << "Start Parsing. Validation is set to " << dp.doValidation() << "." << std::endl;
  179. edm::LogInfo ("DDLParser") << "Start Parsing. Validation is set off for the time being." << std::endl;
  180. // prep for pass 1 through DDD XML
  181. // // Since this block does nothing for CMSSW right now, I have taken it all out
  182. // This clean-up involves interface changes such as the removal of doValidation() everywhere (OR NOT
  183. // if I decide to keep it for other testing reasons.)
  184. // if (dp.doValidation())
  185. // {
  186. // // DCOUT_V('P', "WARNING: PARSER VALIDATION IS TURNED OFF REGARDLESS OF <Schema... ELEMENT");
  187. // SAX2Parser_->setFeature(XMLUni::fgSAX2CoreValidation, true);
  188. // SAX2Parser_->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
  189. // // // SAX2Parser_->setFeature(XMLUni::fgXercesSchemaFullChecking, true);
  190. // }
  191. // else
  192. // {
  193. SAX2Parser_->setFeature(XMLUni::fgSAX2CoreValidation, false);
  194. SAX2Parser_->setFeature(XMLUni::fgSAX2CoreNameSpaces, false);
  195. // // SAX2Parser_->setFeature(XMLUni::fgXercesSchemaFullChecking, false);
  196. // }
  197. // This need be only done once, so might as well to it here.
  198. size_t fileIndex = 0;
  199. std::vector<std::string> fullFileName;
  200. for (; fileIndex < (dp.getFileList()).size(); ++fileIndex)
  201. {
  202. std::string ts = dp.getURLList()[fileIndex];
  203. std::string tf = dp.getFileList()[fileIndex];
  204. if ( ts.size() > 0 ) {
  205. if ( ts[ts.size() - 1] == '/') {
  206. fullFileName.push_back( ts + tf );
  207. } else {
  208. fullFileName.push_back( ts + "/" + tf );
  209. }
  210. } else {
  211. fullFileName.push_back( tf );
  212. }
  213. }
  214. for (std::vector<std::string>::const_iterator fnit = fullFileName.begin();
  215. fnit != fullFileName.end();
  216. ++fnit)
  217. {
  218. size_t foundFile = isFound(extractFileName( *fnit ));
  219. if (!foundFile)
  220. {
  221. pair <std::string, std::string> pss;
  222. pss.first = extractFileName( *fnit );
  223. pss.second = *fnit;
  224. fileNames_[nFiles_++] = pss;
  225. parsed_[nFiles_ - 1]=false;
  226. }
  227. }
  228. // Start processing the files found in the config file.
  229. // PASS 1: This was added later (historically) to implement the DDD
  230. // requirement for Expressions.
  231. DCOUT('P', "DDLParser::parse(): PASS1: Just before setting Xerces content and error handlers... ");
  232. // in cleaning up try-catch blocks 2007-06-26 I decided to remove
  233. // this because of CMSSW rules. but keep the commented way I used to
  234. // do it...
  235. // DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! try
  236. // {
  237. SAX2Parser_->setContentHandler(expHandler_);
  238. for (size_t i = 0; i < fileNames_.size(); ++i)
  239. {
  240. // seal::SealTimer t("DDLParser: parsing expressions of file " +fileNames_[i].first);
  241. if (!parsed_[i])
  242. {
  243. currFileName_ = fileNames_[i].second;
  244. // std::cout << "currFileName = " << currFileName_ << std::endl;
  245. expHandler_->setNameSpace( getNameSpace(extractFileName(currFileName_)) );
  246. // std::cout << "2) namespace = " << getNameSpace(extractFileName(currFileName_)) << std::endl;
  247. parseFile(i);
  248. }
  249. }
  250. expHandler_->dumpElementTypeCounter();
  251. // }
  252. // DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! catch (const XMLException& toCatch) {
  253. // edm::LogInfo ("DDLParser") << "\nPASS1: XMLException while processing files... \n"
  254. // << "Exception message is: \n"
  255. // << StrX(toCatch.getMessage()) << "\n" ;
  256. // cms::concurrency::xercesTerminate();
  257. // // FIX use this after DEPRECATED stuff removed: throw(DDException("See XML Exception above"));
  258. // return -1;
  259. // }
  260. // PASS 2:
  261. DCOUT('P', "DDLParser::parse(): PASS2: Just before setting Xerces content and error handlers... ");
  262. // in cleaning up try-catch blocks 2007-06-26 I decided to remove
  263. // this because of CMSSW rules. but keep the commented way I used to
  264. // do it...
  265. // DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! try
  266. // {
  267. SAX2Parser_->setContentHandler(fileHandler_);
  268. // No need to validate (regardless of user's doValidation
  269. // because the files have already been validated on the first pass.
  270. // This optimization suggested by Martin Liendl.
  271. // SAX2Parser_->setFeature(StrX("http://xml.org/sax/features/validation"), false); // optional
  272. // SAX2Parser_->setFeature(StrX("http://xml.org/sax/features/namespaces"), false); // optional
  273. // SAX2Parser_->setFeature(StrX("http://apache.org/xml/features/validation/dynamic"), false);
  274. // Process files again.
  275. for (size_t i = 0; i < fileNames_.size(); ++i)
  276. {
  277. // seal::SealTimer t("DDLParser: parsing all elements of file " +fileNames_[i].first);
  278. if (!parsed_[i]) {
  279. currFileName_ = fileNames_[i].second;
  280. // std::cout << "currFileName = " << currFileName_ << std::endl;
  281. fileHandler_->setNameSpace( getNameSpace(extractFileName(currFileName_)) );
  282. // std::cout << "3) namespace = " << getNameSpace(extractFileName(currFileName_)) << std::endl;
  283. parseFile(i);
  284. parsed_[i] = true;
  285. pair<std::string, std::string> namePair = fileNames_[i];
  286. LogDebug ("DDLParser") << "Completed parsing file " << namePair.second << std::endl;
  287. }
  288. }
  289. // }
  290. // DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! catch (const XMLException& toCatch) {
  291. // edm::LogError ("DDLParser") << "\nPASS2: XMLException while processing files... \n"
  292. // << "Exception message is: \n"
  293. // << StrX(toCatch.getMessage()) << "\n" ;
  294. // cms::concurrency::xercesTerminate();
  295. // return -1;
  296. // }
  297. return 0;
  298. }
  299. void
  300. DDLParser::parseFile( const int& numtoproc )
  301. {
  302. if (!parsed_[numtoproc])
  303. {
  304. const std::string & fname = fileNames_[numtoproc].second;
  305. // in cleaning up try-catch blocks 2007-06-26 I decided to remove
  306. // this because of CMSSW rules. but keep the commented way I used to
  307. // do it...
  308. // DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! try
  309. // {
  310. currFileName_ = fname;
  311. SAX2Parser_->parse(currFileName_.c_str());
  312. // }
  313. // DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! catch (const XMLException& toCatch)
  314. // {
  315. // std::string e("\nWARNING: DDLParser::parseFile, File: '");
  316. // e += currFileName_ + "'\n"
  317. // + "Exception message is: \n"
  318. // + std::string(StrX(toCatch.getMessage()).localForm()) + "\n";
  319. // throw(DDException(e));
  320. // }
  321. }
  322. else
  323. {
  324. DCOUT('P', "\nWARNING: File " + fileNames_[numtoproc].first
  325. + " has already been processed as " + fileNames_[numtoproc].second);
  326. }
  327. }
  328. void
  329. DDLParser::clearFiles( void )
  330. {
  331. fileNames_.clear();
  332. parsed_.clear();
  333. }
  334. std::string
  335. DDLParser::extractFileName( std::string fullname )
  336. {
  337. std::string ret = "";
  338. size_t bit = fullname.rfind('/');
  339. if ( bit < fullname.size() - 2 ) {
  340. ret=fullname.substr(bit+1);
  341. }
  342. return ret;
  343. }
  344. std::string
  345. DDLParser::getNameSpace( const std::string& fname )
  346. {
  347. size_t j = 0;
  348. std::string ret="";
  349. while (j < fname.size() && fname[j] != '.')
  350. ++j;
  351. if (j < fname.size() && fname[j] == '.')
  352. ret = fname.substr(0, j);
  353. return ret;
  354. }