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 == "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
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
00266
00267
00268
00269
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 {
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 }
00375 }
00376 }