libzypp 17.36.7

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
29#include <zypp/parser/RepoindexFileReader.h>
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 //
102 class RepoindexFileReader::Impl : private base::NonCopyable
103 {
104 public:
110 Impl(const InputStream &is, ProcessResource &&callback);
111
115 bool consumeNode( Reader & reader_r );
116
117 DefaultIntegral<Date::Duration,0> _ttl;
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:
134 ProcessResource _callback;
135 VarReplacer _replacer;
136 };
137
138
139 RepoindexFileReader::Impl::Impl(const InputStream &is,
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
161 bool RepoindexFileReader::Impl::consumeNode( Reader & reader_r )
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 // TODO: Ideally the repo values here are interpreted the same way as
184 // corresponding ones in the RepoFileReader. Check whether we can introduce
185 // a RepoInfo ctor from a string dict. Using it here and in RepoFileReader.
186 // For now we try to parse the same way as in RepoFileReader.
187
188 RepoInfo info;
189 // Set some defaults that are not contained in the repo information
190 info.setAutorefresh( true );
191 info.setEnabled(false);
192
193 std::string attrValue;
194
195 // required alias
196 // mandatory, so we can allow it in var replacement without reset
197 if ( getAttrValue( "alias", reader_r, attrValue ) )
198 {
199 info.setAlias( attrValue );
200 _replacer.setVar( "alias", attrValue );
201 }
202 else
203 throw ParseException(str::form(_("Required attribute '%s' is missing."), "alias"));
204
205 // required url
206 // SLES HACK: or path, but beware of the hardcoded '/repo' prefix!
207 {
208 std::string urlstr;
209 std::string pathstr;
210 getAttrValue( "url", reader_r, urlstr );
211 getAttrValue( "path", reader_r, pathstr );
212 if ( urlstr.empty() )
213 {
214 if ( pathstr.empty() )
215 throw ParseException(str::form(_("One or both of '%s' or '%s' attributes is required."), "url", "path"));
216 else
217 info.setPath( Pathname("/repo") / pathstr );
218 }
219 else
220 {
221 if ( pathstr.empty() )
222 info.setBaseUrl( Url(urlstr) );
223 else
224 {
225 Url url( urlstr );
226 url.setPathName( Pathname(url.getPathName()) / "repo" / pathstr );
227 info.setBaseUrl( url );
228 }
229 }
230 }
231
232 // optional name
233 if ( getAttrValue( "name", reader_r, attrValue ) )
234 info.setName( attrValue );
235
236 // optional targetDistro
237 if ( getAttrValue( "distro_target", reader_r, attrValue ) )
238 info.setTargetDistribution( attrValue );
239
240 // optional priority
241 if ( getAttrValue( "priority", reader_r, attrValue ) )
242 info.setPriority( str::strtonum<unsigned>( attrValue ) );
243
244 // optional enabled
245 if ( getAttrValue( "enabled", reader_r, attrValue ) )
246 info.setEnabled( str::strToBool( attrValue, info.enabled() ) );
247
248 // optional autorefresh
249 if ( getAttrValue( "autorefresh", reader_r, attrValue ) )
250 info.setAutorefresh( str::strToBool( attrValue, info.autorefresh() ) );
251
252 // optional *gpgcheck
253 if ( getAttrValue( "gpgcheck", reader_r, attrValue ) )
254 info.setGpgCheck( str::strToTriBool( attrValue ) );
255 if ( getAttrValue( "repo_gpgcheck", reader_r, attrValue ) )
256 info.setRepoGpgCheck( str::strToTrue( attrValue ) );
257 if ( getAttrValue( "pkg_gpgcheck", reader_r, attrValue ) )
258 info.setPkgGpgCheck( str::strToTrue( attrValue ) );
259
260 // optional keeppackages
261 if ( getAttrValue( "keeppackages", reader_r, attrValue ) )
262 info.setKeepPackages( str::strToTrue( attrValue ) );
263
264 // optional gpgkey
265 if ( getAttrValue( "gpgkey", reader_r, attrValue ) )
266 info.setGpgKeyUrl( Url(attrValue) );
267
268 // optional mirrorlist
269 if ( getAttrValue( "mirrorlist", reader_r, attrValue ) )
270 info.setMirrorListUrl( Url(attrValue) );
271
272 // optional metalink
273 if ( getAttrValue( "metalink", reader_r, attrValue ) )
274 info.setMetalinkUrl( Url(attrValue) );
275
276 DBG << info << endl;
277
278 // ignore the rest
279 // Specially: bsc#1177427 et.al.: type in a .repo file is legacy - ignore it
280 _callback(info);
281 return true;
282 }
283 }
284
285 return true;
286 }
287
288
290 //
291 // CLASS NAME : RepoindexFileReader
292 //
294
295 RepoindexFileReader::RepoindexFileReader( Pathname repoindex_file, ProcessResource callback )
296 : _pimpl(new Impl( InputStream(std::move(repoindex_file)), std::move(callback) ))
297 {}
298
299 RepoindexFileReader::RepoindexFileReader(const InputStream &is, ProcessResource callback )
300 : _pimpl(new Impl( is, std::move(callback) ))
301 {}
302
303 RepoindexFileReader::~RepoindexFileReader()
304 {}
305
306 Date::Duration RepoindexFileReader::ttl() const { return _pimpl->_ttl; }
307
308 } // ns parser
309} // ns zypp
310
311// vim: set ts=2 sts=2 sw=2 et ai:
Reader.h
RepoInfo.h
RepoindexFileReader.h
Interface of repoindex.xml file reader.
zypp::Date::Duration
time_t Duration
Definition Date.h:39
zypp::DefaultIntegral
Integral type with defined initial value when default constructed.
Definition defaultintegral.h:42
zypp::InputStream
Helper to create and pass std::istream.
Definition inputstream.h:57
zypp::InputStream::path
const Pathname & path() const
Path to the input file or empty if no file.
Definition inputstream.h:111
zypp::RepoInfo
What is known about a repository.
Definition RepoInfo.h:72
zypp::RepoInfo::setPkgGpgCheck
void setPkgGpgCheck(TriBool value_r)
Set the value for pkgGpgCheck (or indeterminate to use the default).
Definition RepoInfo.cc:456
zypp::RepoInfo::setMetalinkUrl
void setMetalinkUrl(const Url &url)
Like setMirrorListUrl but expect metalink format.
Definition RepoInfo.cc:542
zypp::RepoInfo::setGpgKeyUrl
void setGpgKeyUrl(const Url &gpgkey)
(leagcy API) Set the gpgkey URL defined for this repo
Definition RepoInfo.cc:551
zypp::RepoInfo::setKeepPackages
void setKeepPackages(bool keep)
Set if packaqes downloaded from this repository will be kept in local cache.
Definition RepoInfo.cc:600
zypp::RepoInfo::setMirrorListUrl
void setMirrorListUrl(const Url &url)
Set mirror list url.
Definition RepoInfo.cc:536
zypp::RepoInfo::setBaseUrl
void setBaseUrl(Url url)
Clears current base URL list and adds url.
Definition RepoInfo.cc:572
zypp::RepoInfo::setGpgCheck
void setGpgCheck(TriBool value_r)
Set the value for gpgCheck (or indeterminate to use the default).
Definition RepoInfo.cc:428
zypp::RepoInfo::setTargetDistribution
void setTargetDistribution(const std::string &targetDistribution)
Sets the distribution for which is this repository meant.
Definition RepoInfo.cc:606
zypp::RepoInfo::setPath
void setPath(const Pathname &path)
set the product path.
Definition RepoInfo.cc:581
zypp::RepoInfo::setPriority
void setPriority(unsigned newval_r)
Set repository priority for solver.
Definition RepoInfo.cc:421
zypp::RepoInfo::setRepoGpgCheck
void setRepoGpgCheck(TriBool value_r)
Set the value for repoGpgCheck (or indeterminate to use the default).
Definition RepoInfo.cc:446
zypp::Url
Url manipulation class.
Definition Url.h:93
zypp::filesystem::Pathname
Pathname.
Definition Pathname.h:47
zypp::parser::ParseException
Definition parseexception.h:34
zypp::parser::RepoindexFileReader::Impl
Definition RepoindexFileReader.cc:103
zypp::parser::RepoindexFileReader::Impl::_ttl
DefaultIntegral< Date::Duration, 0 > _ttl
Definition RepoindexFileReader.cc:117
zypp::parser::RepoindexFileReader::Impl::consumeNode
bool consumeNode(Reader &reader_r)
Callback provided to the XML parser.
Definition RepoindexFileReader.cc:161
zypp::parser::RepoindexFileReader::Impl::_replacer
VarReplacer _replacer
Definition RepoindexFileReader.cc:135
zypp::parser::RepoindexFileReader::Impl::Impl
Impl(const InputStream &is, ProcessResource &&callback)
CTOR.
Definition RepoindexFileReader.cc:139
zypp::parser::RepoindexFileReader::Impl::_callback
ProcessResource _callback
Function for processing collected data.
Definition RepoindexFileReader.cc:134
zypp::parser::RepoindexFileReader::Impl::getAttrValue
bool getAttrValue(const std::string &key_r, Reader &reader_r, std::string &value_r)
Definition RepoindexFileReader.cc:120
zypp::parser::RepoindexFileReader::ProcessResource
function< bool(const RepoInfo &)> ProcessResource
Callback definition.
Definition RepoindexFileReader.h:52
zypp::parser::RepoindexFileReader::_pimpl
RW_pointer< Impl, rw_pointer::Scoped< Impl > > _pimpl
Definition RepoindexFileReader.h:86
zypp::parser::RepoindexFileReader::RepoindexFileReader
RepoindexFileReader(Pathname repoindexFile, ProcessResource callback)
CTOR.
Definition RepoindexFileReader.cc:295
zypp::parser::RepoindexFileReader::ttl
Date::Duration ttl() const
Metadata TTL (repoindex.xml:xpath:/repoindex@ttl or 0).
Definition RepoindexFileReader.cc:306
zypp::parser::RepoindexFileReader::~RepoindexFileReader
~RepoindexFileReader()
DTOR.
Definition RepoindexFileReader.cc:303
zypp::repo::RepoInfoBase::setAutorefresh
void setAutorefresh(bool autorefresh)
enable or disable autorefresh
Definition RepoInfoBase.cc:86
zypp::repo::RepoInfoBase::setAlias
void setAlias(const std::string &alias)
set the repository alias
Definition RepoInfoBase.cc:89
zypp::repo::RepoInfoBase::setName
void setName(const std::string &name)
set the repository name
Definition RepoInfoBase.cc:92
zypp::repo::RepoInfoBase::autorefresh
bool autorefresh() const
If true, the repostory must be refreshed before creating resolvables from it.
Definition RepoInfoBase.cc:101
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:98
zypp::repo::RepoInfoBase::setEnabled
void setEnabled(bool enabled)
enable or disable the repository
Definition RepoInfoBase.cc:83
zypp::xml::Node::localName
XmlString localName() const
The local name of the node.
Definition Node.h:114
zypp::xml::Node::nodeType
NodeType nodeType() const
Get the node type of the current node.
Definition Node.h:126
zypp::xml::Node::value
XmlString value() const
Provides the text value of the node if present.
Definition Node.h:143
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::xml::Reader
xmlTextReader based interface to iterate xml streams.
Definition Reader.h:96
zypp::xml::Reader::nextNodeAttribute
bool nextNodeAttribute()
Definition Reader.cc:162
zypp::xml::Reader::foreachNode
bool foreachNode(const ProcessNode &fnc_r)
Definition Reader.h:144
zypp::xml::XmlString
xmlChar * wrapper.
Definition XmlString.h:41
zypp::xml::XmlString::asString
std::string asString() const
Explicit conversion to std::string.
Definition XmlString.h:77
zypp::xml::XmlString::get
const xmlChar * get() const
Access the xmlChar *.
Definition XmlString.h:61
std
Definition Arch.h:364
zypp::base::NonCopyable
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition NonCopyable.h:26
zypp::callback
Callbacks light.
Definition Callback.h:146
zypp::str::strToTrue
bool strToTrue(const C_Str &str)
Parsing boolean from string.
Definition String.cc:64
zypp::str::strToTriBool
TriBool strToTriBool(const C_Str &str)
Parse str into a bool if it's a legal true or false string; else indeterminate.
Definition String.cc:94
zypp::str::form
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition String.cc:37
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:429
zypp::str::strtonum
TInt strtonum(const C_Str &str)
Parsing numbers from string.
zypp::url
Url details namespace.
Definition UrlBase.cc:58
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition Application.cc:20
_
#define _(MSG)
Definition Gettext.h:39
DBG
#define DBG
Definition Logger.h:99
MIL
#define MIL
Definition Logger.h:100
WAR
#define WAR
Definition Logger.h:101
Pathname.h
Gettext.h
Interface to gettext.
Logger.h
String.h