FileReaderBaseImpl.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <sstream>
00013 
00014 #include "zypp/base/Logger.h"
00015 #include "zypp/base/Function.h"
00016 #include "zypp/Arch.h"
00017 #include "zypp/Edition.h"
00018 #include "zypp/TranslatedText.h"
00019 #include "zypp/ByteCount.h"
00020 
00021 #include "zypp/parser/ParseException.h"
00022 #include "zypp/parser/yum/FileReaderBaseImpl.h"
00023 
00024 using namespace std;
00025 using namespace zypp::xml;
00026 
00027 namespace zypp
00028 {
00029   namespace parser
00030   {
00031     namespace yum
00032     {
00033 
00034 
00035   FileReaderBase::BaseImpl::BaseImpl()
00036     : _expect_rpm_entry(false), _dtype(zypp::Dep::REQUIRES)
00037   {}
00038 
00039   // --------------------------------------------------------------------------
00040 
00041   /*
00042    * xpath and multiplicity of processed nodes are included in the code
00043    * for convenience:
00044    *
00045    * // xpath: <xpath> (?|*|+)
00046    *
00047    * if multiplicity is ommited, then the node has multiplicity 'one'.
00048    */
00049 
00050   // --------------------------------------------------------------------------
00051 
00052   bool FileReaderBase::BaseImpl::consumePackageNode(xml::Reader & reader_r, data::Packagebase_Ptr & package_ptr)
00053   {
00054     // DBG << "**node: " << reader_r->name() << " (" << reader_r->nodeType() << ") tagpath = " << _tagpath << endl;
00055     if (!isBeingProcessed(tag_package))
00056       ZYPP_THROW(ParseException("consumePackageNode() called outside of package element"));
00057 
00058     if (isBeingProcessed(tag_format) && consumeFormatNode(reader_r, package_ptr))
00059       return true;
00060 
00061     if (reader_r->nodeType() == XML_READER_TYPE_ELEMENT)
00062     {
00063       // xpath: //package/name
00064       if (reader_r->name() == "name")
00065       {
00066         package_ptr->name = reader_r.nodeText().asString();
00067         return true;
00068       }
00069 
00070       // xpath: //package/arch
00071       if (reader_r->name() == "arch")
00072       {
00073         string arch = reader_r.nodeText().asString();
00074         // create SrcPackage instead of Package for source packages
00075         if (arch == "src" || arch == "nosrc")
00076         {
00077           arch = "noarch";
00078           data::Packagebase_Ptr srcpkg = new data::SrcPackage;
00079           // we have read name only so far, copying only the name
00080           srcpkg->name = package_ptr->name;
00081           // package_ptr will point to a SrcPackage from now on
00082           package_ptr.swap(srcpkg);
00083         }
00084         package_ptr->arch = Arch(arch);
00085         return true;
00086       }
00087 
00088       // xpath: //package/version
00089       if (reader_r->name() == "version")
00090       {
00091         package_ptr->edition = Edition(reader_r->getAttribute("ver").asString(),
00092                                     reader_r->getAttribute("rel").asString(),
00093                                     reader_r->getAttribute("epoch").asString());
00094         return true;
00095       }
00096 
00097       // xpath: //package/checksum
00098       if (reader_r->name() == "checksum")
00099       {
00100         package_ptr->repositoryLocation.setChecksum(CheckSum(
00101                             reader_r->getAttribute("type").asString(),
00102                             reader_r.nodeText().asString()));
00103         // ignoring pkgid attribute
00104         return true;
00105       }
00106 
00107       // xpath: //package/summary (*)
00108       if (reader_r->name() == "summary")
00109       {
00110         Locale locale(reader_r->getAttribute("lang").asString());
00111         package_ptr->summary.setText(
00112             reader_r.nodeText().asString(), locale);
00113         return true;
00114       }
00115 
00116       // xpath: //package/description (*)
00117       if (reader_r->name() == "description")
00118       {
00119         Locale locale(reader_r->getAttribute("lang").asString());
00120         package_ptr->description.setText(
00121             reader_r.nodeText().asString(), locale);
00122         return true;
00123       }
00124 
00125       // xpath: //package/packager
00126       if (reader_r->name() == "packager")
00127       {
00128         package_ptr->packager = reader_r.nodeText().asString();
00129         return true;
00130       }
00131 
00132       // xpath: //package/url
00133       if (reader_r->name() == "url")
00134       {
00135         package_ptr->url = reader_r.nodeText().asString();
00136         return true;
00137       }
00138 
00139       // xpath: //package/time
00140       if (reader_r->name() == "time")
00141       {
00142         package_ptr->buildTime = reader_r->getAttribute("build").asString();
00143         // ignoring reader_r->getAttribute("file").asString(); (rpm file timestamp)
00144         return true;
00145       }
00146 
00147       // xpath: //package/size
00148       if (reader_r->name() == "size")
00149       {
00151         // reader_r->getAttribute("archive").asString();
00152 
00153         // installed size
00154         package_ptr->installedSize = str::strtonum<ByteCount::SizeType>( reader_r->getAttribute("installed").asString() );
00155 
00156         // rpm package size
00157         package_ptr->repositoryLocation.setDownloadSize(str::strtonum<ByteCount::SizeType>( reader_r->getAttribute("package").asString() ));
00158 
00159         return true;
00160       }
00161 
00162       // xpath: //package/location
00163       if (reader_r->name() == "location")
00164       {
00165         package_ptr->repositoryLocation.setLocation(reader_r->getAttribute("href").asString(), 1);
00166         return true;
00167       }
00168 
00169       // xpath: //package/format
00170       if (reader_r->name() == "format")
00171       {
00172         tag(tag_format);
00173         return true;
00174       }
00175     }
00176 
00177     else if ( reader_r->nodeType() == XML_READER_TYPE_END_ELEMENT )
00178     {
00179       // xpath: //package
00180       if (reader_r->name() == "package")
00181       {
00182         // indicate that further processing is required
00183         // e.g. caller needs to to check for </package> to trigger some action
00184         return false;
00185       }
00186     }
00187 
00188     return true;
00189   }
00190 
00191 
00192   // --------------( consume <format> tag )------------------------------------
00193 
00194   bool FileReaderBase::BaseImpl::consumeFormatNode(
00195     xml::Reader & reader_r, data::Packagebase_Ptr & package_ptr)
00196   {
00197     if (consumeDependency(reader_r, package_ptr->deps))
00198       // this node has been a dependency, which has been handled by
00199       // consumeDependency(), so return right away.
00200       return true;
00201 
00202     // DBG << "format subtag: " << reader_r->name() << endl;
00203 
00204     if (reader_r->nodeType() == XML_READER_TYPE_ELEMENT)
00205     {
00206       // xpath: //format/rpm:license
00207       if (reader_r->name() == "rpm:license")
00208       {
00209         package_ptr->license = reader_r.nodeText().asString();
00210         return true;
00211       }
00212 
00213       // xpath: //format/rpm:vendor
00214       if (reader_r->name() == "rpm:vendor")
00215       {
00216         package_ptr->vendor = reader_r.nodeText().asString();
00217         return true;
00218       }
00219 
00220       // xpath: //format/rpm:group
00221       if (reader_r->name() == "rpm:group")
00222       {
00223         package_ptr->group = reader_r.nodeText().asString();
00224         return true;
00225       }
00226 
00227       // xpath: //format/rpm:buildhost
00228       if (reader_r->name() == "rpm:buildhost")
00229       {
00230         package_ptr->buildhost = reader_r.nodeText().asString();
00231         return true;
00232       }
00233 
00235       if (reader_r->name() == "rpm:sourcerpm")
00236       {
00237         //package->source = reader_r.nodeText().asString();
00238         return true;
00239       }
00240 
00242       if (reader_r->name() == "rpm:header-range")
00243       {
00244         //reader_r->getAttribute("start").asString(),
00245         //reader_r->getAttribute("end").asString(),
00246         return true;
00247       }
00248 
00249       // file entries listed outside of filelists.xml to be treated
00250       // like rpm:provides
00251       // xpath: //format/file (*)
00252       if (reader_r->name() == "file")
00253       {
00254         // insert file dependency into the list
00255         package_ptr->deps[Dep::PROVIDES].insert(
00256           zypp::capability::parse(
00257             ResTraits<Package>::kind,
00258             reader_r.nodeText().asString()));
00259         return true;
00260       }
00261 
00262       // xpath: //format/suse:authors/suse:author (+)
00263       // but tolerating multiplicity (*)
00264       if (reader_r->name() == "suse:author")
00265       {
00266         package_ptr->authors.push_back(reader_r.nodeText().asString());
00267         return true;
00268       }
00269 
00270       // xpath: //format/suse:keywords (?)
00271       // xpath: //format/suse:keywords/suse:keyword (+)
00272       if (reader_r->name() == "suse:keyword")
00273       {
00274         package_ptr->keywords.insert(reader_r.nodeText().asString());
00275         return true;
00276       }
00277 
00279 
00280       // xpath: //format/suse:install-only (?)
00281       if (reader_r->name() == "suse:install-only")
00282       {
00283         package_ptr->installOnly = true;
00284         return true;
00285       }
00286 
00287       // xpath: //format/suse:license-to-confirm (*)
00289       if (reader_r->name() == "suse:license-to-confirm")
00290       {
00291         Locale locale(reader_r->getAttribute("lang").asString());
00292         package_ptr->licenseToConfirm.setText(
00293             reader_r.nodeText().asString(), locale);
00294         return true;
00295       }
00296     }
00297     else if (reader_r->nodeType() == XML_READER_TYPE_END_ELEMENT)
00298     {
00299       // xpath: //format
00300       if (reader_r->name() == "format")
00301       {
00302         toParentTag();
00303         return true;
00304       }
00305     }
00306 
00307     return true;
00308   }
00309 
00310   // --------------------------------------------------------------------------
00311 
00312   bool FileReaderBase::BaseImpl::consumeDependency(
00313     xml::Reader & reader_r, data::Dependencies & deps_r)
00314   {
00315     if (reader_r->nodeType() == XML_READER_TYPE_ELEMENT)
00316     {
00317       // xpath: //format/*/rpm:entry | //format/suse-freshens/suse:entry (+)
00318       if (reader_r->name() == "rpm:entry" | reader_r->name() == "suse:entry")
00319       {
00320         if (!_expect_rpm_entry)
00321           ZYPP_THROW(ParseException("rpm:entry found when not expected"));
00322 
00323         // read kind of resolvable this entry refers, default to Package
00324         string kind_str = reader_r->getAttribute("kind").asString();
00325         Resolvable::Kind kind;
00326         if (kind_str.empty())
00327            kind = ResTraits<Package>::kind;
00328         else
00329           kind = Resolvable::Kind(kind_str);
00330 
00331         // Check whether this is actually a prerequires dependency.
00332         // If so, it will be stored in deps_r as Dep::PREREQUIRES
00333         // instead of Dep::REQUIRES (a prerequires can appear as part
00334         // of requires dependencies only).
00335         bool pre = false;
00336         if (reader_r->getAttribute("pre").asString() == "1")
00337         {
00338           if (_dtype.inSwitch() != Dep::REQUIRES_e)
00339             ZYPP_THROW(ParseException("pre=\"1\" found for non-requires dependency"));
00340           pre = true;
00341         }
00342 /*
00343         DBG << "got rpm:entry for " << _dtype << ": "
00344             << reader_r->getAttribute("name").asString()
00345             << " " << edition << " (" << kind << ")" << endl;
00346 */
00347 
00348         string version = reader_r->getAttribute("ver").asString();
00349 
00350         if (version.empty())
00351         {
00352           // insert unversion dependency into the list
00353           deps_r[pre ? Dep::PREREQUIRES : _dtype].insert(
00354             zypp::capability::parse(
00355               kind, reader_r->getAttribute("name").asString()
00356             )
00357           );
00358         }
00359         else
00360         {
00361           Edition edition(
00362             version,
00363             reader_r->getAttribute("rel").asString(),
00364             reader_r->getAttribute("epoch").asString()
00365           );
00366 
00367           // insert versioned dependency into the list
00368           deps_r[pre ? Dep::PREREQUIRES : _dtype].insert(
00369             zypp::capability::parse(
00370               kind,
00371               reader_r->getAttribute("name").asString(),
00372               Rel(reader_r->getAttribute("flags").asString()),
00373               edition
00374             )
00375           );
00376         }
00377 
00379       }
00380 
00381       // xpath: //format/rpm:provides (?)
00382       if (reader_r->name() == "rpm:provides")
00383       {
00384         _dtype = zypp::Dep::PROVIDES;
00385         _expect_rpm_entry = true;
00386         return true;
00387       }
00388       // xpath: //format/rpm:conflicts (?)
00389       if (reader_r->name() == "rpm:conflicts")
00390       {
00391         _dtype = zypp::Dep::CONFLICTS;
00392         _expect_rpm_entry = true;
00393         return true;
00394       }
00395       // xpath: //format/rpm:obsoletes (?)
00396       if (reader_r->name() == "rpm:obsoletes")
00397       {
00398         _dtype = zypp::Dep::OBSOLETES;
00399         _expect_rpm_entry = true;
00400         return true;
00401       }
00402       // xpath: //format/rpm:requires (?)
00403       if (reader_r->name() == "rpm:requires")
00404       {
00405         _dtype = zypp::Dep::REQUIRES;
00406         _expect_rpm_entry = true;
00407         return true;
00408       }
00409       // xpath: //format/rpm:recommends (?)
00410       if (reader_r->name() == "rpm:recommends")
00411       {
00412         _dtype = zypp::Dep::RECOMMENDS;
00413         _expect_rpm_entry = true;
00414         return true;
00415       }
00416       // xpath: //format/rpm:enhances (?)
00417       if (reader_r->name() == "rpm:enhances")
00418       {
00419         _dtype = zypp::Dep::ENHANCES;
00420         _expect_rpm_entry = true;
00421         return true;
00422       }
00423       // xpath: //format/rpm:supplements (?)
00424       if (reader_r->name() == "rpm:supplements")
00425       {
00426         _dtype = zypp::Dep::SUPPLEMENTS;
00427         _expect_rpm_entry = true;
00428         return true;
00429       }
00430       // xpath: //format/rpm:suggests (?)
00431       if (reader_r->name() == "rpm:suggests")
00432       {
00433         _dtype = zypp::Dep::SUGGESTS;
00434         _expect_rpm_entry = true;
00435         return true;
00436       }
00437       // xpath: //format/suse:freshens (?)
00438       if (reader_r->name() == "suse:freshens")
00439       {
00440         _dtype = zypp::Dep::FRESHENS;
00441         _expect_rpm_entry = true;
00442       }
00443     }
00444     else if (reader_r->nodeType() == XML_READER_TYPE_END_ELEMENT)
00445     {
00446       // xpath: //format/* (?)
00447       if (reader_r->name() == "rpm:requires"
00448           || reader_r->name() == "rpm:provides"
00449           || reader_r->name() == "rpm:conflicts"
00450           || reader_r->name() == "rpm:obsoletes"
00451           || reader_r->name() == "rpm:recommends"
00452           || reader_r->name() == "rpm:enhances"
00453           || reader_r->name() == "rpm:supplements"
00454           || reader_r->name() == "rpm:suggests"
00455           || reader_r->name() == "suse:freshens")
00456       {
00457         _expect_rpm_entry = false;
00458         return true;
00459       }
00460     }
00461 
00462     // tell the caller this has not been a dependency tag (i.e. not processed)
00463     return false;
00464   }
00465 
00466   // --------------------------------------------------------------------------
00467 
00468   string FileReaderBase::BaseImpl::TagPath::asString()
00469   {
00470     ostringstream s;
00471 
00472     s << "(";
00473 
00474     if (depth())
00475     {
00476       TagList::const_iterator p = path.begin();
00477       s << *p;
00478       ++p;
00479 
00480       for (; p != path.end(); ++p)
00481         s << "," << *p;
00482     }
00483     else
00484       s << "empty";
00485 
00486     s << ")";
00487 
00488     return s.str();
00489   }
00490 
00491 
00492     } // ns yum
00493   } // ns parser
00494 } // ns zypp
00495 
00496 // vim: set ts=2 sts=2 sw=2 et ai:

Generated on Tue Sep 25 19:23:03 2007 for libzypp by  doxygen 1.5.3