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

Generated on Thu Jul 6 00:07:21 2006 for zypp by  doxygen 1.4.6