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