CMS 3D CMS Logo

DDXMLElement.cc

Go to the documentation of this file.
00001 /***************************************************************************
00002                           DDXMLElement.cc  -  description
00003                              -------------------
00004     begin                : Fri Mar 15 2002
00005     email                : case@ucdhep.ucdavis.edu
00006  ***************************************************************************/
00007 
00008 
00009 
00010 // -------------------------------------------------------------------------
00011 // Includes
00012 // -------------------------------------------------------------------------
00013 #include "DDXMLElement.h"
00014 #include "DetectorDescription/Parser/interface/DDLSAX2FileHandler.h"
00015 #include "DetectorDescription/Parser/interface/DDLParser.h"
00016 
00017 // DDCore dependencies
00018 #include "DetectorDescription/Base/interface/DDdebug.h"
00019 #include "DetectorDescription/Base/interface/DDException.h"
00020 
00021 #include <string>
00022 #include <algorithm>
00023 #include <map>
00024 #include <vector>
00025 #include <iostream>
00026 #include <sstream>
00027 
00028 //#include <strstream>
00029 
00030 // -------------------------------------------------------------------------
00031 // Constructor/Destructor
00032 // -------------------------------------------------------------------------
00033 
00034 DDXMLElement::DDXMLElement() : attributes_(), text_(), autoClear_(false)
00035 { }
00036 
00037 DDXMLElement::DDXMLElement(const bool& clearme) : attributes_(), text_(), autoClear_(clearme)
00038 { }
00039 
00040 DDXMLElement::~DDXMLElement()
00041 { }
00042 
00043 // -------------------------------------------------------------------------
00044 // Implementation
00045 // -------------------------------------------------------------------------
00046 
00047 // For pre-processing, after attributes are loaded.  Default, do nothing!
00048 void DDXMLElement::preProcessElement(const std::string& name, const std::string& nmspace)
00049 {
00050   DCOUT_V('P', "DDXMLElement::preProcessElementBase default, do nothing) started-completed.");
00051 }
00052 
00053 // This loads the attributes into the attributes_ std::vector.
00054 void DDXMLElement::loadAttributes (const std::string& elemName
00055                                      , const std::vector<std::string> & names
00056                                      , const std::vector<std::string> & values
00057                                      , const std::string& nmspace)
00058 {
00059 
00060   attributes_.resize(attributes_.size()+1);
00061   DDXMLAttribute & tAttributes =  attributes_.back();
00062   
00063   // adds attributes
00064   for (size_t i = 0; i < names.size(); ++i)
00065     {
00066       //      tAttributes[ names[i] ] = values[i];
00067       tAttributes.insert(std::make_pair(names[i], values[i]));
00068     }
00069 
00070   preProcessElement( elemName, nmspace );
00071   DCOUT_V('P', "DDXMLElement::loadAttributes completed. " << *this);
00072 }
00073 
00074 // clear data.
00075 void DDXMLElement::clear()
00076 {
00077   text_.clear();
00078   attributes_.clear();
00079   attributeAccumulator_.clear();
00080 }
00081 
00082 // Access to current attributes by name.
00083 const std::string & DDXMLElement::getAttribute(const std::string& name) const
00084 {
00085   static const std::string ldef;
00086   if (attributes_.size())
00087     return get(name, attributes_.size() - 1);
00088   return ldef;
00089 }
00090 
00091 const DDXMLAttribute& DDXMLElement::getAttributeSet(size_t aIndex) const 
00092 {
00093   //  if (aIndex < attributes_.size())
00094   return attributes_[aIndex];  
00095 }
00096 
00097 
00098 const DDName DDXMLElement::getDDName(const std::string& defaultNS, const std::string& attname, size_t aIndex)
00099 {
00100   if (aIndex < attributes_.size()
00101       && attributes_[aIndex].find(attname) != attributes_[aIndex].end()) { 
00102     std::string ns = defaultNS;
00103     const std::string & name = attributes_[aIndex].find(attname)->second;
00104     std::string rn = name;
00105     size_t foundColon= name.find(':');
00106     if (foundColon != std::string::npos) {
00107       ns = name.substr(0,foundColon);
00108       rn = name.substr(foundColon+1);
00109 
00110     }
00111     //    std::cout << "Name: " << rn << " Namespace: " << ns << std::endl;
00112     return DDName(rn, ns);
00113   }
00114   //  std::cout << "no " << attname <<  " default namespace: " << defaultNS << " at index " << aIndex << std::endl;
00115   std::string msg = "DDXMLElement:getDDName failed.  It was asked to make ";
00116   msg += "a DDName using attribute: " + attname;
00117   msg += " in position: " + itostr(int(aIndex)) + ".  There are ";
00118   msg += itostr(int(attributes_.size())) + " entries in the element.";
00119   throwError(msg);
00120   return DDName("justToCompile", "justToCompile"); // used to make sure that 
00121   // the method will compile with some compilers that are picky.
00122 } 
00123 
00124 std::string DDXMLElement::getNameSpace(const std::string& defaultNS, const std::string& attname
00125                                   , size_t aIndex)
00126 {
00127   std::cout << "DEPRECATED: PLEASE DO NOT USE getNameSpace ANYMORE!" << std::endl;
00128   std::string ns;
00129   const std::string & name = get(attname, aIndex);
00130   size_t foundColon= name.find(':');
00131   if (foundColon != std::string::npos)
00132     ns = name.substr(0,foundColon);
00133   else
00134     {
00135       ns = defaultNS;
00136     }
00137   return ns;
00138 }
00139 
00140 const std::string DDXMLElement::getName(const std::string& attname
00141                              , size_t aIndex)
00142 {
00143   std::cout << "DEPRECATED: PLEASE DO NOT USE getName ANYMORE!!" << std::endl;
00144   std::string rn;
00145   const std::string & name = get(attname, aIndex);
00146   size_t foundColon= name.find(':');
00147   if (foundColon != std::string::npos)
00148     rn = name.substr(foundColon+1);
00149   {
00150     rn = name;
00151   }
00152   return rn;
00153 }
00154 
00155 // Returns a specific value from the aIndex set of attributes.
00156 const std::string & DDXMLElement::get(const std::string& name, const size_t aIndex ) const
00157 {
00158   static const std::string sts;
00159   if (aIndex < attributes_.size())
00160     {
00161       DDXMLAttribute::const_iterator it = attributes_[aIndex].find(name);
00162       if (attributes_[aIndex].end() == it)
00163         {
00164           DCOUT_V('P', "WARNING: DDXMLElement::get did not find the requested attribute: "  << name << std::endl << *this);
00165           return sts;
00166         }
00167       else
00168         return (it->second);
00169     }
00170   std::string msg = "DDXMLElement:get failed.  It was asked for attribute " + name;
00171   msg += " in position " + itostr(int(aIndex)) + " when there are only ";
00172   msg += itostr(int(attributes_.size())) + " in the element storage.\n";
00173   throwError(msg);
00174   // meaningless...
00175   return sts;
00176 
00177 }
00178 
00179 // Returns a specific set of values as a std::vector of std::strings,
00180 // given the attribute name.
00181 std::vector<std::string> DDXMLElement::getVectorAttribute(const std::string& name)
00182 {
00183 
00184   //  The idea here is that the attributeAccumulator_ is a cache of
00185   //  on-the-fly generation from the std::vector<DDXMLAttribute> and the 
00186   //  reason is simply to speed things up if it is requested more than once.
00187   std::vector<std::string> tv;
00188   AttrAccumType::const_iterator ita = attributeAccumulator_.find(name);
00189   if (ita != attributeAccumulator_.end())
00190     {
00191       tv = attributeAccumulator_[name];
00192       if (tv.size() < attributes_.size())
00193         {
00194           appendAttributes(tv, name);
00195         }
00196       DCOUT_V('P', "DDXMLElement::getAttribute found attribute named " << name << " in a map of size " << size());
00197     }
00198   else
00199     {
00200       if (attributes_.size())
00201         {
00202           appendAttributes(tv, name);
00203         }
00204       else
00205         {
00206       DCOUT_V('P', "DDXMLAttributeAccumulator::getAttribute was asked to provide a std::vector of values for an attribute named " << name << " but there was no such attribute.");
00207               //      throw DDException(msg);
00208         }
00209     } 
00210   return tv;
00211 }
00212 
00213 // Default do-nothing processElementBases.
00214 void DDXMLElement::processElement(const std::string& name, const std::string& nmspace)
00215 {
00216   DCOUT_V('P', "DDXMLElement::processElementBase (default, do nothing) started-completed");
00217   loadText(std::string());
00218   if ( autoClear_ ) clear(); 
00219   
00220 }
00221 
00222 void DDXMLElement::loadText(const std::string& inText)
00223 {
00224   text_.push_back(inText);
00225   //  std::cout << "just put a std::string using loadText. size is now: " << text_.size() << std::endl;
00226 }
00227 
00228 void DDXMLElement::appendText(const std::string& inText)
00229 {
00230   static const std::string cr("\n");
00231   if (text_.size() > 0) {
00232     text_[text_.size() - 1] += cr;
00233     text_[text_.size() - 1] += inText ;
00234   } else
00235     {
00236       std::string msg = "DDXMLElement::appendText could not append to non-existent text.";
00237       throwError(msg);
00238     }
00239 }
00240 
00241 const std::string DDXMLElement::getText(size_t tindex) const
00242 {
00243   if (tindex > text_.size()) {
00244     std::string msg = "DDXMLElement::getText tindex is greater than text_.size()).";
00245     throwError(msg);
00246   }
00247   return text_[tindex];
00248 }
00249 
00250  bool DDXMLElement::gotText() const
00251  {
00252    if (text_.size() != 0)
00253      return true;
00254    return false;
00255  }
00256 
00257 std::ostream & operator<<(std::ostream & os, const DDXMLElement & element)
00258 {
00259   element.stream(os);
00260   return os;
00261 }
00262 
00263 void DDXMLElement::stream(std::ostream & os) const
00264 {
00265   os << "Output of current element attributes:" << std::endl;
00266   for (std::vector<DDXMLAttribute>::const_iterator itv = attributes_.begin();
00267        itv != attributes_.end(); ++itv)
00268     {
00269       for (DDXMLAttribute::const_iterator it = itv->begin(); 
00270            it != itv->end(); ++it)
00271         os << it->first <<  " = " << it->second << "\t";
00272       os << std::endl;
00273     }
00274 }                        
00275 
00276 void DDXMLElement::appendAttributes(std::vector<std::string> & tv
00277                                               , const std::string& name)
00278 {
00279   for (size_t i = tv.size(); i < attributes_.size(); ++i)
00280     {
00281       DDXMLAttribute::const_iterator itnv = attributes_[i].find(name);
00282       if (itnv != attributes_[i].end())
00283         tv.push_back(itnv->second);
00284       else
00285         tv.push_back("");
00286     }  
00287 }
00288 
00289 // Number of elements accumulated.
00290 size_t DDXMLElement::size() const
00291 {
00292   return attributes_.size();
00293 }
00294 
00295 std::vector<DDXMLAttribute>::const_iterator DDXMLElement::begin()
00296 {
00297   myIter_ = attributes_.begin();
00298   return attributes_.begin();
00299 }
00300 
00301 std::vector<DDXMLAttribute>::const_iterator DDXMLElement::end()
00302 {
00303   myIter_ = attributes_.end();
00304   return attributes_.end();
00305 }
00306 
00307 std::vector<DDXMLAttribute>::const_iterator& DDXMLElement::operator++(int inc)
00308 {
00309   myIter_ = myIter_ + inc;
00310   return myIter_;
00311 }
00312 
00313 
00314 const std::string& DDXMLElement::parent() const {
00315   DDLSAX2FileHandler* s2han = DDLParser::instance()->getDDLSAX2FileHandler();
00316   return s2han->parent();
00317 }
00318 
00319 // yet another :-)
00320 std::string DDXMLElement::itostr(int in)
00321 {
00322   std::ostringstream ostr;
00323   ostr << in;
00324   return ostr.str();
00325 }
00326 
00327 bool DDXMLElement::isEmpty () const
00328 {
00329   return (attributes_.size() == 0 ? true : false);
00330 }
00331 
00332 void DDXMLElement::throwError( const std::string& keyMessage ) const 
00333 {
00334     std::string msg = keyMessage + "\n";
00335     msg += " Element " + DDLParser::instance()->getDDLSAX2FileHandler()->self() +"\n";
00336     msg += " File " + DDLParser::instance()->getCurrFileName() + ".\n";
00337     throw DDException(msg);
00338 }

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