libzypp  17.14.0
ProductFileReader.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 #include "zypp/base/Logger.h"
14 #include "zypp/base/Exception.h"
15 #include "zypp/base/Functional.h"
16 
17 #include "zypp/PathInfo.h"
18 
22 #include "zypp/parser/xml/Reader.h"
23 
24 using std::endl;
25 
27 namespace zypp
28 {
29  namespace parser
31  {
32 
34  //
35  // class ProductFileData::Upgrade
36  //
38 
40  {
41  std::string _name;
42  std::string _summary;
43  std::string _repository;
44  std::string _product;
46  std::string _status;
47  };
48 
50  : _pimpl( allocated_r ? allocated_r : new Impl )
51  {}
52 
53  std::string ProductFileData::Upgrade::name() const { return _pimpl->_name; }
54  std::string ProductFileData::Upgrade::summary() const { return _pimpl->_summary; }
55  std::string ProductFileData::Upgrade::repository() const { return _pimpl->_repository; }
56  std::string ProductFileData::Upgrade::product() const { return _pimpl->_product; }
57  bool ProductFileData::Upgrade::notify() const { return _pimpl->_notify; }
58  std::string ProductFileData::Upgrade::status() const { return _pimpl->_status; }
59 
61  //
62  // class ProductFileData
63  //
65 
67  {
72 
73  std::string _shortName;
74  std::string _summary;
75 
76  std::string _productline;
77  std::string _registerTarget;
78  std::string _registerRelease;
79  std::string _registerFlavor;
80 
81  std::string _updaterepokey;
82 
84  };
85 
87  : _pimpl( allocated_r ? allocated_r : new Impl )
88  {}
89 
93  Arch ProductFileData::arch() const { return _pimpl->_arch; }
94 
95  std::string ProductFileData::shortName() const { return _pimpl->_shortName; }
96  std::string ProductFileData::summary() const { return _pimpl->_summary; }
97 
98  std::string ProductFileData::productline() const { return _pimpl->_productline; }
99  std::string ProductFileData::registerTarget() const { return _pimpl->_registerTarget; }
101  std::string ProductFileData::registerFlavor() const { return _pimpl->_registerFlavor; }
102 
103  std::string ProductFileData::updaterepokey() const { return _pimpl->_updaterepokey; }
104 
106 
107  std::ostream & operator<<( std::ostream & str, const ProductFileData & obj )
108  {
109  str << str::form( "|product|%s|%s|%s|%s|",
110  obj.name().c_str(),
111  obj.edition().c_str(),
112  obj.arch().c_str(),
113  obj.vendor().c_str() );
114  if ( ! obj.upgrades().empty() )
115  {
116  for_( it, obj.upgrades().begin(), obj.upgrades().end() )
117  str << endl << " " << *it;
118  }
119  return str;
120  }
121 
122  std::ostream & operator<<( std::ostream & str, const ProductFileData::Upgrade & obj )
123  {
124  str << str::form( "|upgrade|%s|%s|%s|%s|%s|",
125  obj.name().c_str(),
126  obj.repository().c_str(),
127  obj.product().c_str(),
128  obj.status().c_str(),
129  (obj.notify() ? "notify" : "noNotify") );
130  return str;
131  }
133  //
134  // class ProductFileReader
135  //
137 
138  struct ProductNode : public xml::ParseDef
139  {
141  : ParseDef( "product", MANDTAORY )
142  , _pdata( pdata_r )
143  {
144  (*this)
145  ("vendor", OPTIONAL, xml::parseDefAssign( _pdata._vendor ) )
146  ("name", MANDTAORY, xml::parseDefAssign( _pdata._name ) )
147  ("version", MANDTAORY, xml::parseDefAssign( _version ) )
148  ("release", MANDTAORY, xml::parseDefAssign( _release ) )
149  ("arch", MANDTAORY, xml::parseDefAssign( _pdata._arch ) )
150  ("shortsummary", OPTIONAL, xml::parseDefAssign( _pdata._shortName ) )
151  ("summary", MULTIPLE_OPTIONAL, xml::parseDefAssign( _ttext )( "lang", _tlocale )
152  >>bind( &ProductNode::doneLocalizedDefault, this, _1, boost::ref(_pdata._summary) ))
153  ("productline", OPTIONAL, xml::parseDefAssign( _pdata._productline ) )
154  ("register", OPTIONAL)
155  ("updaterepokey", OPTIONAL, xml::parseDefAssign( _pdata._updaterepokey ) )
156  ("upgrades", OPTIONAL)
157  ;
158 
159  (*this)["register"]
160  ("target", OPTIONAL, xml::parseDefAssign( _pdata._registerTarget ) )
161  ("release", OPTIONAL, xml::parseDefAssign( _pdata._registerRelease ) )
162  ("flavor", OPTIONAL, xml::parseDefAssign( _pdata._registerFlavor ) )
163  ;
164 
165  (*this)["upgrades"]
166  ("upgrade", MULTIPLE_OPTIONAL, xml::parseDefAssign()
167  >> bind( &ProductNode::doneUpgrade, this, _1 ))
168  ;
169 
170  (*this)["upgrades"]["upgrade"]
171  ("name", OPTIONAL, xml::parseDefAssign( _upgrade._name ) )
172  ("summary", OPTIONAL, xml::parseDefAssign( _upgrade._summary ) )
173  ("repository", OPTIONAL, xml::parseDefAssign( _upgrade._repository ) )
174  ("product", OPTIONAL, xml::parseDefAssign( _upgrade._product ) )
175  ("notify", OPTIONAL, xml::parseDefAssign( _upgrade._notify ) )
176  ("status", OPTIONAL, xml::parseDefAssign( _upgrade._status ) )
177  ;
178 
179  // </product> callback to build edition.
180  setConsumer( xml::parseDefAssign() >> bind( &ProductNode::done, this, _1 ) );
181  // xml::ParseDef::_debug = true;
182  }
183 
185  void doneUpgrade( const xml::Node & _node )
186  {
188  _pdata._upgrades.push_back( cdata );
190  }
192  void doneLocalizedDefault( const xml::Node & _node, std::string & store_r )
193  {
194  // take 1st or default
195  if ( store_r.empty() || _tlocale.empty() )
196  store_r = _ttext;
197  }
198 
200  void done( const xml::Node & _node )
201  {
203  }
204 
205  private:
207 
208  std::string _version;
209  std::string _release;
210 
211  std::string _ttext;
212  std::string _tlocale;
213 
215  };
216 
217  bool ProductFileReader::parse( const InputStream & input_r ) const
218  {
219  MIL << "+++" << input_r << endl;
220  bool ret = true;
221 
222  ProductFileData::Impl * pdataImpl = 0;
223  ProductFileData pdata( (pdataImpl = new ProductFileData::Impl) );
224 
225  try
226  {
227  xml::Reader reader( input_r );
228  ProductNode rootNode( *pdataImpl );
229  rootNode.take( reader );
230 
231  }
232  catch ( const Exception & err )
233  {
234  // parse error
235  ERR << err << endl;
236  ERR << "---" << ret << " - " << input_r << endl;
237  return ret;
238  }
239 
240  if ( _consumer )
241  {
242  ret = _consumer( pdata );
243  }
244 
245  MIL << "---" << ret << " - " << input_r << endl;
246  return ret;
247  }
248 
250 
251  bool ProductFileReader::scanDir( const Consumer & consumer_r, const Pathname & dir_r )
252  {
253  std::list<Pathname> retlist;
254  int res = filesystem::readdir( retlist, dir_r, /*dots*/false );
255  if ( res != 0 )
256  {
257  WAR << "scanDir " << dir_r << " failed (" << res << ")" << endl;
258  return true;
259  }
260 
261  ProductFileReader reader( consumer_r );
262  for_( it, retlist.begin(), retlist.end() )
263  {
264  if ( PathInfo( *it, PathInfo::LSTAT ).isFile() && ! reader.parse( *it ) )
265  {
266  return false; // consumer_r request to stop parsing.
267  }
268  }
269  return true;
270  }
271 
273  {
274  if ( ! PathInfo( file_r ).isFile() )
275  {
276  WAR << "scanFile " << PathInfo( file_r ) << " is not a file." << endl;
277  return ProductFileData();
278  }
279 
280  ProductFileData ret;
281  ProductFileReader reader( functor::getFirst( ret ), file_r );
282  return ret;
283  }
284 
286  } // namespace parser
289 } // namespace zypp
ProductFileData::Impl & _pdata
#define MIL
Definition: Logger.h:79
ParseDef(const std::string &name_r, Mode mode_r)
Definition: ParseDef.cc:369
Define a xml node structure to parse.
Definition: ParseDef.h:128
Architecture.
Definition: Arch.h:36
static ProductFileData scanFile(const Pathname &file_r)
Parse one file (or symlink) and return the ProductFileData parsed.
GetFirst< Tp > getFirst(Tp &result_r)
Convenience function for creating GetFirst.
Definition: Functional.h:382
String related utilities and Regular expression matching.
Access to the sat-pools string space.
Definition: IdString.h:41
std::string registerFlavor() const
std::ostream & operator<<(std::ostream &str, const IniDict &obj)
Definition: IniDict.cc:143
Helper to create and pass std::istream.
Definition: InputStream.h:56
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:28
Edition represents [epoch:]version[-release]
Definition: Edition.h:60
bool parse(const InputStream &input_r=InputStream()) const
Parse the input stream and call _consumer for each parsed section.
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition: String.cc:36
const char * c_str() const
Definition: Arch.h:59
#define ERR
Definition: Logger.h:81
RWCOW_pointer< Impl > _pimpl
void done(const xml::Node &_node)
finaly
xmlTextReader based interface to Reader's current node.
Definition: Node.h:35
ProductNode(ProductFileData::Impl &pdata_r)
void take(Reader &reader_r)
Parse the node.
Definition: ParseDef.cc:439
#define WAR
Definition: Logger.h:80
std::string registerRelease() const
void doneUpgrade(const xml::Node &_node)
collect _upgrade
const char * c_str() const
Conversion to const char *
Definition: IdString.cc:50
void doneLocalizedDefault(const xml::Node &_node, std::string &store_r)
collect localized data
int readdir(std::list< std::string > &retlist_r, const Pathname &path_r, bool dots_r)
Return content of directory via retlist.
Definition: PathInfo.cc:589
ProductFileData::Upgrade::Impl _upgrade
Base class for Exception.
Definition: Exception.h:145
Data returned by ProductFileReader.
Upgrade(Impl *allocated_r=0)
Ctor takes ownership of allocated_r.
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:220
void setConsumer(const shared_ptr< ParseDefConsume > &target_r)
Set data consumer.
Definition: ParseDef.cc:423
ProductFileData(Impl *allocated_r=0)
Ctor takes ownership of allocated_r.
std::vector< Upgrade > Upgrades
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
Parser for /etc/products.d enries (just relevant entires).
const char * c_str() const
Definition: IdStringType.h:105
std::string registerTarget() const
static bool scanDir(const Consumer &consumer_r, const Pathname &dir_r)
Parse all files (no symlinks) in dir_r and call consumer_r for each ProductFileData parsed.
function< bool(const ProductFileData &)> Consumer
Callback being invoked for each ProductFileData parsed.
const Upgrades & upgrades() const