CMS 3D CMS Logo

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