CMS 3D CMS Logo

FlagXML.h

Go to the documentation of this file.
00001 // Author : Samvel Khalatian (samvel at fnal dot gov)
00002 // Created: 06/01/06
00003 // License: GPL
00004 
00005 #ifndef FLAG_XML_H
00006 #define FLAG_XML_H
00007 
00008 #include <list>
00009 #include <map>
00010 
00011 #include <boost/serialization/nvp.hpp>
00012 #include <boost/serialization/string.hpp>
00013 #include <boost/serialization/list.hpp>
00014 
00015 #include "CalibTracker/SiStripRunSummary/interface/ClassIDBase.h"
00016 #include "CalibTracker/SiStripRunSummary/interface/ClassID.h"
00017 #include "CalibTracker/SiStripRunSummary/interface/Flag.h"
00018 
00019 // Declare class to save compilation time: used for conversion of flags
00020 // Txt -> XML
00021 class FlagTxt;
00022 
00031 class FlagXML: public Flag {
00032   public:
00033     typedef std::list<FlagXML *> LChildren;
00034 
00035     FlagXML(): Flag() { poParentFlag_ = 0; }
00036     virtual ~FlagXML();
00037 
00049     template<class T> FlagXML *createChild();
00050 
00061     template<class T> FlagXML *getChild   () const;
00062 
00075     template<class T> int getChildren( LChildren &roLChildren) const;
00076 
00087     virtual bool setState( const State &reSTATE);
00088 
00089   protected:
00096     FlagXML( const FlagXML &roFLAGXML);
00097 
00104     FlagXML( const FlagTxt &roFLAGTXT);
00105 
00127     inline virtual 
00128       int isChildValid( const FlagXML * /* poCHILD_CANDIDATE */) const {
00129 
00130       // No children are allowed by default
00131       return 0;
00132     }
00133 
00134   private:
00139     friend class FlagTxt;
00140 
00141     typedef ClassIDBase::ID FlagID; 
00142     typedef std::multimap<FlagID,FlagXML *> MChildFlags;
00143 
00153     FlagXML &operator =( const FlagXML &roFLAGXML);
00154 
00162     void updateState( const State &reCHILD_STATE);
00163 
00170     void addChild( FlagXML *poSubFlag);
00171 
00177     friend class boost::serialization::access;
00178 
00179     template<class Archive>
00180       void save( Archive &roArchive, const unsigned int &rnVersion) const;
00181 
00182     template<class Archive>
00183       void load( Archive &roArchive, const unsigned int &rnVersion);
00184 
00185     BOOST_SERIALIZATION_SPLIT_MEMBER()
00191     FlagXML     *poParentFlag_;
00192     MChildFlags  oMChildFlags_;
00193 };
00194 
00195 // --[ TEMPLATES IMPLEMENTATION ]----------------------------------------------
00196 //                                                  --[ PUBLIC ]--
00201 template<class T>
00202   FlagXML *FlagXML::createChild() {
00203     FlagXML *poResult = 0;
00204     
00205     try {
00206       // Create object of requested class: may throw exception
00207       FlagXML *poFlag = new T();
00208 
00209       // Get number of allowed children
00210       int nChildFlags = isChildValid( poFlag);
00211 
00212       FlagID nID = ClassID<T>::get();
00213 
00214       switch( nChildFlags) {
00215         case 0:
00216           // No child flags allowed
00217           delete poFlag;
00218           break;
00219         case -1:
00220           // No limit on child flags
00221           {
00222             // Parent will be set by addChild(...)
00223             addChild( poFlag);
00224 
00225             // Update parent state: child may be put into ERROR state by 
00226             // default (this is specified in Flag class). Unfortunately
00227             // parent won't be updated
00228             updateState( poFlag->getState());
00229 
00230             poResult = poFlag;
00231           }
00232           break;
00233         default:
00234           // All other cases
00235           {
00236             if( 0 < nChildFlags) {
00237               // Check if Flag already exists
00238               std::pair<MChildFlags::const_iterator, 
00239                         MChildFlags::const_iterator> oFoundChildren = 
00240                 oMChildFlags_.equal_range( nID);
00241 
00242               if( nChildFlags > std::distance( oFoundChildren.first,
00243                                                oFoundChildren.second)) {
00244 
00245                 // Parent will be set by addChild(...)
00246                 addChild( poFlag);
00247 
00248                 // Update parent state: child may be put into ERROR state by 
00249                 // default (this is specified in Flag class). Unfortunately
00250                 // parent won't be updated
00251                 updateState( poFlag->getState());
00252 
00253                 poResult = poFlag;
00254               } else {
00255                 // No more child tags are allowed
00256                 delete poFlag;
00257               }
00258             } else {
00259               // Unsupported value of child flags returned
00260               delete poFlag;
00261             }// End check if nChildFlags is positive
00262           }
00263           break;
00264       } // End switch( nChildFlags)
00265     } catch(...) {
00266       // Ups, trying to create child of Flag that is not inherited from
00267       // given class :[
00268     }
00269 
00270     return poResult;
00271   }
00272 
00277 template<class T>
00278   FlagXML *FlagXML::getChild() const {
00279     // Get Class ID
00280     FlagID nID = ClassID<T>::get();
00281 
00282     // Find appropriate child
00283     std::pair<MChildFlags::const_iterator, MChildFlags::const_iterator>
00284       oFoundChildren = oMChildFlags_.equal_range( nID);
00285 
00286     // Return found child or invalid pointer in case child can not be found
00287     FlagXML *poChild = 0;
00288     if( 1 == std::distance( oFoundChildren.first, oFoundChildren.second)) {
00289       // One child was found: copy pointer
00290       poChild = oFoundChildren.first->second;
00291     }
00292 
00293     return poChild;
00294   }
00295 
00300 template<class T>
00301   int FlagXML::getChildren( LChildren &roLChildren) const {
00302     // Get Class ID
00303     FlagID nID = ClassID<T>::get();
00304 
00305     // Find appropriate children
00306     std::pair<MChildFlags::const_iterator, MChildFlags::const_iterator>
00307       oFoundChildren = oMChildFlags_.equal_range( nID);
00308 
00309     // Return found child or invalid pointer in case child can not be found
00310     // Return list of found children or empty one if children can not be
00311     // found
00312     roLChildren.clear();
00313     if( 0 < std::distance( oFoundChildren.first, oFoundChildren.second)) {
00314       // A number of children was found: copy them into a list and return it
00315       while( oFoundChildren.first != oFoundChildren.second) {
00316         roLChildren.push_back( ( oFoundChildren.first++)->second);
00317       }
00318     } // End check if any children are found
00319 
00320     return roLChildren.size();
00321   }
00322 
00323 //                                                  --[ PRIVATE ]--
00329 template<class Archive>
00330   void FlagXML::save( Archive &roArchive, const unsigned int &rnVersion) const {
00331     roArchive & BOOST_SERIALIZATION_NVP( eState_);
00332     roArchive & BOOST_SERIALIZATION_NVP( oComment_);
00333 
00334     // Copy Child Flags into list: we can not save map since IDs of classes
00335     // are runtime dependent. Solution: save pure list of child flags. And
00336     // Recreate map on reading the list from archive.
00337     LChildren oLChildren;
00338     for( MChildFlags::const_iterator oIter = oMChildFlags_.begin();
00339          oIter != oMChildFlags_.end();
00340          ++oIter) {
00341 
00342       oLChildren.push_back( oIter->second);
00343     }
00344 
00345     // Save Child Flags
00346     roArchive & BOOST_SERIALIZATION_NVP( oLChildren);
00347   }
00348 
00349 template<class Archive>
00350   void FlagXML::load( Archive &roArchive, const unsigned int &rnVersion) {
00351     roArchive & BOOST_SERIALIZATION_NVP( eState_);
00352     roArchive & BOOST_SERIALIZATION_NVP( oComment_);
00353 
00354     // Read Child Flags: regular list will be extracted.
00355     LChildren oLChildren;
00356     roArchive & BOOST_SERIALIZATION_NVP( oLChildren);
00357 
00358     // Reconstruct map of child flags since IDs of classes are runtime
00359     // dependent.
00360     for( LChildren::const_iterator oIter = oLChildren.begin();
00361          oIter != oLChildren.end();
00362          ++oIter) {
00363 
00364       // Parent will be set by addChild(...)
00365       addChild( *oIter);
00366     }
00367   }
00373 #endif

Generated on Tue Jun 9 17:25:52 2009 for CMSSW by  doxygen 1.5.4