Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:55:07

0001 #include "DetectorDescription/Parser/interface/DDLParser.h"
0002 #include "DetectorDescription/Parser/interface/DDLDocumentProvider.h"
0003 #include "DetectorDescription/Parser/interface/DDLSAX2ExpressionHandler.h"
0004 #include "DetectorDescription/Parser/interface/DDLSAX2FileHandler.h"
0005 #include "DetectorDescription/Parser/interface/DDLSAX2Handler.h"
0006 #include "Utilities/Xerces/interface/Xerces.h"
0007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0008 #include "FWCore/ParameterSet/interface/FileInPath.h"
0009 #include <xercesc/framework/MemBufInputSource.hpp>
0010 #include <xercesc/sax2/XMLReaderFactory.hpp>
0011 #include <xercesc/util/XMLUni.hpp>
0012 
0013 #include <iostream>
0014 
0015 class DDCompactView;
0016 
0017 XERCES_CPP_NAMESPACE_USE
0018 
0019 using namespace std;
0020 
0021 /// Constructor MUST associate a DDCompactView storage.
0022 DDLParser::DDLParser(DDCompactView& cpv) : cpv_(cpv), nFiles_(0) {
0023   cms::concurrency::xercesInitialize();
0024   SAX2Parser_ = XMLReaderFactory::createXMLReader();
0025 
0026   SAX2Parser_->setFeature(XMLUni::fgSAX2CoreValidation, false);  // optional
0027   SAX2Parser_->setFeature(XMLUni::fgSAX2CoreNameSpaces, false);  // optional
0028 
0029   elementRegistry_ = new DDLElementRegistry();
0030   expHandler_ = new DDLSAX2ExpressionHandler(cpv, *elementRegistry_);
0031   fileHandler_ = new DDLSAX2FileHandler(cpv, *elementRegistry_);
0032   errHandler_ = new DDLSAX2Handler();
0033   SAX2Parser_->setErrorHandler(errHandler_);
0034   SAX2Parser_->setContentHandler(fileHandler_);
0035 }
0036 
0037 /// Destructor terminates the XMLPlatformUtils (as required by Xerces)
0038 DDLParser::~DDLParser(void) {
0039   // clean up and leave
0040   delete expHandler_;
0041   delete fileHandler_;
0042   delete errHandler_;
0043   delete elementRegistry_;
0044   cms::concurrency::xercesTerminate();
0045 }
0046 
0047 /**  This method allows external "users" to use the current DDLParser on their own.
0048  *   by giving them access to the SAX2XMLReader.  This may not be a good idea!  The
0049  *   reason that I 
0050  */
0051 SAX2XMLReader* DDLParser::getXMLParser(void) { return SAX2Parser_; }
0052 
0053 DDLSAX2FileHandler* DDLParser::getDDLSAX2FileHandler(void) { return fileHandler_; }
0054 
0055 size_t DDLParser::isFound(const std::string& filename) {
0056   FileNameHolder::const_iterator it = fileNames_.begin();
0057   size_t i = 1;
0058   bool foundFile = false;
0059   while (it != fileNames_.end() && !foundFile) {
0060     if (it->second.first == filename) {
0061       foundFile = true;
0062     } else
0063       ++i;
0064     ++it;
0065   }
0066   if (foundFile)
0067     return i;
0068   return 0;
0069 }
0070 
0071 bool DDLParser::isParsed(const std::string& filename) {
0072   size_t found = isFound(filename);
0073   if (found)
0074     return parsed_[found];
0075   return false;
0076 }
0077 
0078 // Must receive a filename and path relative to the src directory of a CMSSW release
0079 // e.g. DetectorDescription/test/myfile.xml
0080 bool DDLParser::parseOneFile(const std::string& fullname) {
0081   std::string filename = extractFileName(fullname);
0082   edm::FileInPath fp(fullname);
0083   std::string absoluteFileName = fp.fullPath();
0084   size_t foundFile = isFound(filename);
0085   if (!foundFile) {
0086     pair<std::string, std::string> pss;
0087     pss.first = filename;
0088     pss.second = absoluteFileName;  //url+filename;
0089     int fIndex = nFiles_;
0090     fileNames_[nFiles_] = pss;
0091     ++nFiles_;
0092     parsed_[fIndex] = false;
0093 
0094     currFileName_ = fileNames_[fIndex].second;
0095 
0096     SAX2Parser_->setContentHandler(expHandler_);
0097     expHandler_->setNameSpace(getNameSpace(filename));
0098 
0099     LogDebug("DDLParser") << "ParseOneFile() Parsing: " << fileNames_[fIndex].second << std::endl;
0100     parseFile(fIndex);
0101     expHandler_->createDDConstants();
0102     // PASS 2:
0103 
0104     SAX2Parser_->setContentHandler(fileHandler_);
0105     fileHandler_->setNameSpace(getNameSpace(extractFileName(currFileName_)));
0106     parseFile(fIndex);
0107     parsed_[fIndex] = true;
0108   } else  // was found and is parsed...
0109   {
0110     return true;
0111   }
0112   return false;
0113 }
0114 
0115 //  This is for parsing the content of a blob stored in the conditions system of CMS.
0116 void DDLParser::parse(const std::vector<unsigned char>& ablob, unsigned int bsize) {
0117   char* dummy(nullptr);
0118   MemBufInputSource mbis(&*ablob.begin(), bsize, dummy);
0119   SAX2Parser_->parse(mbis);
0120   expHandler_->createDDConstants();
0121 }
0122 
0123 int DDLParser::parse(const DDLDocumentProvider& dp) {
0124   edm::LogInfo("DDLParser") << "Start Parsing.  Validation is set off for the time being." << std::endl;
0125   // prep for pass 1 through DDD XML
0126   SAX2Parser_->setFeature(XMLUni::fgSAX2CoreValidation, false);
0127   SAX2Parser_->setFeature(XMLUni::fgSAX2CoreNameSpaces, false);
0128 
0129   //  This need be only done once, so might as well to it here.
0130   size_t fileIndex = 0;
0131   std::vector<std::string> fullFileName;
0132   const std::vector<std::string>& fileList = dp.getFileList();
0133   const std::vector<std::string>& urlList = dp.getURLList();
0134 
0135   for (; fileIndex < fileList.size(); ++fileIndex) {
0136     std::string ts = urlList[fileIndex];
0137     std::string tf = fileList[fileIndex];
0138     if (!ts.empty()) {
0139       if (ts[ts.size() - 1] == '/') {
0140         fullFileName.emplace_back(ts + tf);
0141       } else {
0142         fullFileName.emplace_back(ts + "/" + tf);
0143       }
0144     } else {
0145       fullFileName.emplace_back(tf);
0146     }
0147   }
0148 
0149   for (const auto& fnit : fullFileName) {
0150     size_t foundFile = isFound(extractFileName(fnit));
0151 
0152     if (!foundFile) {
0153       pair<std::string, std::string> pss;
0154       pss.first = extractFileName(fnit);
0155       pss.second = fnit;
0156       fileNames_[nFiles_++] = pss;
0157       parsed_[nFiles_ - 1] = false;
0158     }
0159   }
0160 
0161   // Start processing the files found in the config file.
0162   assert(fileNames_.size() == nFiles_);
0163 
0164   // PASS 1:  This was added later (historically) to implement the DDD
0165   // requirement for Expressions.
0166 
0167   SAX2Parser_->setContentHandler(expHandler_);
0168   for (size_t i = 0; i < nFiles_; ++i) {
0169     if (!parsed_[i]) {
0170       currFileName_ = fileNames_[i].second;
0171       expHandler_->setNameSpace(getNameSpace(extractFileName(currFileName_)));
0172       parseFile(i);
0173     }
0174   }
0175   expHandler_->createDDConstants();
0176 
0177   // PASS 2:
0178 
0179   SAX2Parser_->setContentHandler(fileHandler_);
0180 
0181   // No need to validate (regardless of user's doValidation
0182   // because the files have already been validated on the first pass.
0183   // This optimization suggested by Martin Liendl.
0184 
0185   // Process files again.
0186   for (size_t i = 0; i < nFiles_; ++i) {
0187     if (!parsed_[i]) {
0188       currFileName_ = fileNames_[i].second;
0189       fileHandler_->setNameSpace(getNameSpace(extractFileName(currFileName_)));
0190       parseFile(i);
0191       parsed_[i] = true;
0192       pair<std::string, std::string> namePair = fileNames_[i];
0193       LogDebug("DDLParser") << "Completed parsing file " << namePair.second << std::endl;
0194     }
0195   }
0196   return 0;
0197 }
0198 
0199 void DDLParser::parseFile(const int& numtoproc) {
0200   if (!parsed_[numtoproc]) {
0201     const std::string& fname = fileNames_[numtoproc].second;
0202 
0203     currFileName_ = fname;
0204     SAX2Parser_->parse(currFileName_.c_str());
0205   }
0206 }
0207 
0208 void DDLParser::clearFiles(void) {
0209   fileNames_.clear();
0210   parsed_.clear();
0211 }
0212 
0213 std::string const DDLParser::extractFileName(const std::string& fullname) {
0214   return (fullname.substr(fullname.rfind('/') + 1));
0215 }
0216 
0217 std::string const DDLParser::getNameSpace(const std::string& fname) {
0218   size_t j = 0;
0219   std::string ret = "";
0220   while (j < fname.size() && fname[j] != '.')
0221     ++j;
0222   if (j < fname.size() && fname[j] == '.')
0223     ret = fname.substr(0, j);
0224   return ret;
0225 }