libzypp 17.31.23
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-core/base/InputStream>
19#include <zypp-core/base/DefaultIntegral>
20
21#include <zypp/Pathname.h>
22
24#include <zypp-core/parser/ParseException>
25
26#include <zypp/RepoInfo.h>
27
29
30
31#undef ZYPP_BASE_LOGGER_LOGGROUP
32#define ZYPP_BASE_LOGGER_LOGGROUP "parser"
33
34using std::endl;
35
36namespace 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:
std::unordered_map< std::string, std::string > _vars
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.
Definition: inputstream.h:111
What is known about a repository.
Definition: RepoInfo.h:72
void setBaseUrl(const Url &url)
Clears current base URL list and adds url.
Definition: RepoInfo.cc:643
void setTargetDistribution(const std::string &targetDistribution)
Sets the distribution for which is this repository meant.
Definition: RepoInfo.cc:674
void setPath(const Pathname &path)
set the product path.
Definition: RepoInfo.cc:652
void setPriority(unsigned newval_r)
Set repository priority for solver.
Definition: RepoInfo.cc:400
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:604
void setPathName(const std::string &path, EEncoding eflag=zypp::url::E_DECODED)
Set the path name.
Definition: Url.cc:764
DefaultIntegral< Date::Duration, 0 > _ttl
bool consumeNode(Reader &reader_r)
Callback provided to the XML parser.
Impl(const InputStream &is, const ProcessResource &callback)
CTOR.
ProcessResource _callback
Function for processing collected data.
bool getAttrValue(const std::string &key_r, Reader &reader_r, std::string &value_r)
RW_pointer< Impl, rw_pointer::Scoped< Impl > > _pimpl
RepoindexFileReader(const zypp::Pathname &repoindexFile, const ProcessResource &callback)
CTOR.
function< bool(const RepoInfo &)> ProcessResource
Callback definition.
Date::Duration ttl() const
Metadata TTL (repoindex.xml:xpath:/repoindex@ttl or 0).
void setAutorefresh(bool autorefresh)
enable or disable autorefresh
Definition: RepoInfoBase.cc:91
void setAlias(const std::string &alias)
set the repository alias
Definition: RepoInfoBase.cc:94
void setName(const std::string &name)
set the repository name
Definition: RepoInfoBase.cc:97
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
Definition: RepoInfoBase.cc:88
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:180
bool foreachNode(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
const ProcessCredentials & _callback
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:36
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.
Definition: CodePitfalls.doc:2
#define _(MSG)
Definition: Gettext.h:37
#define DBG
Definition: Logger.h:95
#define MIL
Definition: Logger.h:96
#define WAR
Definition: Logger.h:97