SysContent.cc
Go to the documentation of this file.00001
00002
00003
00004
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
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 }
00055
00057
00058
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
00091
00092
00093 std::ostream & Writer::Impl::writeXml( std::ostream & str ) const
00094 {
00095
00096 str << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
00097 str << "<syscontent>\n";
00098
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
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
00124 str << "</syscontent>" << endl;
00125 return str;
00126 };
00127
00129
00130
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
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
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
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
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 }
00371
00373
00374
00375
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
00398 rootNode.take( reader );
00399 }
00400
00402
00403
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
00442
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 }
00456 }