CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/DetectorDescription/Parser/src/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 #include "DetectorDescription/Parser/src/DDXMLElement.h"
00009 #include "DetectorDescription/Parser/interface/DDLSAX2FileHandler.h"
00010 #include "DetectorDescription/Parser/interface/DDLParser.h"
00011 
00012 #include "DetectorDescription/Base/interface/DDdebug.h"
00013 
00014 #include <algorithm>
00015 #include <iostream>
00016 #include <sstream>
00017 
00018 DDXMLElement::DDXMLElement( DDLElementRegistry* myreg )
00019   : myRegistry_( myreg ),
00020     attributes_(),
00021     text_(),
00022     autoClear_( false )
00023 {}
00024 
00025 DDXMLElement::DDXMLElement( DDLElementRegistry* myreg, const bool& clearme )
00026   : myRegistry_( myreg ),
00027     attributes_(),
00028     text_(),
00029     autoClear_( clearme )
00030 {}
00031 
00032 DDXMLElement::~DDXMLElement( void )
00033 {}
00034 
00035 // For pre-processing, after attributes are loaded.  Default, do nothing!
00036 void
00037 DDXMLElement::preProcessElement( const std::string& name, const std::string& nmspace, DDCompactView& cpv )
00038 {
00039   DCOUT_V('P', "DDXMLElement::preProcessElementBase default, do nothing) started-completed.");
00040 }
00041 
00042 // This loads the attributes into the attributes_ std::vector.
00043 void
00044 DDXMLElement::loadAttributes( const std::string& elemName,
00045                               const std::vector<std::string> & names,
00046                               const std::vector<std::string> & values,
00047                               const std::string& nmspace, DDCompactView& cpv )
00048 {
00049   attributes_.resize(attributes_.size()+1);
00050   DDXMLAttribute & tAttributes =  attributes_.back();
00051   
00052   // adds attributes
00053   for (size_t i = 0; i < names.size(); ++i)
00054   {
00055     //      tAttributes[ names[i] ] = values[i];
00056     tAttributes.insert(std::make_pair(names[i], values[i]));
00057   }
00058 
00059   preProcessElement( elemName, nmspace, cpv );
00060   DCOUT_V('P', "DDXMLElement::loadAttributes completed. " << *this);
00061 }
00062 
00063 // clear data.
00064 void
00065 DDXMLElement::clear( void )
00066 {
00067   text_.clear();
00068   attributes_.clear();
00069   attributeAccumulator_.clear();
00070 }
00071 
00072 // Access to current attributes by name.
00073 const std::string &
00074 DDXMLElement::getAttribute( const std::string& name ) const
00075 {
00076   static const std::string ldef;
00077   if (attributes_.size())
00078     return get(name, attributes_.size() - 1);
00079   return ldef;
00080 }
00081 
00082 const DDXMLAttribute&
00083 DDXMLElement::getAttributeSet( size_t aIndex ) const 
00084 {
00085   //  if (aIndex < attributes_.size())
00086   return attributes_[aIndex];  
00087 }
00088 
00089 
00090 const DDName
00091 DDXMLElement::getDDName( const std::string& defaultNS, const std::string& attname, size_t aIndex )
00092 {
00093   if (aIndex < attributes_.size()
00094       && attributes_[aIndex].find(attname) != attributes_[aIndex].end()) { 
00095     std::string ns = defaultNS;
00096     // For the user to fully control namespaces they must provide for 
00097     // all name attributes something of the form, for example:
00098     //        <Solid name="ns:name" ...
00099     // If defaultNS is "!" (magic I don't like) then find and set
00100     // the namespace properly.
00101     if ( defaultNS == "!" ) {
00102       ns = "";
00103     } 
00104     const std::string & name = attributes_[aIndex].find(attname)->second;
00105     std::string rn = name;
00106     size_t foundColon= name.find(':');
00107     if (foundColon != std::string::npos) {
00108       ns = name.substr(0,foundColon);
00109       rn = name.substr(foundColon+1);
00110 
00111     }
00112     //    std::cout << "Name: " << rn << " Namespace: " << ns << std::endl;
00113     return DDName(rn, ns);
00114   }
00115   //  std::cout << "no " << attname <<  " default namespace: " << defaultNS << " at index " << aIndex << std::endl;
00116   std::string msg = "DDXMLElement:getDDName failed.  It was asked to make ";
00117   msg += "a DDName using attribute: " + attname;
00118   msg += " in position: " + itostr(int(aIndex)) + ".  There are ";
00119   msg += itostr(int(attributes_.size())) + " entries in the element.";
00120   throwError(msg);
00121   return DDName("justToCompile", "justToCompile"); // used to make sure it compiles
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 
00156 
00157 // Returns a specific value from the aIndex set of attributes.
00158 const std::string &
00159 DDXMLElement::get( const std::string& name, const size_t aIndex ) const
00160 {
00161   static const std::string sts;
00162   if (aIndex < attributes_.size())
00163   {
00164     DDXMLAttribute::const_iterator it = attributes_[aIndex].find(name);
00165     if (attributes_[aIndex].end() == it)
00166     {
00167       DCOUT_V('P', "WARNING: DDXMLElement::get did not find the requested attribute: "  << name << std::endl << *this);
00168       return sts;
00169     }
00170     else
00171       return (it->second);
00172   }
00173   std::string msg = "DDXMLElement:get failed.  It was asked for attribute " + name;
00174   msg += " in position " + itostr(int(aIndex)) + " when there are only ";
00175   msg += itostr(int(attributes_.size())) + " in the element storage.\n";
00176   throwError(msg);
00177   // meaningless...
00178   return sts;
00179 }
00180 
00181 // Returns a specific set of values as a std::vector of std::strings,
00182 // given the attribute name.
00183 std::vector<std::string>
00184 DDXMLElement::getVectorAttribute( const std::string& name )
00185 {
00186   //  The idea here is that the attributeAccumulator_ is a cache of
00187   //  on-the-fly generation from the std::vector<DDXMLAttribute> and the 
00188   //  reason is simply to speed things up if it is requested more than once.
00189   std::vector<std::string> tv;
00190   AttrAccumType::const_iterator ita = attributeAccumulator_.find(name);
00191   if (ita != attributeAccumulator_.end())
00192   {
00193     tv = attributeAccumulator_[name];
00194     if (tv.size() < attributes_.size())
00195     {
00196       appendAttributes(tv, name);
00197     }
00198     DCOUT_V('P', "DDXMLElement::getAttribute found attribute named " << name << " in a map of size " << size());
00199   }
00200   else
00201   {
00202     if (attributes_.size())
00203     {
00204       appendAttributes(tv, name);
00205     }
00206     else
00207     {
00208       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.");
00209       //      throw DDException(msg);
00210     }
00211   } 
00212   return tv;
00213 }
00214 
00215 // Default do-nothing processElementBases.
00216 void
00217 DDXMLElement::processElement( const std::string& name, const std::string& nmspace, DDCompactView& cpv )
00218 {
00219   DCOUT_V('P', "DDXMLElement::processElementBase (default, do nothing) started-completed");
00220   loadText(std::string());
00221   if ( autoClear_ ) clear(); 
00222   
00223 }
00224 
00225 void
00226 DDXMLElement::loadText( const std::string& inText )
00227 {
00228   text_.push_back(inText);
00229   //  std::cout << "just put a std::string using loadText. size is now: " << text_.size() << std::endl;
00230 }
00231 
00232 void
00233 DDXMLElement::appendText( const std::string& inText )
00234 {
00235   static const std::string cr("\n");
00236   if (text_.size() > 0) {
00237     text_[text_.size() - 1] += cr;
00238     text_[text_.size() - 1] += inText ;
00239   } else
00240   {
00241     std::string msg = "DDXMLElement::appendText could not append to non-existent text.";
00242     throwError(msg);
00243   }
00244 }
00245 
00246 const std::string
00247 DDXMLElement::getText( size_t tindex ) const
00248 {
00249   if (tindex > text_.size()) {
00250     std::string msg = "DDXMLElement::getText tindex is greater than text_.size()).";
00251     throwError(msg);
00252   }
00253   return text_[tindex];
00254 }
00255 
00256 bool
00257 DDXMLElement::gotText( void ) const
00258 {
00259   if (text_.size() != 0)
00260     return true;
00261   return false;
00262 }
00263 
00264 std::ostream & operator<<( std::ostream & os, const DDXMLElement & element )
00265 {
00266   element.stream(os);
00267   return os;
00268 }
00269 
00270 void
00271 DDXMLElement::stream( std::ostream & os ) const
00272 {
00273   os << "Output of current element attributes:" << std::endl;
00274   for (std::vector<DDXMLAttribute>::const_iterator itv = attributes_.begin();
00275        itv != attributes_.end(); ++itv)
00276   {
00277     for (DDXMLAttribute::const_iterator it = itv->begin(); 
00278          it != itv->end(); ++it)
00279       os << it->first <<  " = " << it->second << "\t";
00280     os << std::endl;
00281   }
00282 }                        
00283 
00284 void
00285 DDXMLElement::appendAttributes( std::vector<std::string> & tv,
00286                                 const std::string& name )
00287 {
00288   for (size_t i = tv.size(); i < attributes_.size(); ++i)
00289   {
00290     DDXMLAttribute::const_iterator itnv = attributes_[i].find(name);
00291     if (itnv != attributes_[i].end())
00292       tv.push_back(itnv->second);
00293     else
00294       tv.push_back("");
00295   }  
00296 }
00297 
00298 // Number of elements accumulated.
00299 size_t
00300 DDXMLElement::size( void ) const
00301 {
00302   return attributes_.size();
00303 }
00304 
00305 std::vector<DDXMLAttribute>::const_iterator
00306 DDXMLElement::begin( void )
00307 {
00308   myIter_ = attributes_.begin();
00309   return attributes_.begin();
00310 }
00311 
00312 std::vector<DDXMLAttribute>::const_iterator
00313 DDXMLElement::end( void )
00314 {
00315   myIter_ = attributes_.end();
00316   return attributes_.end();
00317 }
00318 
00319 std::vector<DDXMLAttribute>::const_iterator&
00320 DDXMLElement::operator++( int inc )
00321 {
00322   myIter_ = myIter_ + inc;
00323   return myIter_;
00324 }
00325 
00326 const std::string&
00327 DDXMLElement::parent( void ) const
00328 {
00329   return parentElement_;
00330 }
00331 
00332 void
00333 DDXMLElement::setParent( const std::string& pename )
00334 {
00335   parentElement_ = pename;
00336 }
00337 
00338 void
00339 DDXMLElement::setSelf( const std::string& sename )
00340 {
00341   myElement_ = sename;
00342 }
00343 
00344 // yet another :-)
00345 std::string
00346 DDXMLElement::itostr( int in )
00347 {
00348   std::ostringstream ostr;
00349   ostr << in;
00350   return ostr.str();
00351 }
00352 
00353 bool
00354 DDXMLElement::isEmpty( void ) const
00355 {
00356   return (attributes_.size() == 0 ? true : false);
00357 }
00358 
00359 void
00360 DDXMLElement::throwError( const std::string& keyMessage ) const 
00361 {
00362   std::string msg = keyMessage + "\n";
00363   //    if (myElement_) {
00364   msg += " Element " + myElement_ +"\n";
00365   //    }
00366   //    msg += " File " + DDLParser::instance()->getCurrFileName() + ".\n";
00367   throw DDException(msg);
00368 }