1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/parser/yum/FileReaderBaseImpl.cc
10 * Implementation of shared code for yum::*FileReaders.
14 #include "zypp/base/Logger.h"
15 #include "zypp/base/Function.h"
16 #include "zypp/Arch.h"
17 #include "zypp/Edition.h"
18 #include "zypp/TranslatedText.h"
19 #include "zypp/ByteCount.h"
21 #include "zypp/parser/ParseException.h"
22 #include "zypp/parser/yum/FileReaderBaseImpl.h"
25 using namespace zypp::xml;
35 FileReaderBase::BaseImpl::BaseImpl()
36 : _expect_rpm_entry(false), _dtype(zypp::Dep::REQUIRES)
39 // --------------------------------------------------------------------------
42 * xpath and multiplicity of processed nodes are included in the code
45 * // xpath: <xpath> (?|*|+)
47 * if multiplicity is ommited, then the node has multiplicity 'one'.
50 // --------------------------------------------------------------------------
52 bool FileReaderBase::BaseImpl::consumePackageNode(xml::Reader & reader_r, data::Packagebase_Ptr & package_ptr)
54 // DBG << "**node: " << reader_r->name() << " (" << reader_r->nodeType() << ") tagpath = " << _tagpath << endl;
55 if (!isBeingProcessed(tag_package))
56 ZYPP_THROW(ParseException("consumePackageNode() called outside of package element"));
58 if (isBeingProcessed(tag_format) && consumeFormatNode(reader_r, package_ptr))
61 if (reader_r->nodeType() == XML_READER_TYPE_ELEMENT)
63 // xpath: //package/name
64 if (reader_r->name() == "name")
66 package_ptr->name = reader_r.nodeText().asString();
70 // xpath: //package/arch
71 if (reader_r->name() == "arch")
73 string arch = reader_r.nodeText().asString();
74 // create SrcPackage instead of Package for source packages
75 if (arch == "src" || arch == "nosrc")
78 data::Packagebase_Ptr srcpkg = new data::SrcPackage;
79 // we have read name only so far, copying only the name
80 srcpkg->name = package_ptr->name;
81 // package_ptr will point to a SrcPackage from now on
82 package_ptr.swap(srcpkg);
84 package_ptr->arch.swap(arch);
88 // xpath: //package/version
89 if (reader_r->name() == "version")
91 if (reader_r->getAttribute("epoch").asString().empty());
92 package_ptr->edition += (reader_r->getAttribute("epoch").asString()+":");
94 package_ptr->edition += ( reader_r->getAttribute("ver").asString() + "-" + reader_r->getAttribute("rel").asString() );
98 // xpath: //package/checksum
99 if (reader_r->name() == "checksum")
101 package_ptr->repositoryLocation.setChecksum(CheckSum(
102 reader_r->getAttribute("type").asString(),
103 reader_r.nodeText().asString()));
104 // ignoring pkgid attribute
108 // xpath: //package/summary (*)
109 if (reader_r->name() == "summary")
111 Locale locale(reader_r->getAttribute("lang").asString());
112 package_ptr->summary.setText(
113 reader_r.nodeText().asString(), locale);
117 // xpath: //package/description (*)
118 if (reader_r->name() == "description")
120 Locale locale(reader_r->getAttribute("lang").asString());
121 package_ptr->description.setText(
122 reader_r.nodeText().asString(), locale);
126 // xpath: //package/packager
127 if (reader_r->name() == "packager")
129 package_ptr->packager = reader_r.nodeText().asString();
133 // xpath: //package/url
134 if (reader_r->name() == "url")
136 package_ptr->url = reader_r.nodeText().asString();
140 // xpath: //package/time
141 if (reader_r->name() == "time")
143 package_ptr->buildTime = reader_r->getAttribute("build").asString();
144 // ignoring reader_r->getAttribute("file").asString(); (rpm file timestamp)
148 // xpath: //package/size
149 if (reader_r->name() == "size")
151 //! \todo what's 'archive' size of the package (it is neither the rpm file size nor its installed size)
152 // reader_r->getAttribute("archive").asString();
155 package_ptr->installedSize = str::strtonum<ByteCount::SizeType>( reader_r->getAttribute("installed").asString() );
158 package_ptr->repositoryLocation.setDownloadSize(str::strtonum<ByteCount::SizeType>( reader_r->getAttribute("package").asString() ));
163 // xpath: //package/location
164 if (reader_r->name() == "location")
166 package_ptr->repositoryLocation.setLocation(reader_r->getAttribute("href").asString(), 1);
170 // xpath: //package/format
171 if (reader_r->name() == "format")
178 else if ( reader_r->nodeType() == XML_READER_TYPE_END_ELEMENT )
181 if (reader_r->name() == "package")
183 // indicate that further processing is required
184 // e.g. caller needs to to check for </package> to trigger some action
192 bool FileReaderBase::BaseImpl::editionStringFromAttrs( xml::Reader & reader_r, string &edition )
195 if ( ! reader_r->getAttribute("epoch").asString().empty() )
196 result += (reader_r->getAttribute("epoch").asString() + ":");
198 result += reader_r->getAttribute("ver").asString();
199 result += ( "-" + reader_r->getAttribute("ver").asString());
200 result.swap(edition);
204 // --------------( consume <format> tag )------------------------------------
206 bool FileReaderBase::BaseImpl::consumeFormatNode(
207 xml::Reader & reader_r, data::Packagebase_Ptr & package_ptr)
209 if (consumeDependency(reader_r, package_ptr->deps))
210 // this node has been a dependency, which has been handled by
211 // consumeDependency(), so return right away.
214 // DBG << "format subtag: " << reader_r->name() << endl;
216 if (reader_r->nodeType() == XML_READER_TYPE_ELEMENT)
218 // xpath: //format/rpm:license
219 if (reader_r->name() == "rpm:license")
221 package_ptr->license = reader_r.nodeText().asString();
225 // xpath: //format/rpm:vendor
226 if (reader_r->name() == "rpm:vendor")
228 package_ptr->vendor = reader_r.nodeText().asString();
232 // xpath: //format/rpm:group
233 if (reader_r->name() == "rpm:group")
235 package_ptr->group = reader_r.nodeText().asString();
239 // xpath: //format/rpm:buildhost
240 if (reader_r->name() == "rpm:buildhost")
242 package_ptr->buildhost = reader_r.nodeText().asString();
246 //! \todo xpath: //format/rpm:sourcerpm where to store this?
247 if (reader_r->name() == "rpm:sourcerpm")
249 //package->source = reader_r.nodeText().asString();
253 //! \todo xpath: //format/rpm:header-range what is this?
254 if (reader_r->name() == "rpm:header-range")
256 //reader_r->getAttribute("start").asString(),
257 //reader_r->getAttribute("end").asString(),
261 // file entries listed outside of filelists.xml to be treated
263 // xpath: //format/file (*)
264 if (reader_r->name() == "file")
266 // insert file dependency into the list
267 package_ptr->deps[Dep::PROVIDES].insert(
268 zypp::capability::parse(
269 ResTraits<Package>::kind,
270 reader_r.nodeText().asString()));
274 // xpath: //format/suse:authors/suse:author (+)
275 // but tolerating multiplicity (*)
276 if (reader_r->name() == "suse:author")
278 package_ptr->authors.push_back(reader_r.nodeText().asString());
282 // xpath: //format/suse:keywords (?)
283 // xpath: //format/suse:keywords/suse:keyword (+)
284 if (reader_r->name() == "suse:keyword")
286 package_ptr->keywords.insert(reader_r.nodeText().asString());
290 //! \todo xpath: //format/suse:dirsizes (?)
292 // xpath: //format/suse:install-only (?)
293 if (reader_r->name() == "suse:install-only")
295 package_ptr->installOnly = true;
299 // xpath: //format/suse:license-to-confirm (*)
300 //! \todo this is ambiguous - fix the rnc schema
301 if (reader_r->name() == "suse:license-to-confirm")
303 Locale locale(reader_r->getAttribute("lang").asString());
304 package_ptr->licenseToConfirm.setText(
305 reader_r.nodeText().asString(), locale);
309 else if (reader_r->nodeType() == XML_READER_TYPE_END_ELEMENT)
312 if (reader_r->name() == "format")
322 // --------------------------------------------------------------------------
324 bool FileReaderBase::BaseImpl::consumeDependency(
325 xml::Reader & reader_r, data::Dependencies & deps_r)
327 if (reader_r->nodeType() == XML_READER_TYPE_ELEMENT)
329 // xpath: //format/*/rpm:entry | //format/suse-freshens/suse:entry (+)
330 if (reader_r->name() == "rpm:entry" | reader_r->name() == "suse:entry")
332 if (!_expect_rpm_entry)
333 ZYPP_THROW(ParseException("rpm:entry found when not expected"));
335 // read kind of resolvable this entry refers, default to Package
336 string kind_str = reader_r->getAttribute("kind").asString();
337 Resolvable::Kind kind;
338 if (kind_str.empty())
339 kind = ResTraits<Package>::kind;
341 kind = Resolvable::Kind(kind_str);
343 // Check whether this is actually a prerequires dependency.
344 // If so, it will be stored in deps_r as Dep::PREREQUIRES
345 // instead of Dep::REQUIRES (a prerequires can appear as part
346 // of requires dependencies only).
348 if (reader_r->getAttribute("pre").asString() == "1")
350 if (_dtype.inSwitch() != Dep::REQUIRES_e)
351 ZYPP_THROW(ParseException("pre=\"1\" found for non-requires dependency"));
355 DBG << "got rpm:entry for " << _dtype << ": "
356 << reader_r->getAttribute("name").asString()
357 << " " << edition << " (" << kind << ")" << endl;
360 string version = reader_r->getAttribute("ver").asString();
364 // insert unversion dependency into the list
365 deps_r[pre ? Dep::PREREQUIRES : _dtype].insert(
366 zypp::capability::parse(
367 kind, reader_r->getAttribute("name").asString()
375 reader_r->getAttribute("rel").asString(),
376 reader_r->getAttribute("epoch").asString()
379 // insert versioned dependency into the list
380 deps_r[pre ? Dep::PREREQUIRES : _dtype].insert(
381 zypp::capability::parse(
383 reader_r->getAttribute("name").asString(),
384 Rel(reader_r->getAttribute("flags").asString()),
390 //! \todo check <rpm:entry name="/bin/sh" pre="1">
393 // xpath: //format/rpm:provides (?)
394 if (reader_r->name() == "rpm:provides")
396 _dtype = zypp::Dep::PROVIDES;
397 _expect_rpm_entry = true;
400 // xpath: //format/rpm:conflicts (?)
401 if (reader_r->name() == "rpm:conflicts")
403 _dtype = zypp::Dep::CONFLICTS;
404 _expect_rpm_entry = true;
407 // xpath: //format/rpm:obsoletes (?)
408 if (reader_r->name() == "rpm:obsoletes")
410 _dtype = zypp::Dep::OBSOLETES;
411 _expect_rpm_entry = true;
414 // xpath: //format/rpm:requires (?)
415 if (reader_r->name() == "rpm:requires")
417 _dtype = zypp::Dep::REQUIRES;
418 _expect_rpm_entry = true;
421 // xpath: //format/rpm:recommends (?)
422 if (reader_r->name() == "rpm:recommends")
424 _dtype = zypp::Dep::RECOMMENDS;
425 _expect_rpm_entry = true;
428 // xpath: //format/rpm:enhances (?)
429 if (reader_r->name() == "rpm:enhances")
431 _dtype = zypp::Dep::ENHANCES;
432 _expect_rpm_entry = true;
435 // xpath: //format/rpm:supplements (?)
436 if (reader_r->name() == "rpm:supplements")
438 _dtype = zypp::Dep::SUPPLEMENTS;
439 _expect_rpm_entry = true;
442 // xpath: //format/rpm:suggests (?)
443 if (reader_r->name() == "rpm:suggests")
445 _dtype = zypp::Dep::SUGGESTS;
446 _expect_rpm_entry = true;
449 // xpath: //format/suse:freshens (?)
450 if (reader_r->name() == "suse:freshens")
452 _dtype = zypp::Dep::FRESHENS;
453 _expect_rpm_entry = true;
456 else if (reader_r->nodeType() == XML_READER_TYPE_END_ELEMENT)
458 // xpath: //format/* (?)
459 if (reader_r->name() == "rpm:requires"
460 || reader_r->name() == "rpm:provides"
461 || reader_r->name() == "rpm:conflicts"
462 || reader_r->name() == "rpm:obsoletes"
463 || reader_r->name() == "rpm:recommends"
464 || reader_r->name() == "rpm:enhances"
465 || reader_r->name() == "rpm:supplements"
466 || reader_r->name() == "rpm:suggests"
467 || reader_r->name() == "suse:freshens")
469 _expect_rpm_entry = false;
474 // tell the caller this has not been a dependency tag (i.e. not processed)
478 // --------------------------------------------------------------------------
480 string FileReaderBase::BaseImpl::TagPath::asString()
488 TagList::const_iterator p = path.begin();
492 for (; p != path.end(); ++p)
508 // vim: set ts=2 sts=2 sw=2 et ai: