00001
00002
00003
00004
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
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
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;
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 }
00154
00155
00156
00157 void
00158 YUMPrimaryParser::parseFormatNode(YUMPrimaryData_Ptr dataPtr,
00159 xmlNodePtr formatNode)
00160 {
00161 if (dataPtr == NULL) return;
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 == "requires") {
00199 parseDependencyEntries(& dataPtr->requires, child);
00200 }
00201 else if (name == "recommends") {
00202 parseDependencyEntries(& dataPtr->recommends, child);
00203 }
00204 else if (name == "suggests") {
00205 parseDependencyEntries(& dataPtr->suggests, child);
00206 }
00207 else if (name == "supplements") {
00208 parseDependencyEntries(& dataPtr->supplements, child);
00209 }
00210 else if (name == "enhances") {
00211 parseDependencyEntries(& dataPtr->enhances, child);
00212 }
00213 else if (name == "file") {
00214 dataPtr->files.push_back
00215 (FileData(_helper.content(child),
00216 _helper.attribute(child,"type")));
00217 }
00218
00219 else if (name == "authors") {
00220 parseAuthorEntries(& dataPtr->authors, child);
00221 }
00222 else if (name == "keywords") {
00223 parseKeywordEntries(& dataPtr->keywords, child);
00224 }
00225 else if (name == "media") {
00226 dataPtr->media = _helper.attribute(child,"mediaid");
00227 }
00228 else if (name == "dirsizes") {
00229 parseDirsizeEntries(& dataPtr->dirSizes, child);
00230 }
00231 else if (name == "freshens") {
00232 parseDependencyEntries(& dataPtr->freshens, child);
00233 }
00234 else if (name == "install-only") {
00235 dataPtr->installOnly = true;
00236 }
00237 else if (name == "license-to-confirm")
00238 {
00239 dataPtr->license_to_confirm.setText(_helper.content(child), Locale(_helper.attribute(child,"lang")));
00240 }
00241 else {
00242 WAR << "YUM <format> contains the unknown element <" << name << "> "
00243 << _helper.positionInfo(child) << ", skipping" << endl;
00244 }
00245 }
00246 }
00247 }
00248
00249
00250 void
00251 YUMPrimaryParser::parseDependencyEntries(list<YUMDependency> *depList,
00252 xmlNodePtr depNode)
00253 {
00254 xml_assert(depList);
00255 xml_assert(depNode);
00256
00257 for (xmlNodePtr child = depNode->children;
00258 child != 0;
00259 child = child ->next) {
00260 if (_helper.isElement(child)) {
00261 string name = _helper.name(child);
00262
00263
00264
00265
00266
00267
00268 if (name == "entry")
00269 {
00270 if ( _helper.content(child).empty() )
00271 {
00272 depList->push_back
00273 (YUMDependency(_helper.attribute(child,"kind"),
00274 _helper.attribute(child,"name"),
00275 _helper.attribute(child,"flags"),
00276 _helper.attribute(child,"epoch"),
00277 _helper.attribute(child,"ver"),
00278 _helper.attribute(child,"rel"),
00279 _helper.attribute(child,"pre")));
00280 }
00281 else
00282 {
00283 depList->push_back
00284 (YUMDependency(_helper.attribute(child,"kind"),
00285 _helper.content(child)));
00286 }
00287 }
00288 else if ( name == "capability" )
00289 {
00290 depList->push_back
00291 (YUMDependency(_helper.attribute(child,"kind"),
00292 _helper.content(child)));
00293 }
00294 else {
00295 WAR << "YUM dependency within <format> contains the unknown element <" << name << "> "
00296 << _helper.positionInfo(child) << ", skipping" << endl;
00297 }
00298 }
00299 }
00300 }
00301
00302 void
00303 YUMPrimaryParser::parseAuthorEntries(list<string> *authors,
00304 xmlNodePtr node)
00305 {
00306 xml_assert(authors);
00307 xml_assert(node);
00308
00309 for (xmlNodePtr child = node->children;
00310 child != 0;
00311 child = child ->next) {
00312 if (_helper.isElement(child)) {
00313 string name = _helper.name(child);
00314 if (name == "author") {
00315 authors->push_back(_helper.content(child));
00316 }
00317 else {
00318 WAR << "YUM <authors> contains the unknown element <" << name << "> "
00319 << _helper.positionInfo(child) << ", skipping" << endl;
00320 }
00321 }
00322 }
00323 }
00324
00325 void YUMPrimaryParser::parseKeywordEntries(list<string> *keywords,
00326 xmlNodePtr node)
00327 {
00328 xml_assert(keywords);
00329 xml_assert(node);
00330
00331 for (xmlNodePtr child = node->children;
00332 child != 0;
00333 child = child ->next) {
00334 if (_helper.isElement(child)) {
00335 string name = _helper.name(child);
00336 if (name == "keyword") {
00337 keywords->push_back(_helper.content(child));
00338 }
00339 else {
00340 WAR << "YUM <keywords> contains the unknown element <" << name << "> "
00341 << _helper.positionInfo(child) << ", skipping" << endl;
00342 }
00343 }
00344 }
00345 }
00346
00347 void YUMPrimaryParser::parseDirsizeEntries(list<YUMDirSize> *sizes,
00348 xmlNodePtr node)
00349 {
00350 xml_assert(sizes);
00351 xml_assert(node);
00352
00353 for (xmlNodePtr child = node->children;
00354 child != 0;
00355 child = child ->next) {
00356 if (_helper.isElement(child)) {
00357 string name = _helper.name(child);
00358 if (name == "dirsize") {
00359 sizes->push_back(YUMDirSize(_helper.attribute(child,"path"),
00360 _helper.attribute(child,"size-kbyte"),
00361 _helper.attribute(child,"filecount")));
00362 }
00363 else {
00364 WAR << "YUM <dirsizes> contains the unknown element <" << name << "> "
00365 << _helper.positionInfo(child) << ", skipping" << endl;
00366 }
00367 }
00368 }
00369 }
00370
00371 }
00372 }
00373 }