libzypp 17.35.18
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:
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 };
137
138
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" )
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
273
276
278
279 } // ns parser
280} // ns zypp
281
282// vim: set ts=2 sts=2 sw=2 et ai:
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.
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:93
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
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:162
bool foreachNode(const 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
Definition Arch.h:364
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition NonCopyable.h:26
Callbacks light.
Definition Callback.h:146
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
TInt strtonum(const C_Str &str)
Parsing numbers from string.
Url details namespace.
Definition UrlBase.cc:58
Easy-to use interface to the ZYPP dependency resolver.
#define _(MSG)
Definition Gettext.h:39
#define DBG
Definition Logger.h:99
#define MIL
Definition Logger.h:100
#define WAR
Definition Logger.h:101
Interface to gettext.