YUMPrimaryParser.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00013 #include <zypp/parser/yum/YUMPrimaryParser.h>
00014 #include <istream>
00015 #include <string>
00016 #include "zypp/parser/xml_parser_assert.h"
00017 #include <libxml/xmlstring.h>
00018 #include <libxml/xmlreader.h>
00019 #include <libxml/tree.h>
00020 #include <zypp/parser/LibXMLHelper.h>
00021 #include <zypp/base/Logger.h>
00022 #include <zypp/parser/yum/schemanames.h>
00023 #include <zypp/ZYppFactory.h>
00024 
00025 using namespace std;
00026 namespace zypp
00027 {
00028 namespace parser
00029 {
00030 namespace yum
00031 {
00032 
00033 
00034 YUMPrimaryParser::YUMPrimaryParser(std::istream &is, const std::string& baseUrl, parser::ParserProgress::Ptr progress )
00035     : XMLNodeIterator<YUMPrimaryData_Ptr>(is, baseUrl,PRIMARYSCHEMA, progress)
00036     , _zypp_architecture( getZYpp()->architecture() )
00037 {
00038   if (is.fail())
00039   {
00040     ERR << "Bad stream" << endl;
00041   }
00042   fetchNext();
00043 }
00044 
00045 YUMPrimaryParser::YUMPrimaryParser(const Pathname &filename, const std::string &baseUrl, parser::ParserProgress::Ptr progress )
00046     : XMLNodeIterator<YUMPrimaryData_Ptr>(filename, baseUrl,PRIMARYSCHEMA, progress)
00047     , _zypp_architecture( getZYpp()->architecture() )
00048 {
00049   fetchNext();
00050 }
00051 
00052 YUMPrimaryParser::YUMPrimaryParser()
00053     : _zypp_architecture( getZYpp()->architecture() )
00054 { }
00055 
00056 YUMPrimaryParser::YUMPrimaryParser(YUMPrimaryData_Ptr& entry)
00057     : XMLNodeIterator<YUMPrimaryData_Ptr>(entry)
00058     , _zypp_architecture( getZYpp()->architecture() )
00059 { }
00060 
00061 
00062 YUMPrimaryParser::~YUMPrimaryParser()
00063 {}
00064 
00065 
00066 
00067 
00068 // select for which elements process() will be called
00069 bool
00070 YUMPrimaryParser::isInterested(const xmlNodePtr nodePtr)
00071 {
00072   bool result = (_helper.isElement(nodePtr)
00073                  && _helper.name(nodePtr) == "package");
00074   return result;
00075 }
00076 
00077 
00078 // do the actual processing
00079 YUMPrimaryData_Ptr
00080 YUMPrimaryParser::process(const xmlTextReaderPtr reader)
00081 {
00082   xml_assert(reader);
00083   YUMPrimaryData_Ptr dataPtr = new YUMPrimaryData;
00084   xmlNodePtr dataNode = xmlTextReaderExpand(reader);
00085   xml_assert(dataNode);
00086 
00087   dataPtr->type = _helper.attribute(dataNode,"type");
00088   dataPtr->installOnly = false;
00089   dataPtr->media = "1";
00090 
00091   for (xmlNodePtr child = dataNode->children;
00092        child != 0;
00093        child = child->next)
00094   {
00095     if (_helper.isElement(child))
00096     {
00097       string name = _helper.name(child);
00098       if (name == "name")
00099       {
00100         dataPtr->name = _helper.content(child);
00101       }
00102       else if (name == "arch")
00103       {
00104         dataPtr->arch = _helper.content(child);
00105         try
00106         {
00107           if (!Arch(dataPtr->arch).compatibleWith( _zypp_architecture ))
00108           {
00109             dataPtr = NULL;                     // skip <package>, incompatible architecture
00110             break;
00111           }
00112         }
00113         catch ( const Exception & excpt_r )
00114         {
00115           ZYPP_CAUGHT( excpt_r );
00116           DBG << "Skipping malformed " << dataPtr->arch << endl;
00117           dataPtr = NULL;
00118           break;
00119         }
00120       }
00121       else if (name == "version")
00122       {
00123         dataPtr->epoch = _helper.attribute(child,"epoch");
00124         dataPtr->ver = _helper.attribute(child,"ver");
00125         dataPtr->rel = _helper.attribute(child,"rel");
00126       }
00127       else if (name == "checksum")
00128       {
00129         dataPtr->checksumType = _helper.attribute(child,"type");
00130         dataPtr->checksumPkgid = _helper.attribute(child,"pkgid");
00131         dataPtr->checksum = _helper.content(child);
00132       }
00133       else if (name == "summary")
00134       {
00135         dataPtr->summary = _helper.content(child);
00136       }
00137       else if (name == "description")
00138       {
00139         dataPtr->description = _helper.content(child);
00140       }
00141       else if (name == "packager")
00142       {
00143         dataPtr->packager = _helper.content(child);
00144       }
00145       else if (name == "url")
00146       {
00147         dataPtr->url = _helper.content(child);
00148       }
00149       else if (name == "time")
00150       {
00151         dataPtr->timeFile = _helper.attribute(child,"file");
00152         dataPtr->timeBuild = _helper.attribute(child,"build");
00153       }
00154       else if (name == "size")
00155       {
00156         dataPtr->sizePackage = _helper.attribute(child,"package");
00157         dataPtr->sizeInstalled = _helper.attribute(child,"installed");
00158         dataPtr->sizeArchive = _helper.attribute(child,"archive");
00159       }
00160       else if (name == "location")
00161       {
00162         dataPtr->location = _helper.attribute(child,"href");
00163         dataPtr->media = _helper.attribute(child,"base","#1");
00164         int pos = dataPtr->media.find("#");
00165         if (pos > 0)
00166           dataPtr->media = dataPtr->media.substr(pos + 1);
00167       }
00168       else if (name == "format")
00169       {
00170         parseFormatNode(dataPtr, child);
00171       }
00172       else if (name == "license-to-confirm")
00173       {
00174         dataPtr->license_to_confirm.setText(_helper.content(child), Locale(_helper.attribute(child,"lang")));
00175       }
00176       else
00177       {
00178         WAR << "YUM <metadata> contains the unknown element <" << name << "> "
00179         << _helper.positionInfo(child) << ", skipping" << endl;
00180       }
00181     }
00182   }
00183   return dataPtr;
00184 } /* end process */
00185 
00186 
00187 
00188 void
00189 YUMPrimaryParser::parseFormatNode(YUMPrimaryData_Ptr dataPtr,
00190                                   xmlNodePtr formatNode)
00191 {
00192   if (dataPtr == NULL) return;                  // skipping
00193   xml_assert(formatNode);
00194   dataPtr->installOnly = false;
00195   for (xmlNodePtr child = formatNode->children;
00196        child != 0;
00197        child = child ->next)
00198   {
00199     if (_helper.isElement(child))
00200     {
00201       string name = _helper.name(child);
00202       if (name == "license")
00203       {
00204         dataPtr->license = _helper.content(child);
00205       }
00206       else if (name == "vendor")
00207       {
00208         dataPtr->vendor = _helper.content(child);
00209       }
00210       else if (name == "group")
00211       {
00212         dataPtr->group = _helper.content(child);
00213       }
00214       else if (name == "buildhost")
00215       {
00216         dataPtr->buildhost = _helper.content(child);
00217       }
00218       else if (name == "sourcerpm")
00219       {
00220         dataPtr->sourcerpm = _helper.content(child);
00221       }
00222       else if (name == "header-range")
00223       {
00224         dataPtr->headerStart = _helper.attribute(child,"start");
00225         dataPtr->headerEnd = _helper.attribute(child,"end");
00226       }
00227       else if (name == "provides")
00228       {
00229         parseDependencyEntries(& dataPtr->provides, child);
00230       }
00231       else if (name == "conflicts")
00232       {
00233         parseDependencyEntries(& dataPtr->conflicts, child);
00234       }
00235       else if (name == "obsoletes")
00236       {
00237         parseDependencyEntries(& dataPtr->obsoletes, child);
00238       }
00239       else if (name == "prerequires")
00240       {
00241         parseDependencyEntries(& dataPtr->prerequires, child);
00242       }
00243       else if (name == "requires")
00244       {
00245         parseDependencyEntries(& dataPtr->requires, child);
00246       }
00247       else if (name == "recommends")
00248       {
00249         parseDependencyEntries(& dataPtr->recommends, child);
00250       }
00251       else if (name == "suggests")
00252       {
00253         parseDependencyEntries(& dataPtr->suggests, child);
00254       }
00255       else if (name == "supplements")
00256       {
00257         parseDependencyEntries(& dataPtr->supplements, child);
00258       }
00259       else if (name == "enhances")
00260       {
00261         parseDependencyEntries(& dataPtr->enhances, child);
00262       }
00263       else if (name == "file")
00264       {
00265         dataPtr->files.push_back
00266         (FileData(_helper.content(child),
00267                   _helper.attribute(child,"type")));
00268       }
00269       /* SUSE specific elements */
00270       else if (name == "authors")
00271       {
00272         parseAuthorEntries(& dataPtr->authors, child);
00273       }
00274       else if (name == "keywords")
00275       {
00276         parseKeywordEntries(& dataPtr->keywords, child);
00277       }
00278       else if (name == "dirsizes")
00279       {
00280         parseDirsizeEntries(& dataPtr->dirSizes, child);
00281       }
00282       else if (name == "freshens")
00283       {
00284         parseDependencyEntries(& dataPtr->freshens, child);
00285       }
00286       else if (name == "install-only")
00287       {
00288         dataPtr->installOnly = true;
00289       }
00290       else if (name == "license-to-confirm")
00291       {
00292         dataPtr->license_to_confirm.setText(_helper.content(child), Locale(_helper.attribute(child,"lang")));
00293       }
00294       else
00295       {
00296         WAR << "YUM <format> contains the unknown element <" << name << "> "
00297         << _helper.positionInfo(child) << ", skipping" << endl;
00298       }
00299     }
00300   }
00301 }
00302 
00303 
00304 void
00305 YUMPrimaryParser::parseDependencyEntries(std::list<YUMDependency> *depList,
00306     xmlNodePtr depNode)
00307 {
00308   xml_assert(depList);
00309   xml_assert(depNode);
00310 
00311   for (xmlNodePtr child = depNode->children;
00312        child != 0;
00313        child = child ->next)
00314   {
00315     if (_helper.isElement(child))
00316     {
00317       string name = _helper.name(child);
00318       // we have 2 format for entries
00319       // For YUM repositories
00320       // <entry kind="package" name="foo" epoch="2" ver="3" rel="4" flags="LE"/>
00321       // The slightly modified YUM format the storage backend uses.
00322       // <capability kind="package" >foo-devel &lt;= 3:4-5</capability>
00323 
00324       if (name == "entry")
00325       {
00326         if ( _helper.content(child).empty() )
00327         {
00328           depList->push_back
00329           (YUMDependency(_helper.attribute(child,"kind"),
00330                          _helper.attribute(child,"name"),
00331                          _helper.attribute(child,"flags"),
00332                          _helper.attribute(child,"epoch"),
00333                          _helper.attribute(child,"ver"),
00334                          _helper.attribute(child,"rel"),
00335                          _helper.attribute(child,"pre")));
00336         }
00337         else
00338         { // only for backward compat, before we renamed the tag to capability
00339           depList->push_back
00340           (YUMDependency(_helper.attribute(child,"kind"),
00341                          _helper.content(child)));
00342         }
00343       }
00344       else if ( name == "capability" )
00345       {
00346         depList->push_back
00347         (YUMDependency(_helper.attribute(child,"kind"),
00348                        _helper.content(child)));
00349       }
00350       else
00351       {
00352         WAR << "YUM dependency within <format> contains the unknown element <" << name << "> "
00353         << _helper.positionInfo(child) << ", skipping" << endl;
00354       }
00355     }
00356   }
00357 }
00358 
00359 void
00360 YUMPrimaryParser::parseAuthorEntries(std::list<std::string> *authors,
00361                                      xmlNodePtr node)
00362 {
00363   xml_assert(authors);
00364   xml_assert(node);
00365 
00366   for (xmlNodePtr child = node->children;
00367        child != 0;
00368        child = child ->next)
00369   {
00370     if (_helper.isElement(child))
00371     {
00372       string name = _helper.name(child);
00373       if (name == "author")
00374       {
00375         authors->push_back(_helper.content(child));
00376       }
00377       else
00378       {
00379         WAR << "YUM <authors> contains the unknown element <" << name << "> "
00380         << _helper.positionInfo(child) << ", skipping" << endl;
00381       }
00382     }
00383   }
00384 }
00385 
00386 void YUMPrimaryParser::parseKeywordEntries(std::list<std::string> *keywords,
00387     xmlNodePtr node)
00388 {
00389   xml_assert(keywords);
00390   xml_assert(node);
00391 
00392   for (xmlNodePtr child = node->children;
00393        child != 0;
00394        child = child ->next)
00395   {
00396     if (_helper.isElement(child))
00397     {
00398       string name = _helper.name(child);
00399       if (name == "keyword")
00400       {
00401         keywords->push_back(_helper.content(child));
00402       }
00403       else
00404       {
00405         WAR << "YUM <keywords> contains the unknown element <" << name << "> "
00406         << _helper.positionInfo(child) << ", skipping" << endl;
00407       }
00408     }
00409   }
00410 }
00411 
00412 void YUMPrimaryParser::parseDirsizeEntries(std::list<YUMDirSize> *sizes,
00413     xmlNodePtr node)
00414 {
00415   xml_assert(sizes);
00416   xml_assert(node);
00417 
00418   for (xmlNodePtr child = node->children;
00419        child != 0;
00420        child = child ->next)
00421   {
00422     if (_helper.isElement(child))
00423     {
00424       string name = _helper.name(child);
00425       if (name == "dirsize")
00426       {
00427         sizes->push_back(YUMDirSize(_helper.attribute(child,"path"),
00428                                     _helper.attribute(child,"size-kbyte"),
00429                                     _helper.attribute(child,"filecount")));
00430       }
00431       else
00432       {
00433         WAR << "YUM <dirsizes> contains the unknown element <" << name << "> "
00434         << _helper.positionInfo(child) << ", skipping" << endl;
00435       }
00436     }
00437   }
00438 }
00439 
00440 } // namespace yum
00441 } // namespace parser
00442 } // namespace zypp

Generated on Tue Nov 28 16:49:30 2006 for zypp by  doxygen 1.5.0