libzypp  10.5.0
SysContent.cc
Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 #include "zypp/base/Logger.h"
00014 
00015 #include "zypp/SysContent.h"
00016 #include "zypp/parser/xml/Reader.h"
00017 #include "zypp/parser/xml/ParseDef.h"
00018 #include "zypp/parser/xml/ParseDefConsume.h"
00019 
00020 using std::endl;
00021 
00023 namespace zypp
00024 { 
00025 
00026   namespace syscontent
00027   { 
00028 
00030     namespace // Writer helpers
00031     { 
00032 
00037       inline std::string attrIf( const std::string & tag_r,
00038                                  const std::string & value_r )
00039       {
00040         std::string ret;
00041         if ( ! value_r.empty() )
00042           {
00043             ret += " ";
00044             ret += tag_r;
00045             ret += "=\"";
00046             ret += value_r;
00047             ret += "\"";
00048           }
00049         return ret;
00050       }
00051 
00053     } // namespace
00055 
00057     //
00058     //  CLASS NAME : Writer::Impl
00059     //
00061     class Writer::Impl
00062     {
00063     public:
00064       std::ostream & writeXml( std::ostream & str ) const;
00065 
00066     public:
00067       std::string _name;
00068       Edition     _edition;
00069       std::string _description;
00070       StorageT    _onsys;
00071 
00072     public:
00074       static shared_ptr<Impl> nullimpl()
00075       {
00076         static shared_ptr<Impl> _nullimpl( new Impl );
00077         return _nullimpl;
00078       }
00079 
00080     private:
00081       friend Impl * rwcowClone<Impl>( const Impl * rhs );
00083       Impl * clone() const
00084       { return new Impl( *this ); }
00085     };
00087 
00089     //
00090     //  METHOD NAME : Writer::Impl::writeXml
00091     //  METHOD TYPE : std::ostream &
00092     //
00093     std::ostream & Writer::Impl::writeXml( std::ostream & str ) const
00094     {
00095       // intro
00096       str << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
00097       str << "<syscontent>\n";
00098       // ident data
00099       str << "  <ident>\n";
00100       str << "    <name>" << _name << "</name>\n";
00101       str << "    <version"
00102           << attrIf( "epoch", str::numstring(_edition.epoch()) )
00103           << attrIf( "ver",   _edition.version() )
00104           << attrIf( "rel",   _edition.release() )
00105           << "/>\n";
00106       str << "    <description>" << _description << "</description>\n";
00107       str << "    <created>" << Date::now().asSeconds() << "</created>\n";
00108       str << "  </ident>\n";
00109       // ResObjects
00110       str << "  <onsys>\n";
00111       for ( iterator it = _onsys.begin(); it != _onsys.end(); ++it )
00112         {
00113           str << "    <entry"
00114               << attrIf( "kind",  (*it)->kind().asString() )
00115               << attrIf( "name",  (*it)->name() )
00116               << attrIf( "epoch", str::numstring((*it)->edition().epoch()) )
00117               << attrIf( "ver",   (*it)->edition().version() )
00118               << attrIf( "rel",   (*it)->edition().release() )
00119               << attrIf( "arch",  (*it)->arch().asString() )
00120               << "/>\n";
00121         }
00122       str << "  </onsys>\n";
00123       // extro
00124       str << "</syscontent>" << endl;
00125       return str;
00126     };
00127 
00129     //
00130     //  CLASS NAME : Writer
00131     //
00133 
00134     Writer::Writer()
00135     : _pimpl( Impl::nullimpl() )
00136     {}
00137 
00138     const std::string & Writer::name() const
00139     { return _pimpl->_name; }
00140 
00141     Writer & Writer::name( const std::string & val_r )
00142     { _pimpl->_name = val_r; return *this; }
00143 
00144     const Edition & Writer::edition() const
00145     { return _pimpl->_edition; }
00146 
00147     Writer & Writer::edition( const Edition & val_r )
00148     { _pimpl->_edition = val_r; return *this; }
00149 
00150     const std::string & Writer::description() const
00151     { return _pimpl->_description; }
00152 
00153     Writer & Writer::description( const std::string & val_r )
00154     { _pimpl->_description = val_r; return *this; }
00155 
00156     void Writer::addInstalled( const PoolItem & obj_r )
00157     {
00158       if ( obj_r.status().isInstalled() )
00159         {
00160           _pimpl->_onsys.insert( obj_r.resolvable() );
00161         }
00162     }
00163 
00164     void Writer::addIf( const PoolItem & obj_r )
00165     {
00166       if ( obj_r.status().isInstalled() != obj_r.status().transacts()
00167            && ! ( obj_r.status().transacts() && obj_r.status().isBySolver() ) )
00168         {
00169           _pimpl->_onsys.insert( obj_r.resolvable() );
00170         }
00171     }
00172 
00173     void Writer::add( const ResObject::constPtr & obj_r )
00174     { _pimpl->_onsys.insert( obj_r ); }
00175 
00176     bool Writer::empty() const
00177     { return _pimpl->_onsys.empty(); }
00178 
00179     Writer::size_type Writer::size() const
00180     { return _pimpl->_onsys.size(); }
00181 
00182     Writer::const_iterator Writer::begin() const
00183     { return _pimpl->_onsys.begin(); }
00184 
00185     Writer::const_iterator Writer::end() const
00186     { return _pimpl->_onsys.end(); }
00187 
00188     std::ostream & Writer::writeXml( std::ostream & str ) const
00189     { return _pimpl->writeXml( str ); }
00190 
00192     //
00193     //  CLASS NAME : Reader::Entry::Impl
00194     //
00195     class Reader::Entry::Impl
00196     {
00197     public:
00198       std::string _kind;
00199       std::string _name;
00200       Edition     _edition;
00201       Arch        _arch;
00202     };
00204 
00206     //
00207     //  CLASS NAME : Reader::Entry
00208     //
00210 
00211     Reader::Entry::Entry()
00212     : _pimpl( new Impl )
00213     {}
00214 
00215     Reader::Entry::Entry( const shared_ptr<Impl> & pimpl_r )
00216     : _pimpl( pimpl_r )
00217     {}
00218 
00219     const std::string & Reader::Entry::kind() const
00220     { return _pimpl->_kind; }
00221 
00222     const std::string & Reader::Entry::name() const
00223     { return _pimpl->_name; }
00224 
00225     const Edition & Reader::Entry::edition() const
00226     { return _pimpl->_edition; }
00227 
00228     const Arch & Reader::Entry::arch() const
00229     { return _pimpl->_arch; }
00230 
00232     //
00233     //  CLASS NAME : Reader::Impl
00234     //
00236     class Reader::Impl
00237     {
00238     public:
00239       Impl()
00240       {}
00241 
00242       Impl( std::istream & input_r );
00243 
00244     public:
00245       std::string _name;
00246       Edition     _edition;
00247       std::string _description;
00248       Date        _created;
00249 
00250       std::list<Entry> _content;
00251 
00252     public:
00254       static shared_ptr<Impl> nullimpl()
00255       {
00256         static shared_ptr<Impl> _nullimpl( new Impl );
00257         return _nullimpl;
00258       }
00259 
00260     private:
00261       friend Impl * rwcowClone<Impl>( const Impl * rhs );
00263       Impl * clone() const
00264       { return new Impl( *this ); }
00265     };
00267 
00269     namespace // Reader helpers
00270     { 
00271 
00272       using namespace xml;
00273 
00275       struct SycontentNode : public ParseDef
00276       {
00277         SycontentNode( Mode mode_r )
00278         : ParseDef( "syscontent", mode_r )
00279         {
00280           (*this)("ident",       OPTIONAL)
00281                  ("onsys",       OPTIONAL)
00282                  ;
00283 
00284           (*this)["ident"]
00285                  ("name",        OPTIONAL)
00286                  ("version",     OPTIONAL)
00287                  ("description", OPTIONAL)
00288                  ("created",     OPTIONAL)
00289                  ;
00290 
00291           (*this)["onsys"]
00292                  ("entry",       MULTIPLE_OPTIONAL)
00293                  ;
00294         }
00295       };
00296 
00298       struct ConsumeEdition : public ParseDefConsume
00299       {
00300         ConsumeEdition( Edition & value_r )
00301         : _value( & value_r )
00302         {}
00303 
00304         virtual void start( const Node & node_r )
00305         {
00306           *_value = Edition( node_r.getAttribute("ver").asString(),
00307                              node_r.getAttribute("rel").asString(),
00308                              node_r.getAttribute("epoch").asString() );
00309         }
00310 
00311         Edition *_value;
00312       };
00313 
00315       struct ConsumeString : public ParseDefConsume
00316       {
00317         ConsumeString( std::string & value_r )
00318         : _value( & value_r )
00319         {}
00320 
00321         virtual void text( const Node & node_r )
00322         {
00323           *_value = node_r.value().asString();
00324         }
00325 
00326         std::string *_value;
00327       };
00328 
00330       struct ConsumeDate : public ParseDefConsume
00331       {
00332         ConsumeDate( Date & value_r )
00333         : _value( & value_r )
00334         {}
00335 
00336         virtual void text( const Node & node_r )
00337         {
00338           *_value = node_r.value().asString();
00339         }
00340 
00341         Date *_value;
00342       };
00343 
00345       struct ConsumeEntries : public ParseDefConsume
00346       {
00347         ConsumeEntries( std::list<Reader::Entry> & value_r )
00348         : _value( & value_r )
00349         {}
00350 
00351         virtual void start( const Node & node_r )
00352         {
00353           shared_ptr<Reader::Entry::Impl> centry( new Reader::Entry::Impl );
00354 
00355           centry->_kind = node_r.getAttribute("kind").asString();
00356           centry->_name = node_r.getAttribute("name").asString();
00357           centry->_edition = Edition( node_r.getAttribute("ver").asString(),
00358                                       node_r.getAttribute("rel").asString(),
00359                                       node_r.getAttribute("epoch").asString() );
00360           centry->_arch = Arch( node_r.getAttribute("arch").asString() );
00361 
00362           _value->push_back( Reader::Entry( centry ) );
00363         }
00364 
00365         std::list<Reader::Entry> *_value;
00366       };
00367 
00369     } // namespace
00371 
00373     //
00374     //  METHOD NAME : Reader::Impl::Impl
00375     //  METHOD TYPE : Constructor
00376     //
00377     Reader::Impl::Impl( std::istream & input_r )
00378     {
00379       xml::Reader reader( input_r );
00380       SycontentNode rootNode( xml::ParseDef::MANDTAORY );
00381 
00382       rootNode["ident"]["name"].setConsumer
00383       ( new ConsumeString( _name ) );
00384 
00385       rootNode["ident"]["version"].setConsumer
00386       ( new ConsumeEdition( _edition ) );
00387 
00388       rootNode["ident"]["description"].setConsumer
00389       ( new ConsumeString( _description ) );
00390 
00391       rootNode["ident"]["created"].setConsumer
00392       ( new ConsumeDate( _created ) );
00393 
00394       rootNode["onsys"]["entry"].setConsumer
00395       ( new ConsumeEntries( _content ) );
00396 
00397       // parse
00398       rootNode.take( reader );
00399     }
00400 
00402     //
00403     //  CLASS NAME : Reader
00404     //
00406 
00407     Reader::Reader()
00408     : _pimpl( Impl::nullimpl() )
00409     {}
00410 
00411     Reader::Reader( std::istream & input_r )
00412     : _pimpl( new Impl( input_r ) )
00413     {}
00414 
00415     const std::string & Reader::name() const
00416     { return _pimpl->_name; }
00417 
00418     const Edition & Reader::edition() const
00419     { return _pimpl->_edition; }
00420 
00421     const std::string & Reader::description() const
00422     { return _pimpl->_description; }
00423 
00424     const Date & Reader::ctime() const
00425     { return _pimpl->_created; }
00426 
00427     bool Reader::empty() const
00428     { return _pimpl->_content.empty(); }
00429 
00430     Reader::size_type Reader::size() const
00431     { return _pimpl->_content.size(); }
00432 
00433     Reader::const_iterator Reader::begin() const
00434     { return _pimpl->_content.begin(); }
00435 
00436     Reader::const_iterator Reader::end() const
00437     { return _pimpl->_content.end(); }
00438 
00439     /******************************************************************
00440      **
00441      ** FUNCTION NAME : operator<<
00442      ** FUNCTION TYPE : inline std::ostream &
00443     */
00444     std::ostream & operator<<( std::ostream & str, const Reader & obj )
00445     {
00446       return str << "syscontent(" << obj.name() << "-" << obj.edition()
00447                  << ", " << obj.size() << " entries"
00448                  << ",  created " << obj.ctime()
00449                  << ")";
00450     }
00451 
00453   } // namespace syscontent
00456 } // namespace zypp