libzypp 17.34.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 <utility>
19#include <zypp-core/base/InputStream>
20#include <zypp-core/base/DefaultIntegral>
21
22#include <zypp/Pathname.h>
23
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
35using std::endl;
36
37namespace 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 ) )
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 ) )
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
269
271 : _pimpl(new Impl( is, std::move(callback) ))
272 {}
273
276
278
279 } // ns parser
280} // ns zypp
281
282// vim: set ts=2 sts=2 sw=2 et ai:
std::unordered_map< std::string, std::string > _vars
Interface of repoindex.xml file reader.
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition AutoDispose.h:95
time_t Duration
Definition Date.h:39
Helper to create and pass std::istream.
Definition inputstream.h:57
What is known about a repository.
Definition RepoInfo.h:72
void setBaseUrl(Url url)
Clears current base URL list and adds url.
Definition RepoInfo.cc:556
void setTargetDistribution(const std::string &targetDistribution)
Sets the distribution for which is this repository meant.
Definition RepoInfo.cc:587
void setPath(const Pathname &path)
set the product path.
Definition RepoInfo.cc:565
void setPriority(unsigned newval_r)
Set repository priority for solver.
Definition RepoInfo.cc:407
Url manipulation class.
Definition Url.h:92
std::string getPathName(EEncoding eflag=zypp::url::E_DECODED) const
Returns the path name from the URL.
Definition Url.cc:608
void setPathName(const std::string &path, EEncoding eflag=zypp::url::E_DECODED)
Set the path name.
Definition Url.cc:768
DefaultIntegral< Date::Duration, 0 > _ttl
bool consumeNode(Reader &reader_r)
Callback provided to the XML parser.
Impl(const InputStream &is, ProcessResource &&callback)
CTOR.
ProcessResource _callback
Function for processing collected data.
bool getAttrValue(const std::string &key_r, Reader &reader_r, std::string &value_r)
function< bool(const RepoInfo &)> ProcessResource
Callback definition.
RW_pointer< Impl, rw_pointer::Scoped< Impl > > _pimpl
RepoindexFileReader(Pathname repoindexFile, ProcessResource callback)
CTOR.
Date::Duration ttl() const
Metadata TTL (repoindex.xml:xpath:/repoindex@ttl or 0).
void setAutorefresh(bool autorefresh)
enable or disable autorefresh
void setAlias(const std::string &alias)
set the repository alias
void setName(const std::string &name)
set the repository name
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
xmlTextReader based interface to iterate xml streams.
Definition Reader.h:96
xmlChar * wrapper.
Definition XmlString.h:41
const ProcessCredentials & _callback
Definition Arch.h:364
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition NonCopyable.h:26
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition String.cc:37
bool strToBool(const C_Str &str, bool default_r)
Parse str into a bool depending on the default value.
Definition String.h:429
Easy-to use interface to the ZYPP dependency resolver.
#define _(MSG)
Definition Gettext.h:39
#define DBG
Definition Logger.h:97
#define MIL
Definition Logger.h:98
#define WAR
Definition Logger.h:99
Interface to gettext.