libzypp 17.25.10
RepoindexFileReader.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 #include <unordered_map>
14 
15 #include <zypp/base/String.h>
16 #include <zypp/base/Logger.h>
17 #include <zypp/base/Gettext.h>
18 #include <zypp/base/InputStream.h>
20 
21 #include <zypp/Pathname.h>
22 
23 #include <zypp/parser/xml/Reader.h>
25 
26 #include <zypp/RepoInfo.h>
27 
29 
30 
31 #undef ZYPP_BASE_LOGGER_LOGGROUP
32 #define ZYPP_BASE_LOGGER_LOGGROUP "parser"
33 
34 using std::endl;
35 
36 namespace zypp
37 {
38  namespace parser
39  {
40  using xml::Reader;
41  using xml::XmlString;
42 
44  namespace
45  {
46  class VarReplacer : private base::NonCopyable
47  {
48  public:
50  void setVar( const std::string & key_r, const std::string & val_r )
51  {
52  //MIL << "*** Inject " << key_r << " = " << val_r;
53  _vars[key_r] = replace( val_r );
54  //MIL << " (" << _vars[key_r] << ")" << endl;
55  }
56 
57  std::string replace( const std::string & val_r ) const
58  {
59  std::string::size_type vbeg = val_r.find( "%{", 0 );
60  if ( vbeg == std::string::npos )
61  return val_r;
62 
63  str::Str ret;
64  std::string::size_type cbeg = 0;
65  for( ; vbeg != std::string::npos; vbeg = val_r.find( "%{", vbeg ) )
66  {
67  std::string::size_type nbeg = vbeg+2;
68  std::string::size_type nend = val_r.find( "}", nbeg );
69  if ( nend == std::string::npos )
70  {
71  WAR << "Incomplete variable in '" << val_r << "'" << endl;
72  break;
73  }
74  const auto & iter = _vars.find( val_r.substr( nbeg, nend-nbeg ) );
75  if ( iter != _vars.end() )
76  {
77  if ( cbeg < vbeg )
78  ret << val_r.substr( cbeg, vbeg-cbeg );
79  ret << iter->second;
80  cbeg = nend+1;
81  }
82  else
83  WAR << "Undefined variable %{" << val_r.substr( nbeg, nend-nbeg ) << "} in '" << val_r << "'" << endl;
84  vbeg = nend+1;
85  }
86  if ( cbeg < val_r.size() )
87  ret << val_r.substr( cbeg );
88 
89  return ret;
90  }
91  private:
92  std::unordered_map<std::string,std::string> _vars;
93  };
94  } // namespace
96 
98  //
99  // CLASS NAME : RepoindexFileReader::Impl
100  //
102  {
103  public:
109  Impl(const InputStream &is, const ProcessResource & callback);
110 
114  bool consumeNode( Reader & reader_r );
115 
117 
118  private:
119  bool getAttrValue( const std::string & key_r, Reader & reader_r, std::string & value_r )
120  {
121  const XmlString & s( reader_r->getAttribute( key_r ) );
122  if ( s.get() )
123  {
124  value_r = _replacer.replace( s.asString() );
125  return !value_r.empty();
126  }
127  value_r.clear();
128  return false;
129  }
130 
131  private:
134  VarReplacer _replacer;
135  };
137 
139  const ProcessResource & callback)
140  : _callback(callback)
141  {
142  Reader reader( is );
143  MIL << "Reading " << is.path() << endl;
144  reader.foreachNode( bind( &RepoindexFileReader::Impl::consumeNode, this, _1 ) );
145  }
146 
147  // --------------------------------------------------------------------------
148 
149  /*
150  * xpath and multiplicity of processed nodes are included in the code
151  * for convenience:
152  *
153  * // xpath: <xpath> (?|*|+)
154  *
155  * if multiplicity is ommited, then the node has multiplicity 'one'.
156  */
157 
158  // --------------------------------------------------------------------------
159 
161  {
162  if ( reader_r->nodeType() == XML_READER_TYPE_ELEMENT )
163  {
164  // xpath: /repoindex
165  if ( reader_r->name() == "repoindex" )
166  {
167  while ( reader_r.nextNodeAttribute() )
168  {
169  const std::string & name( reader_r->localName().asString() );
170  const std::string & value( reader_r->value().asString() );
171  _replacer.setVar( name, value );
172  // xpath: /repoindex@ttl
173  if ( name == "ttl" )
174  _ttl = str::strtonum<Date::Duration>(value);
175  }
176  return true;
177  }
178 
179  // xpath: /repoindex/data (+)
180  if ( reader_r->name() == "repo" )
181  {
182  RepoInfo info;
183  // Set some defaults that are not contained in the repo information
184  info.setAutorefresh( true );
185  info.setEnabled(false);
186 
187  std::string attrValue;
188 
189  // required alias
190  // mandatory, so we can allow it in var replacement without reset
191  if ( getAttrValue( "alias", reader_r, attrValue ) )
192  {
193  info.setAlias( attrValue );
194  _replacer.setVar( "alias", attrValue );
195  }
196  else
197  throw ParseException(str::form(_("Required attribute '%s' is missing."), "alias"));
198 
199  // required url
200  // SLES HACK: or path, but beware of the hardcoded '/repo' prefix!
201  {
202  std::string urlstr;
203  std::string pathstr;
204  getAttrValue( "url", reader_r, urlstr );
205  getAttrValue( "path", reader_r, pathstr );
206  if ( urlstr.empty() )
207  {
208  if ( pathstr.empty() )
209  throw ParseException(str::form(_("One or both of '%s' or '%s' attributes is required."), "url", "path"));
210  else
211  info.setPath( Pathname("/repo") / pathstr );
212  }
213  else
214  {
215  if ( pathstr.empty() )
216  info.setBaseUrl( Url(urlstr) );
217  else
218  {
219  Url url( urlstr );
220  url.setPathName( Pathname(url.getPathName()) / "repo" / pathstr );
221  info.setBaseUrl( url );
222  }
223  }
224  }
225 
226  // optional name
227  if ( getAttrValue( "name", reader_r, attrValue ) )
228  info.setName( attrValue );
229 
230  // optional targetDistro
231  if ( getAttrValue( "distro_target", reader_r, attrValue ) )
232  info.setTargetDistribution( attrValue );
233 
234  // optional priority
235  if ( getAttrValue( "priority", reader_r, attrValue ) )
236  info.setPriority( str::strtonum<unsigned>( attrValue ) );
237 
238 
239  // optional enabled
240  if ( getAttrValue( "enabled", reader_r, attrValue ) )
241  info.setEnabled( str::strToBool( attrValue, info.enabled() ) );
242 
243  // optional autorefresh
244  if ( getAttrValue( "autorefresh", reader_r, attrValue ) )
245  info.setAutorefresh( str::strToBool( attrValue, info.autorefresh() ) );
246 
247  DBG << info << endl;
248 
249  // ignore the rest
250  _callback(info);
251  return true;
252  }
253  }
254 
255  return true;
256  }
257 
258 
260  //
261  // CLASS NAME : RepoindexFileReader
262  //
264 
265  RepoindexFileReader::RepoindexFileReader( const Pathname & repoindex_file, const ProcessResource & callback )
266  : _pimpl(new Impl(InputStream(repoindex_file), callback))
267  {}
268 
270  : _pimpl(new Impl(is, callback))
271  {}
272 
274  {}
275 
277 
278  } // ns parser
279 } // ns zypp
280 
281 // vim: set ts=2 sts=2 sw=2 et ai:
const ProcessCredentials & _callback
Interface to gettext.
#define _(MSG)
Definition: Gettext.h:37
#define DBG
Definition: Logger.h:90
#define MIL
Definition: Logger.h:91
#define WAR
Definition: Logger.h:92
Url url
Definition: MediaCurl.cc:66
std::unordered_map< std::string, std::string > _vars
Interface of repoindex.xml file reader.
time_t Duration
Definition: Date.h:39
Integral type with defined initial value when default constructed.
Helper to create and pass std::istream.
Definition: InputStream.h:57
const Pathname & path() const
Path to the input file or empty if no file.
Definition: InputStream.h:111
What is known about a repository.
Definition: RepoInfo.h:72
void setBaseUrl(const Url &url)
Clears current base URL list and adds url.
Definition: RepoInfo.cc:643
void setTargetDistribution(const std::string &targetDistribution)
Sets the distribution for which is this repository meant.
Definition: RepoInfo.cc:674
void setPath(const Pathname &path)
set the product path.
Definition: RepoInfo.cc:652
void setPriority(unsigned newval_r)
Set repository priority for solver.
Definition: RepoInfo.cc:400
Url manipulation class.
Definition: Url.h:92
DefaultIntegral< Date::Duration, 0 > _ttl
bool consumeNode(Reader &reader_r)
Callback provided to the XML parser.
Impl(const InputStream &is, const ProcessResource &callback)
CTOR.
ProcessResource _callback
Function for processing collected data.
bool getAttrValue(const std::string &key_r, Reader &reader_r, std::string &value_r)
RW_pointer< Impl, rw_pointer::Scoped< Impl > > _pimpl
RepoindexFileReader(const zypp::Pathname &repoindexFile, const ProcessResource &callback)
CTOR.
function< bool(const RepoInfo &)> ProcessResource
Callback definition.
Date::Duration ttl() const
Metadata TTL (repoindex.xml:xpath:/repoindex@ttl or 0).
void setAutorefresh(bool autorefresh)
enable or disable autorefresh
Definition: RepoInfoBase.cc:91
void setAlias(const std::string &alias)
set the repository alias
Definition: RepoInfoBase.cc:94
void setName(const std::string &name)
set the repository name
Definition: RepoInfoBase.cc:97
bool autorefresh() const
If true, the repostory must be refreshed before creating resolvables from it.
bool enabled() const
If enabled is false, then this repository must be ignored as if does not exists, except when checking...
void setEnabled(bool enabled)
enable or disable the repository
Definition: RepoInfoBase.cc:88
XmlString localName() const
The local name of the node.
Definition: Node.h:114
NodeType nodeType() const
Get the node type of the current node.
Definition: Node.h:126
XmlString value() const
Provides the text value of the node if present.
Definition: Node.h:143
XmlString getAttribute(const char *name_r) const
Provides a copy of the attribute value with the specified qualified name.
Definition: Node.h:71
XmlString name() const
The qualified name of the node, equal to Prefix :LocalName.
Definition: Node.h:118
xmlTextReader based interface to iterate xml streams.
Definition: Reader.h:96
bool nextNodeAttribute()
Definition: Reader.cc:180
bool foreachNode(ProcessNode fnc_r)
Definition: Reader.h:144
xmlChar * wrapper.
Definition: XmlString.h:41
std::string asString() const
Explicit conversion to std::string.
Definition: XmlString.h:77
const xmlChar * get() const
Access the xmlChar *.
Definition: XmlString.h:61
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition: NonCopyable.h:26
SolvableIdType size_type
Definition: PoolMember.h:126
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition: String.cc:36
bool strToBool(const C_Str &str, bool default_r)
Parse str into a bool depending on the default value.
Definition: String.h:426
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2