CMS 3D CMS Logo

DDLParser.cc

Go to the documentation of this file.
00001 /***************************************************************************
00002                           DDLParser.cc  -  description
00003                              -------------------
00004     begin                : Mon Oct 22 2001
00005     email                : case@ucdhep.ucdavis.edu
00006  ***************************************************************************/
00007 
00008 /***************************************************************************
00009  *                                                                         *
00010  *           DDDParser sub-component of DDD                                *
00011  *                                                                         *
00012  ***************************************************************************/
00013 
00014 //--------------------------------------------------------------------------
00015 //  Includes
00016 //--------------------------------------------------------------------------
00017 // Parser parts
00018 #include "DetectorDescription/Parser/interface/DDLParser.h"
00019 #include "DetectorDescription/Parser/interface/DDLDocumentProvider.h"
00020 #include "DetectorDescription/Parser/interface/DDLConfiguration.h"
00021 #include "DetectorDescription/Parser/interface/DDLSAX2Handler.h"
00022 #include "DetectorDescription/Parser/interface/DDLSAX2FileHandler.h"
00023 #include "DetectorDescription/Parser/interface/DDLSAX2ConfigHandler.h"
00024 #include "DetectorDescription/Parser/interface/DDLSAX2ExpressionHandler.h"
00025 
00026 #include "DDLElementRegistry.h"
00027 #include "StrX.h"
00028 
00029 // DDCore Dependencies
00030 #include "DetectorDescription/Base/interface/DDdebug.h"
00031 #include "DetectorDescription/Base/interface/DDException.h"
00032 #include "DetectorDescription/Algorithm/src/AlgoInit.h"
00033 
00034 // Xerces dependencies
00035 #include <xercesc/util/PlatformUtils.hpp>
00036 #include <xercesc/util/XMLUni.hpp>
00037 #include <xercesc/sax2/SAX2XMLReader.hpp>
00038 #include <xercesc/sax2/XMLReaderFactory.hpp>
00039 #include <xercesc/sax/SAXException.hpp>
00040 
00041 // EDM dependencies.
00042 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00043 #include "FWCore/ParameterSet/interface/FileInPath.h"
00044 
00045 #include <string>
00046 #include <iostream>
00047 #include <map>
00048 
00049 // // Seal
00050 // #include "SealUtil/SealTimer.h"
00051 
00052 using namespace std;
00053 using namespace xercesc_2_7;
00054 
00055 //--------------------------------------------------------------------------
00056 //  DDLParser:  Default constructor and destructor.
00057 //--------------------------------------------------------------------------
00059 DDLParser::~DDLParser()
00060 { 
00061   // clean up and leave
00062   XMLPlatformUtils::Terminate();
00063   DCOUT_V('P', "DDLParser::~DDLParser(): destruct DDLParser"); 
00064 }
00065 
00067 DDLParser::DDLParser( )  : nFiles_(0)
00068 { 
00069   // Initialize the XML4C2 system
00070 
00071   // in cleaning up try-catch blocks 2007-06-26 I decided to remove
00072   // this because of CMSSW rules. but keep the commented way I used to
00073   // do it...
00074 //   DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! try
00075 //     {
00076       XMLPlatformUtils::Initialize();
00077       AlgoInit();
00078 //     }
00079 
00080 //   DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! catch (const XMLException& toCatch)
00081 //     {
00082 //       std::string e("\nDDLParser(): Error during initialization! Message:");
00083 //       e += std::string(StrX(toCatch.getMessage()).localForm()) + std::string ("\n");
00084 //       throw (DDException(e));
00085 //     }
00086 
00087   SAX2Parser_  = XMLReaderFactory::createXMLReader();
00088 
00089   SAX2Parser_->setFeature(XMLUni::fgSAX2CoreValidation, false);   // optional
00090   SAX2Parser_->setFeature(XMLUni::fgSAX2CoreNameSpaces, false);   // optional
00091   // Specify other parser features, e.g.
00092   //  SAX2Parser_->setFeature(XMLUni::fgXercesSchemaFullChecking, false);
00093 
00094   expHandler_  = new DDLSAX2ExpressionHandler;
00095   fileHandler_ = new DDLSAX2FileHandler;
00096   errHandler_  = new DDLSAX2Handler;
00097   SAX2Parser_->setErrorHandler(errHandler_); 
00098   SAX2Parser_->setContentHandler(fileHandler_); 
00099 
00100   //  edm::LogInfo ("DDLParser") << "created SAX2XMLReader at memory " << SAX2Parser_ << std::endl;
00101   
00102   DCOUT_V('P', "DDLParser::DDLParser(): new (and only) DDLParser"); 
00103 }
00104 
00105 // ---------------------------------------------------------------------------
00106 //  DDLSAX2Parser: Implementation of the DDLParser sitting on top of the Xerces
00107 //  C++ XML Parser
00108 //  
00109 //--------------------------------------------------------------------------
00110 // Initialize singleton pointer.
00111 DDLParser* DDLParser::instance_ = 0;
00112 
00113 DDLParser* DDLParser::instance()
00114 {
00115 
00116   if ( instance_ == 0 ) {
00117     instance_ = new DDLParser();
00118   }
00119 
00120   return instance_;
00121 }
00122 
00127 SAX2XMLReader* DDLParser::getXMLParser() { return SAX2Parser_; }
00128 
00129 DDLSAX2FileHandler* DDLParser::getDDLSAX2FileHandler() { 
00130   return fileHandler_; 
00131 }
00132 
00133 size_t DDLParser::isFound(const std::string& filename)
00134 {
00135   FileNameHolder::const_iterator it = fileNames_.begin();
00136   size_t i = 1;
00137   bool foundFile = false;
00138   while (it != fileNames_.end() && !foundFile) //  for (; it != fileNames_.end(); ++it) 
00139     {
00140       if (it->second.first == filename)
00141         {
00142           foundFile = true;
00143         }
00144       else ++i;
00145       ++it;
00146     }
00147   if (foundFile)
00148     return i;
00149   return 0;
00150 }
00151 
00152 bool DDLParser::isParsed(const std::string& filename)
00153 {
00154   size_t found = isFound(filename);
00155   if (found)
00156     return parsed_[found];
00157   return false;
00158 }
00159 
00160 bool DDLParser::parseOneFile(const std::string& fullname) //, const std::string& url)
00161 {
00162 
00163   std::string filename = expHandler_->extractFileName(fullname);
00164   edm::FileInPath fp(fullname);
00165   std::string absoluteFileName = fp.fullPath();
00166   size_t foundFile = isFound(filename);
00167   if (!foundFile)
00168     {
00169       int fIndex = foundFile;
00170       pair <std::string, std::string> pss;
00171       pss.first = filename;
00172       pss.second = absoluteFileName; //url+filename;
00173       fIndex = nFiles_;
00174       fileNames_[nFiles_] = pss;
00175       ++nFiles_;
00176       parsed_[fIndex]=false;
00177 
00178       currFileName_ = fileNames_[fIndex].second;
00179 
00180   // in cleaning up try-catch blocks 2007-06-26 I decided to remove
00181   // this because of CMSSW rules. but keep the commented way I used to
00182   // do it...
00183 //       DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! try
00184 //         {
00185           SAX2Parser_->setContentHandler(expHandler_);
00186           LogDebug ("DDLParser") << "ParseOneFile() Parsing: " << fileNames_[fIndex].second << std::endl;
00187           parseFile ( fIndex );
00188 
00189 //         }
00190 //       DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! catch (const XMLException& toCatch) {
00191 //         edm::LogError ("DDLParser") << "\nDDLParser::ParseOneFile, PASS1: XMLException while processing files... \n"
00192 //              << "Exception message is: \n"
00193 //              << StrX(toCatch.getMessage()) << "\n" ;
00194 //         XMLPlatformUtils::Terminate();
00195 //         throw (DDException("  See XMLException above. "));
00196 //       }
00197 
00198       // PASS 2:
00199 
00200       DCOUT_V('P', "DDLParser::ParseOneFile(): PASS2: Just before setting Xerces content and error handlers... ");
00201 
00202 //       DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! try
00203 //         {
00204 
00205       SAX2Parser_->setContentHandler(fileHandler_);
00206       
00207       parseFile ( fIndex );
00208       parsed_[fIndex] = true;
00209 
00210 //         }
00211 //       DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! catch (const XMLException& toCatch) {
00212 //         edm::LogError ("DDLParser") << "\nDDLParser::ParseOneFile, PASS2: XMLException while processing files... \n"
00213 //              << "Exception message is: \n"
00214 //              << StrX(toCatch.getMessage()) << "\n" ;
00215 //         XMLPlatformUtils::Terminate();
00216 //         throw (DDException("  See XMLException above."));
00217 //       }
00218     }
00219   else // was found and is parsed...
00220     {
00221       DCOUT('P', " WARNING: DDLParser::ParseOneFile() file " + filename
00222            + " was already parsed as " + fileNames_[foundFile].second);
00223       return true;
00224     }
00225   return false;
00226 }
00227 
00228 std::vector < std::string >  DDLParser::getFileList(void) 
00229 {
00230   std::vector<std::string> flist;
00231   for (FileNameHolder::const_iterator fit = fileNames_.begin(); fit != fileNames_.end(); ++fit)
00232     {
00233       flist.push_back(fit->second.first); // was .second (mec: 2003:02:19
00234     }
00235   return flist;
00236 }
00237 
00238 void DDLParser::dumpFileList(void) {
00239   edm::LogInfo ("DDLParser") << "File List:" << std::endl;
00240   for (FileNameHolder::const_iterator it = fileNames_.begin(); it != fileNames_.end(); ++it)
00241     edm::LogInfo ("DDLParser") << it->second.second << std::endl;
00242 }
00243 
00244 void DDLParser::dumpFileList(ostream& co) {
00245   co << "File List:" << std::endl;
00246   for (FileNameHolder::const_iterator it = fileNames_.begin(); it != fileNames_.end(); ++it)
00247     co << it->second.second << std::endl;
00248 }
00249 
00250 int DDLParser::parse(const DDLDocumentProvider& dp)
00251 {
00252   //  edm::LogInfo ("DDLParser") << "Start Parsing.  Validation is set to " << dp.doValidation() << "." << std::endl;
00253   edm::LogInfo ("DDLParser") << "Start Parsing.  Validation is set off for the time being." << std::endl;
00254   // prep for pass 1 through DDD XML
00255 //   // Since this block does nothing for CMSSW right now, I have taken it all out
00256 //   This clean-up involves interface changes such as the removal of doValidation() everywhere (OR NOT 
00257 //   if I decide to keep it for other testing reasons.)
00258    if (dp.doValidation())
00259      { 
00260 //       DCOUT_V('P', "WARNING:  PARSER VALIDATION IS TURNED OFF REGARDLESS OF <Schema... ELEMENT");
00261   SAX2Parser_->setFeature(XMLUni::fgSAX2CoreValidation, true);
00262   SAX2Parser_->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
00263 //       //  SAX2Parser_->setFeature(XMLUni::fgXercesSchemaFullChecking, true);
00264      }
00265    else
00266 //     {
00267   SAX2Parser_->setFeature(XMLUni::fgSAX2CoreValidation, false);
00268   SAX2Parser_->setFeature(XMLUni::fgSAX2CoreNameSpaces, false);
00269 //       //  SAX2Parser_->setFeature(XMLUni::fgXercesSchemaFullChecking, false);
00270 
00271 //     }
00272 
00273   //  This need be only done once, so might as well to it here.
00274   size_t fileIndex = 0;
00275   std::vector<std::string> fullFileName;
00276 
00277   for (; fileIndex < (dp.getFileList()).size(); ++fileIndex)
00278     { 
00279       std::string ts = dp.getURLList()[fileIndex];
00280       std::string tf = dp.getFileList()[fileIndex];
00281       if ( ts.size() > 0 ) {
00282         if ( ts[ts.size() - 1] == '/') {
00283           fullFileName.push_back( ts + tf );
00284         } else {
00285           fullFileName.push_back( ts + "/" + tf );
00286         }
00287       } else {
00288         fullFileName.push_back( tf );
00289       }
00290     }
00291 
00292     for (std::vector<std::string>::const_iterator fnit = fullFileName.begin(); 
00293          fnit != fullFileName.end();
00294          ++fnit)
00295       {
00296         size_t foundFile = isFound(expHandler_->extractFileName( *fnit )); 
00297         
00298         if (!foundFile)
00299           {
00300             pair <std::string, std::string> pss;
00301             pss.first = expHandler_->extractFileName( *fnit );
00302             pss.second = *fnit;
00303             fileNames_[nFiles_++] = pss;
00304             parsed_[nFiles_ - 1]=false;
00305           }
00306       }
00307     
00308   // Start processing the files found in the config file.
00309   
00310   // PASS 1:  This was added later (historically) to implement the DDD
00311   // requirement for Expressions.
00312   DCOUT('P', "DDLParser::parse(): PASS1: Just before setting Xerces content and error handlers... ");
00313   
00314   
00315   // in cleaning up try-catch blocks 2007-06-26 I decided to remove
00316   // this because of CMSSW rules. but keep the commented way I used to
00317   // do it...
00318 //   DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! try
00319 //     {
00320       SAX2Parser_->setContentHandler(expHandler_);
00321       for (size_t i = 0; i < fileNames_.size(); ++i)
00322         {
00323 //        seal::SealTimer t("DDLParser: parsing expressions of file " +fileNames_[i].first);
00324           if (!parsed_[i])
00325             {
00326               parseFile(i);
00327             }
00328         }
00329       expHandler_->dumpElementTypeCounter();
00330 //     }
00331 //   DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! catch (const XMLException& toCatch) {
00332 //     edm::LogInfo ("DDLParser") << "\nPASS1: XMLException while processing files... \n"
00333 //       << "Exception message is: \n"
00334 //       << StrX(toCatch.getMessage()) << "\n" ;
00335 //     XMLPlatformUtils::Terminate();
00336 //     // FIX use this after DEPRECATED stuff removed:    throw(DDException("See XML Exception above"));
00337 //     return -1;
00338 //   }
00339   // PASS 2:
00340 
00341   DCOUT('P', "DDLParser::parse(): PASS2: Just before setting Xerces content and error handlers... ");
00342 
00343   // in cleaning up try-catch blocks 2007-06-26 I decided to remove
00344   // this because of CMSSW rules. but keep the commented way I used to
00345   // do it...
00346 //   DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! try
00347 //     {
00348       SAX2Parser_->setContentHandler(fileHandler_);
00349 
00350       // No need to validate (regardless of user's doValidation
00351       // because the files have already been validated on the first pass.
00352       // This optimization suggested by Martin Liendl.
00353 //       SAX2Parser_->setFeature(StrX("https://xml.org/sax/features/validation"), false);   // optional
00354 //       SAX2Parser_->setFeature(StrX("https://xml.org/sax/features/namespaces"), false);   // optional
00355 //       SAX2Parser_->setFeature(StrX("https://apache.org/xml/features/validation/dynamic"), false);
00356 
00357 
00358       // Process files again.
00359       for (size_t i = 0; i < fileNames_.size(); ++i)
00360         {
00361 //        seal::SealTimer t("DDLParser: parsing all elements of file " +fileNames_[i].first);
00362           parseFile(i);
00363           parsed_[i] = true;
00364           pair<std::string, std::string> namePair = fileNames_[i];
00365           LogDebug ("DDLParser") << "Completed parsing file " << namePair.second << std::endl;
00366         }
00367 //     }
00368 //   DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! catch (const XMLException& toCatch) {
00369 //     edm::LogError ("DDLParser") << "\nPASS2: XMLException while processing files... \n"
00370 //       << "Exception message is: \n"
00371 //       << StrX(toCatch.getMessage()) << "\n" ;
00372 //     XMLPlatformUtils::Terminate();
00373 //     return -1;
00374 //   }
00375   return 0;
00376 }
00377 
00378 void DDLParser::parseFile(const int& numtoproc) 
00379 {
00380   
00381   if (!parsed_[numtoproc])
00382     {
00383       const std::string & fname = fileNames_[numtoproc].second;
00384 
00385   // in cleaning up try-catch blocks 2007-06-26 I decided to remove
00386   // this because of CMSSW rules. but keep the commented way I used to
00387   // do it...
00388 //       DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! try
00389 //      {
00390           currFileName_ = fname;
00391           SAX2Parser_->parse(currFileName_.c_str());
00392 //      }
00393 //       DO NOT UNCOMMENT FOR ANY RELEASE; ONLY FOR DEBUGGING! catch (const XMLException& toCatch)
00394 //      {
00395 //        std::string e("\nWARNING: DDLParser::parseFile, File: '");
00396 //        e += currFileName_ + "'\n"
00397 //          + "Exception message is: \n"
00398 //          + std::string(StrX(toCatch.getMessage()).localForm()) + "\n";
00399 //        throw(DDException(e));
00400 //      }
00401     }
00402   else
00403     {
00404       DCOUT('P', "\nWARNING: File " + fileNames_[numtoproc].first 
00405            + " has already been processed as " + fileNames_[numtoproc].second);
00406     }
00407 }
00408 
00409 // Return the name of the Current file being processed by the parser.
00410 std::string DDLParser::getCurrFileName()
00411 {
00412   return currFileName_;
00413 }
00414 

Generated on Tue Jun 9 17:32:24 2009 for CMSSW by  doxygen 1.5.4