libzypp  17.25.0
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:
zypp::RepoInfo::setBaseUrl
void setBaseUrl(const Url &url)
Clears current base URL list and adds url.
Definition: RepoInfo.cc:637
zypp::xml::Reader
xmlTextReader based interface to iterate xml streams.
Definition: Reader.h:95
zypp::xml::XmlString::asString
std::string asString() const
Explicit conversion to std::string.
Definition: XmlString.h:77
_callback
const ProcessCredentials & _callback
Definition: CredentialFileReader.cc:122
zypp::RepoInfo
What is known about a repository.
Definition: RepoInfo.h:71
zypp::repo::RepoInfoBase::setAutorefresh
void setAutorefresh(bool autorefresh)
enable or disable autorefresh
Definition: RepoInfoBase.cc:91
zypp::repo::RepoInfoBase::setName
void setName(const std::string &name)
set the repository name
Definition: RepoInfoBase.cc:97
MIL
#define MIL
Definition: Logger.h:79
zypp::repo::RepoInfoBase::enabled
bool enabled() const
If enabled is false, then this repository must be ignored as if does not exists, except when checking...
Definition: RepoInfoBase.cc:104
zypp::parser::RepoindexFileReader::Impl::_callback
ProcessResource _callback
Function for processing collected data.
Definition: RepoindexFileReader.cc:133
zypp::str::strToBool
bool strToBool(const C_Str &str, bool default_r)
Parse str into a bool depending on the default value.
Definition: String.h:426
zypp::xml::Reader::foreachNode
bool foreachNode(ProcessNode fnc_r)
Definition: Reader.h:144
Pathname.h
zypp::RepoInfo::setPath
void setPath(const Pathname &path)
set the product path.
Definition: RepoInfo.cc:646
zypp::RepoInfo::setPriority
void setPriority(unsigned newval_r)
Set repository priority for solver.
Definition: RepoInfo.cc:400
ParseException.h
zypp::parser::RepoindexFileReader::Impl
Definition: RepoindexFileReader.cc:101
zypp::parser::RepoindexFileReader::Impl::_replacer
VarReplacer _replacer
Definition: RepoindexFileReader.cc:134
zypp::parser::RepoindexFileReader::RepoindexFileReader
RepoindexFileReader(const zypp::Pathname &repoindexFile, const ProcessResource &callback)
CTOR.
Definition: RepoindexFileReader.cc:265
RepoInfo.h
zypp::base::NonCopyable
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition: NonCopyable.h:26
Logger.h
WAR
#define WAR
Definition: Logger.h:80
zypp::parser::ParseException
Definition: ParseException.h:33
zypp::xml::Node::nodeType
NodeType nodeType() const
Get the node type of the current node.
Definition: Node.h:126
zypp::RepoInfo::setTargetDistribution
void setTargetDistribution(const std::string &targetDistribution)
Sets the distribution for which is this repository meant.
Definition: RepoInfo.cc:668
zypp::parser::RepoindexFileReader::ttl
Date::Duration ttl() const
Metadata TTL (repoindex.xml:xpath:/repoindex@ttl or 0).
Definition: RepoindexFileReader.cc:276
zypp::Date::Duration
time_t Duration
Definition: Date.h:39
zypp::xml::Node::localName
XmlString localName() const
The local name of the node.
Definition: Node.h:114
zypp::parser::RepoindexFileReader::Impl::getAttrValue
bool getAttrValue(const std::string &key_r, Reader &reader_r, std::string &value_r)
Definition: RepoindexFileReader.cc:119
_
#define _(MSG)
Definition: Gettext.h:37
zypp::str::form
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition: String.cc:35
zypp::xml::Node::getAttribute
XmlString getAttribute(const char *name_r) const
Provides a copy of the attribute value with the specified qualified name.
Definition: Node.h:71
zypp::xml::Node::name
XmlString name() const
The qualified name of the node, equal to Prefix :LocalName.
Definition: Node.h:118
zypp::InputStream
Helper to create and pass std::istream.
Definition: InputStream.h:56
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
zypp::parser::RepoindexFileReader::_pimpl
RW_pointer< Impl, rw_pointer::Scoped< Impl > > _pimpl
Definition: RepoindexFileReader.h:85
zypp::repo::RepoInfoBase::setEnabled
void setEnabled(bool enabled)
enable or disable the repository
Definition: RepoInfoBase.cc:88
zypp::repo::RepoInfoBase::autorefresh
bool autorefresh() const
If true, the repostory must be refreshed before creating resolvables from it.
Definition: RepoInfoBase.cc:108
zypp::DefaultIntegral< Date::Duration, 0 >
_vars
std::unordered_map< std::string, std::string > _vars
Definition: RepoindexFileReader.cc:92
Gettext.h
zypp::xml::XmlString
xmlChar * wrapper.
Definition: XmlString.h:40
zypp::parser::RepoindexFileReader::Impl::Impl
Impl(const InputStream &is, const ProcessResource &callback)
CTOR.
Definition: RepoindexFileReader.cc:138
zypp::InputStream::path
const Pathname & path() const
Path to the input file or empty if no file.
Definition: InputStream.h:111
String.h
zypp::filesystem::Pathname
Pathname.
Definition: Pathname.h:44
zypp::xml::Node::value
XmlString value() const
Provides the text value of the node if present.
Definition: Node.h:143
zypp::sat::detail::size_type
SolvableIdType size_type
Definition: PoolMember.h:126
xml::Reader
DBG
#define DBG
Definition: Logger.h:78
InputStream.h
RepoindexFileReader.h
zypp::repo::RepoInfoBase::setAlias
void setAlias(const std::string &alias)
set the repository alias
Definition: RepoInfoBase.cc:94
zypp::parser::RepoindexFileReader::~RepoindexFileReader
~RepoindexFileReader()
DTOR.
Definition: RepoindexFileReader.cc:273
Reader.h
url
Url url
Definition: MediaCurl.cc:66
zypp::Url
Url manipulation class.
Definition: Url.h:87
zypp::parser::RepoindexFileReader::Impl::_ttl
DefaultIntegral< Date::Duration, 0 > _ttl
Definition: RepoindexFileReader.cc:116
zypp::parser::RepoindexFileReader::ProcessResource
function< bool(const RepoInfo &)> ProcessResource
Callback definition.
Definition: RepoindexFileReader.h:52
zypp::xml::Reader::nextNodeAttribute
bool nextNodeAttribute()
Definition: Reader.cc:180
zypp::parser::RepoindexFileReader::Impl::consumeNode
bool consumeNode(Reader &reader_r)
Callback provided to the XML parser.
Definition: RepoindexFileReader.cc:160
DefaultIntegral.h