XMLFilesBackend.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 #include <ctime>
00014 #include <cstdlib>
00015 #include <cstdio>
00016 
00017 #include "zypp/base/Logger.h"
00018 #include "zypp/base/Exception.h"
00019 #include "zypp/base/Random.h"
00020 #include "zypp/base/Gettext.h"
00021 #include "zypp/CapFactory.h"
00022 #include "zypp/Digest.h"
00023 #include "zypp/ExternalProgram.h"
00024 
00025 #include "zypp/target/store/xml/XMLPatchImpl.h"
00026 #include "zypp/target/store/xml/XMLMessageImpl.h"
00027 #include "zypp/target/store/xml/XMLScriptImpl.h"
00028 #include "zypp/target/store/xml/XMLSelectionImpl.h"
00029 #include "zypp/target/store/xml/XMLProductImpl.h"
00030 #include "zypp/target/store/xml/XMLPatternImpl.h"
00031 #include "zypp/target/store/xml/XMLAtomImpl.h"
00032 
00033 #include "zypp/parser/xmlstore/XMLProductParser.h"
00034 #include "zypp/parser/xmlstore/XMLPatternParser.h"
00035 #include "zypp/parser/xmlstore/XMLPatchParser.h"
00036 #include "zypp/parser/xmlstore/XMLLanguageParser.h"
00037 
00038 #include <iostream>
00039 #include <fstream>
00040 #include <sstream>
00041 #include <streambuf>
00042 
00043 #include <list>
00044 
00045 #include <zypp/TmpPath.h>
00046 #include <zypp/ZYppFactory.h>
00047 #include <zypp/ZYpp.h>
00048 #include <zypp/PathInfo.h>
00049 
00050 #include "XMLFilesBackend.h"
00051 #include "serialize.h"
00052 
00053 //#define ZYPP_DB_DIR "/var/lib/zypp_db/"
00054 #define ZYPP_DB_DIR ( getZYpp()->homePath().asString()+"/db/" )
00055 
00056 using std::endl;
00057 using std::string;
00058 using std::list;
00059 using namespace zypp;
00060 using namespace zypp::filesystem;
00061 
00063 namespace zypp
00064 { 
00065 namespace storage
00066 { 
00067 
00080 struct PRODUCT_TABLE_ENTRY
00081 {
00082   const char * dist_name;
00083   const char * dist_version;
00084   const char * product_name;
00085   const char * product_version;
00086 };
00087 
00093 PRODUCT_TABLE_ENTRY* products_table()
00094 {
00095   static PRODUCT_TABLE_ENTRY products[] = {
00096     { "SUSE-Linux-Enterprise-Desktop-i386", "10-0", "SUSE SLED" , "10" },
00097     { "SUSE-Linux-Enterprise-Desktop-x86_64", "10-0", "SUSE SLED", "10" },
00098     { "SUSE-Linux-Enterprise-Server-i386", "10-0", "SUSE SLES", "10" },
00099     { "SUSE-Linux-Enterprise-Server-x86_64", "10-0", "SUSE SLES", "10" },
00100     { "SUSE-Linux-Enterprise-Server-ppc", "10-0", "SUSE SLES", "10" },
00101     { "SUSE-Linux-Enterprise-Server-ia64", "10-0", "SUSE SLES", "10" },
00102     { "SUSE-Linux-Enterprise-Server-s390x", "10-0", "SUSE SLES", "10" },
00103     { "SUSE-Linux-10.1-CD-download-x86", "10.1-0", "SUSE LINUX", "10.1" },
00104     { "SUSE-Linux-10.1-CD-download-ppc", "10.1-0", "SUSE LINUX", "10.1" },
00105     { "SUSE-Linux-10.1-CD-download-x86_64", "10.1-0", "SUSE LINUX", "10.1" },
00106     { "SUSE-Linux-10.1-CD-x86", "10.1-0", "SUSE LINUX", "10.1" },
00107     { "SUSE-Linux-10.1-CD-ppc", "10.1-0", "SUSE LINUX", "10.1" },
00108     { "SUSE-Linux-10.1-CD-x86_64", "10.1-0", "SUSE LINUX", "10.1" },
00109     { "SUSE-Linux-10.1-DVD9-x86-x86_64", "10.1-0", "SUSE LINUX", "10.1" },
00110     { "SUSE-Linux-10.1-OSS-DVD-x86", "10.1-0", "SUSE LINUX", "10.1" },
00111     { "SUSE-Linux-10.1-DVD-OSS-i386", "10.1-0", "SUSE LINUX", "10.1" },
00112     { "SUSE-Linux-10.1-DVD-OSS-ppc", "10.1-0", "SUSE LINUX", "10.1" },
00113     { "SUSE-Linux-10.1-DVD-OSS-x86_64", "10.1-0", "SUSE LINUX", "10.1" },
00114     { "SUSE-Linux-10.1-FTP", "10.1-0", "SUSE LINUX", "10.1" },
00115     { "SUSE-Linux-10.1-DVD-i386", "10.1-0", "SUSE LINUX", "10.1" },
00116     { "SUSE-Linux-10.1-DVD-x86_64", "10.1-0", "SUSE LINUX", "10.1" },
00117     { "SuSE-Linux-10.1-PromoDVD-i386", "10.1-0", "SUSE LINUX", "10.1" },
00118     { "SUSE-Linux-10.1-DVD9-CTMAGAZIN-x86-x86_64", "10.1-0", "SUSE LINUX", "10.1" },
00119     { "SUSE-Linux-Enterprise-SDK-i386", "10-0", "SLE SDK", "10" },
00120     { "SUSE-Linux-Enterprise-SDK-x86_64", "10-0", "SLE SDK", "10" },
00121     { "SUSE-Linux-Enterprise-SDK-ia64", "10-0", "SLE SDK", "10" },
00122     { "SUSE-Linux-Enterprise-SDK-s390x", "10-0", "SLE SDK", "10" },
00123     { "SUSE-Linux-Enterprise-SDK-ppc", "10-0", "SLE SDK", "10" },
00124     { "SUSE-Linux-Enterprise-RT", "10-0", "SLE RT", "10" },
00125     { 0L, 0L, 0L, 0L }
00126   };
00127 
00128   return products;
00129 }
00130 
00132 //
00133 //      CLASS NAME : XMLFilesBackend::Private
00134 //
00136 class XMLFilesBackend::Private
00137 {
00138   public:
00139   Private()
00140   { }
00141   bool randomFileName;
00142   std::set<Resolvable::Kind> kinds;
00143   std::set<Resolvable::Kind> kinds_flags;
00144   Pathname root;
00145 };
00146 
00148 //
00149 //      CLASS NAME : XMLFilesBackend
00150 //
00152 
00154 //
00155 //      METHOD NAME : XMLFilesBackend::XMLFilesBackend
00156 //      METHOD TYPE : Ctor
00157 //
00158 XMLFilesBackend::XMLFilesBackend(const Pathname &root) : Backend(root)
00159 {
00160   d = new Private;
00161   d->randomFileName = false;
00162   d->root = root;
00163 
00164   // types of resolvables stored (supported)
00165   d->kinds.insert(ResTraits<zypp::Patch>::kind);
00166   //d->kinds.insert(ResTraits<zypp::Message>::kind);
00167   //d->kinds.insert(ResTraits<zypp::Script>::kind);
00168   d->kinds.insert(ResTraits<zypp::Selection>::kind);
00169   d->kinds.insert(ResTraits<zypp::Product>::kind);
00170   d->kinds.insert(ResTraits<zypp::Pattern>::kind);
00171   d->kinds.insert(ResTraits<zypp::Language>::kind);
00172 
00173   // types of resolvables stored (supported)
00174   d->kinds_flags.insert(ResTraits<zypp::Package>::kind);
00175   d->kinds_flags.insert(ResTraits<zypp::Patch>::kind);
00176   //d->kinds.insert(ResTraits<zypp::Message>::kind);
00177   //d->kinds.insert(ResTraits<zypp::Script>::kind);
00178   d->kinds_flags.insert(ResTraits<zypp::Selection>::kind);
00179   d->kinds_flags.insert(ResTraits<zypp::Product>::kind);
00180   d->kinds_flags.insert(ResTraits<zypp::Pattern>::kind);
00181   d->kinds_flags.insert(ResTraits<zypp::Language>::kind);
00182 
00183 
00184   // check if the db exists
00185   if (!isBackendInitialized())
00186   {
00187     DBG << "Database not initialized" << std::endl;
00188     initBackend();
00189     // should be initialized now...
00190     if (!isBackendInitialized())
00191       DBG << "Error, cant init database" << std::endl;
00192     else
00193       DBG << "Database initialized" << std::endl;
00194    }
00195    else
00196    {
00197      DBG << "Database already initialized" << std::endl;
00198    }
00199 }
00200 
00201 Date XMLFilesBackend::timestamp() const
00202 {
00203   PathInfo ts_info = PathInfo( d->root + Pathname(ZYPP_DB_DIR) + "timestamp" );
00204   if ( ts_info.isExist() )
00205   {
00206     return Date(ts_info.mtime());
00207   }
00208   else
00209   {
00210     updateTimestamp();
00211     return Date::now();
00212   }
00213 }
00214 
00215 bool
00216 XMLFilesBackend::isBackendInitialized() const
00217 {
00218   bool ok = true;
00219   Pathname dbdir = d->root +  ZYPP_DB_DIR;
00220   ok = ok && PathInfo(dbdir).isExist();
00221 
00222   bool fixperms = false;
00223 
00224   // The db dir was created with 700 permissions
00225   // see bug #169094
00226   if ( ok && PathInfo(dbdir).perm() == 0700 )
00227   {
00228     if ( geteuid() == 0 )
00229     {
00230       fixperms = true;
00231       WAR << "Wrong permissions for /var/lib/zypp, will fix" << std::endl;
00232 
00233       const char* argv[] =
00234       {
00235         "chmod",
00236         "-R",
00237         "0755",
00238         "/var/lib/zypp",
00239         NULL
00240       };
00241 
00242       ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
00243       prog.close();
00244     }
00245     else
00246     {
00247       WAR << "Wrong permissions for /var/lib/zypp, but can't fix unless you run as root." << std::endl;
00248     }
00249 
00250   }
00251 
00252   // folders for resolvables
00253   std::set<Resolvable::Kind>::const_iterator it_kinds;
00254   for ( it_kinds = d->kinds.begin() ; it_kinds != d->kinds.end(); ++it_kinds )
00255   {
00256     Resolvable::Kind kind = (*it_kinds);
00257     bool isthere = PathInfo( dirForResolvableKind(kind) ).isExist();
00258     ok = ok && isthere;
00259   }
00260 
00261   // resolvable flags folder flags
00262   for ( it_kinds = d->kinds_flags.begin() ; it_kinds != d->kinds_flags.end(); ++it_kinds )
00263   {
00264     Resolvable::Kind kind = (*it_kinds);
00265     bool isthere = PathInfo( dirForResolvableKindFlags(kind) ).isExist();
00266     ok = ok && isthere;
00267   }
00268 
00269   // named flags
00270   bool nmthere = PathInfo( dirForNamedFlags() ).isExist();
00271   ok = ok && nmthere;
00272 
00273   return ok;
00274 }
00275 
00276 void
00277 XMLFilesBackend::initBackend()
00278 {
00279   // all directories are 755 except the sources directory which can contain passwords
00280   // in urls.
00281 
00282   Pathname topdir = d->root + Pathname(ZYPP_DB_DIR);
00283   DBG << "Creating directory structure " << topdir << std::endl;
00284 
00285   if (0 != assert_dir(topdir, 0755))
00286       ZYPP_THROW(Exception("Cannot create XMLBackend db directory " + topdir.asString()));
00287 
00288   // create dir for resolvables
00289   std::set<Resolvable::Kind>::const_iterator it_kinds;
00290   for ( it_kinds = d->kinds.begin() ; it_kinds != d->kinds.end(); ++it_kinds )
00291   {
00292     Resolvable::Kind kind = (*it_kinds);
00293     Pathname p(dirForResolvableKind(kind));
00294     if (0 != assert_dir(p, 0755))
00295       ZYPP_THROW(Exception("Cannot create directory " + p.asString()));
00296     else
00297       MIL << "Created " << p.asString() << std::endl;
00298   }
00299 
00300   // create dir for resolvables flags
00301   for ( it_kinds = d->kinds_flags.begin() ; it_kinds != d->kinds_flags.end(); ++it_kinds )
00302   {
00303     Resolvable::Kind kind = (*it_kinds);
00304     Pathname p(dirForResolvableKindFlags(kind));
00305     if (0 != assert_dir(p, 0755))
00306       ZYPP_THROW(Exception("Cannot create directory " + p.asString()));
00307     else
00308       MIL << "Created " << p.asString() << std::endl;
00309   }
00310 
00311   // dir for named flags
00312   Pathname namedflags(dirForNamedFlags());
00313   if (0 != assert_dir(namedflags, 0755))
00314     ZYPP_THROW(Exception("Cannot create directory " + namedflags.asString()));
00315   else
00316     MIL << "Created " << namedflags.asString() << std::endl;
00317 }
00318 
00319 void XMLFilesBackend::setRandomFileNameEnabled( bool enabled )
00320 {
00321   d->randomFileName = enabled;
00322 }
00323 
00324 std::string
00325 XMLFilesBackend::dirForResolvableKind( Resolvable::Kind kind ) const
00326 {
00327   return Pathname( d->root + Pathname(ZYPP_DB_DIR) + Pathname(resolvableKindToString(kind, true)) ).asString();
00328 }
00329 
00330 std::string
00331 XMLFilesBackend::dirForResolvableKindFlags( Resolvable::Kind kind ) const
00332 {
00333   return Pathname( d->root + Pathname(ZYPP_DB_DIR) + Pathname("flags") + Pathname(resolvableKindToString(kind, true)) ).asString();
00334 }
00335 
00336 std::string
00337 XMLFilesBackend::dirForNamedFlags() const
00338 {
00339   return Pathname( d->root + Pathname(ZYPP_DB_DIR) + Pathname("named-flags")).asString();
00340 }
00341 
00342 std::string
00343 XMLFilesBackend::dirForResolvable( ResObject::constPtr resolvable ) const
00344 {
00345   return dirForResolvableKind(resolvable->kind());
00346 }
00347 
00348 std::string
00349 XMLFilesBackend::dirForResolvableFlags( ResObject::constPtr resolvable ) const
00350 {
00351   return dirForResolvableKindFlags(resolvable->kind());
00352 }
00353 
00354 std::string
00355 XMLFilesBackend::fileNameForNVR( const NVR &nvr ) const
00356 {
00357   std::string filename;
00358   filename = nvr.name;
00359   if ( nvr.edition != Edition::noedition )
00360   {
00361      filename += "-" + nvr.edition.asString();
00362   }
00363   // get rid of spaces and other characters
00364   std::stringstream filename_stream(filename);
00365   std::string filename_encoded = Digest::digest("MD5", filename_stream);
00366   return filename_encoded;
00367 }
00368 
00369 std::string
00370 XMLFilesBackend::fileNameForResolvable( ResObject::constPtr resolvable ) const
00371 {
00372   return fileNameForNVR( NVR( resolvable->name(), resolvable->edition() ) );
00373 }
00374 
00375 std::string
00376 XMLFilesBackend::fullPathForResolvable( ResObject::constPtr resolvable ) const
00377 {
00378   return( Pathname( dirForResolvable(resolvable) ) / fileNameForResolvable(resolvable) ).asString();
00379 }
00380 
00381 std::string
00382 XMLFilesBackend::fullPathForNamedFlags( const std::string &key ) const
00383 {
00384   std::stringstream key_stream(key);
00385   std::string key_encoded = Digest::digest("MD5", key_stream);
00386   return( Pathname( dirForNamedFlags() ) / key_encoded ).asString();
00387 }
00388 
00389 std::string
00390 XMLFilesBackend::fullPathForResolvableFlags( ResObject::constPtr resolvable ) const
00391 {
00392   // flags are in a hidden file with the same name
00393   return( Pathname( dirForResolvableFlags(resolvable) ) / fileNameForResolvable(resolvable) ).asString();
00394 }
00395 
00396 void
00397 XMLFilesBackend::setObjectFlag( ResObject::constPtr resolvable, const std::string &flag )
00398 {
00399   std::set<std::string> flags = objectFlags(resolvable);
00400   flags.insert(flag);
00401   writeObjectFlags(resolvable, flags);
00402 }
00403 
00404 void
00405 XMLFilesBackend::removeObjectFlag( ResObject::constPtr resolvable, const std::string &flag )
00406 {
00407   std::set<std::string> flags = objectFlags(resolvable);
00408   flags.erase(flag);
00409   writeObjectFlags(resolvable, flags);
00410 }
00411 
00412 void
00413 XMLFilesBackend::writeObjectFlags( ResObject::constPtr resolvable, const std::set<std::string> &flags )
00414 {
00415   std::string filename = fullPathForResolvableFlags(resolvable);
00416   writeFlagsInFile( filename, flags );
00417   MIL << "Wrote " << flags.size() << " flags for " << resolvable->name() << " " << resolvable->edition() << std::endl;
00418 }
00419 
00420 std::set<std::string>
00421 XMLFilesBackend::objectFlags( ResObject::constPtr resolvable ) const
00422 {
00423   std::string filename = fullPathForResolvableFlags(resolvable);
00424   return flagsFromFile(filename);
00425 }
00426 
00427 bool
00428 XMLFilesBackend::doesObjectHasFlag( ResObject::constPtr resolvable, const std::string &flag ) const
00429 {
00430   std::set<std::string> flags = objectFlags(resolvable);
00431   return (find(flags.begin(), flags.end(), flag) != flags.end());
00432 }
00433 
00435 // Named Flags API
00437 
00438 void
00439 XMLFilesBackend::setFlag( const std::string &key, const std::string &flag )
00440 {
00441   std::set<std::string> _flags = flags(key);
00442   _flags.insert(flag);
00443   writeFlags(key, _flags);
00444 }
00445 
00446 void
00447 XMLFilesBackend::removeFlag( const std::string &key, const std::string &flag )
00448 {
00449   std::set<std::string> _flags = flags(key);
00450   _flags.erase(flag);
00451   writeFlags(key, _flags);
00452 }
00453 
00454 std::set<std::string>
00455 XMLFilesBackend::flags( const std::string &key ) const
00456 {
00457   std::string filename = fullPathForNamedFlags(key);
00458   return flagsFromFile(filename);
00459 }
00460 
00461 bool
00462 XMLFilesBackend::hasFlag( const std::string &key, const std::string &flag ) const
00463 {
00464   std::set<std::string> _flags = flags(key);
00465   return (find(_flags.begin(), _flags.end(), flag) != _flags.end());
00466 }
00467 
00468 void
00469 XMLFilesBackend::writeFlags( const std::string &key, const std::set<std::string> &pflags )
00470 {
00471   std::string filename = fullPathForNamedFlags(key);
00472   writeFlagsInFile( filename, pflags );
00473   MIL << "Wrote " << pflags.size() << " flags for " << key << std::endl;
00474 }
00475 
00477 // Common functions for both named and resolvable flags
00479 
00480 void
00481 XMLFilesBackend::writeFlagsInFile( const std::string &filename, const std::set<std::string> &pflags )
00482 {
00483   std::ofstream file(filename.c_str());
00484   if (!file) {
00485     ZYPP_THROW (Exception( "Can't open " + filename ) );
00486   }
00487 
00488   try
00489   {
00490     for ( std::set<std::string>::const_iterator it = pflags.begin(); it != pflags.end(); it++)
00491     {
00492       // dont save empty strings
00493       if ( *it == std::string() )
00494         continue;
00495       else
00496         file << *it << std::endl;
00497     }
00498     file << std::endl;
00499     MIL << "Wrote " << pflags.size() << " flags in " << filename << std::endl;
00500   }
00501   catch( std::exception &e )
00502   {
00503     ZYPP_THROW(Exception("Can't write flags to store"));
00504   }
00505   updateTimestamp();
00506 }
00507 
00508 std::set<std::string>
00509 XMLFilesBackend::flagsFromFile( const std::string &filename ) const
00510 {
00511   std::set<std::string> _flags;
00512   // do we have previous saved flags?
00513   if ( ! PathInfo( filename ).isExist() )
00514     return _flags;
00515 
00516   std::ifstream file(filename.c_str());
00517   if (!file) {
00518     ZYPP_THROW (Exception( "Can't open " + filename ) );
00519   }
00520 
00521   std::string buffer;
00522   while(file && !file.eof())
00523   {
00524     getline(file, buffer);
00525     if (buffer == std::string())
00526       continue;
00527 
00528     _flags.insert(buffer);
00529   }
00530   //MIL << "Read " << flags.size() << " flags for " << resolvable->name() << " " << resolvable->edition() << std::endl;
00531   return _flags;
00532 }
00533 
00534 void
00535 XMLFilesBackend::updateTimestamp() const
00536 {
00537   Pathname filename = d->root + Pathname(ZYPP_DB_DIR) + "timestamp";
00538   std::ofstream file(filename.asString().c_str(), std::ios::out);
00539   if (!file)
00540   {
00541     ZYPP_THROW (Exception( "Can't open timestamp file " + filename.asString() ) );
00542   }
00543   file.close();
00544 }
00545 
00547 // Resolvables storage
00549 
00550 void
00551 XMLFilesBackend::storeObject( ResObject::constPtr resolvable )
00552 {
00553   // only ignore if it is not a supported resolvable kind
00554   std::set<Resolvable::Kind>::const_iterator it;
00555   it = find(d->kinds.begin(), d->kinds.end(), resolvable->kind() );
00556   if (it == d->kinds.end())
00557   {
00558     ERR << "This backend was not designed to store resolvable of kind " << resolvableKindToString(resolvable->kind()) << ", ignoring..." << std::endl;
00559     return;
00560   }
00561 
00562   std::string xml = castedToXML(resolvable);
00563   std::string filename = fullPathForResolvable(resolvable);
00564   //DBG << std::endl << xml << std::endl;
00565   std::ofstream file;
00566   //DBG << filename << std::endl;
00567   try
00568   {
00569     file.open(filename.c_str());
00570     file << xml;
00571     file.close();
00572   }
00573   catch(std::exception &e)
00574   {
00575     ERR << "Error saving resolvable " << resolvable << std::endl;
00576     ZYPP_THROW(Exception(e.what()));
00577   }
00578   updateTimestamp();
00579 }
00580 
00581 void
00582 XMLFilesBackend::deleteFileObject( const Pathname &filename ) const
00583 {
00584   try
00585   {
00586     int ret = filesystem::unlink( filename );
00587     if ( ret != 0 && ret != ENOENT )
00588     {
00589       ERR << "Error removing resolvable file " << filename << std::endl;
00590       ZYPP_THROW(Exception("Error deleting " + filename.asString()));
00591     }
00592     updateTimestamp();
00593   }
00594   catch(std::exception &e)
00595   {
00596     ERR << "Error removing resolvable file " << filename << std::endl;
00597     ZYPP_THROW(Exception(e.what()));
00598   }
00599 }
00600 
00601 void
00602 XMLFilesBackend::deleteObject( ResObject::constPtr resolvable )
00603 {
00604   // only ignore if it is not a supported resolvable kind
00605   std::set<Resolvable::Kind>::const_iterator it;
00606   it = find(d->kinds.begin(), d->kinds.end(), resolvable->kind() );
00607   if (it == d->kinds.end())
00608   {
00609     ERR << "This backend was not designed to store resolvable of kind " << resolvableKindToString(resolvable->kind()) << ", ignoring..." << std::endl;
00610     return;
00611   }
00612 
00613   // only remove the file
00614   try
00615   {
00616     deleteFileObject( fullPathForResolvable(resolvable) );
00617   }
00618   catch ( const Exception &e )
00619   {
00620     ERR << "Error removing resolvable " << resolvable << std::endl;
00621     ZYPP_RETHROW(e);
00622   }
00623 }
00624 
00625 std::list<ResObject::Ptr> XMLFilesBackend::resolvablesFromFile( std::string file_path, Resolvable::Kind kind ) const
00626 {
00627   MIL << "[" << resolvableKindToString( kind, false ) << "] - " << file_path << std::endl;
00628   std::list<ResObject::Ptr> resolvables;
00629   std::ifstream res_file(file_path.c_str());
00630   if ( kind == ResTraits<zypp::Patch>::kind )
00631   {
00632     // a patch file can contain more than one patch, but we store only
00633     // one patch, so we break at the first
00634     // FIXME how can we avoid creating this for every object?
00635     try {
00636     XMLPatchParser iter(res_file,"");
00637     for (; !iter.atEnd(); ++iter)
00638     {
00639       Patch::Ptr patch = createPatch(**iter);
00640       resolvables.push_back(patch);
00641       Patch::AtomList atoms = patch->atoms();
00642       for (Patch::AtomList::iterator at = atoms.begin(); at != atoms.end(); at++)
00643         resolvables.push_back(*at);
00644 
00645       break;
00646     }
00647     }
00648     catch (const Exception & excpt_r)
00649     {
00650         ZYPP_CAUGHT( excpt_r );
00651         WAR << "Skipping invalid patch file " << file_path << endl;
00652     }
00653   }
00654   else if ( kind == ResTraits<zypp::Product>::kind )
00655   {
00656     XMLProductParser iter(res_file,"");
00657     for (; !iter.atEnd(); ++iter)
00658     {
00659       resolvables.push_back(createProduct(**iter));
00660       break;
00661     }
00662   }
00663   else if ( kind == ResTraits<zypp::Selection>::kind )
00664   {
00665     XMLPatternParser iter(res_file,"");
00666     for (; !iter.atEnd(); ++iter)
00667     {
00668       resolvables.push_back(createSelection(**iter));
00669       break;
00670     }
00671   }
00672   else if ( kind == ResTraits<zypp::Pattern>::kind )
00673   {
00674     XMLPatternParser iter(res_file,"");
00675     for (; !iter.atEnd(); ++iter)
00676     {
00677       resolvables.push_back(createPattern(**iter));
00678       break;
00679     }
00680   }
00681   else if ( kind == ResTraits<zypp::Language>::kind )
00682   {
00683     XMLLanguageParser iter(res_file,"");
00684     for (; !iter.atEnd(); ++iter)
00685     {
00686       resolvables.push_back(createLanguage(**iter));
00687       break;
00688     }
00689   }
00690   else
00691   {
00692     /* nothing for now */
00693   }
00694   return resolvables;
00695 }
00696 
00697 std::list<ResObject::Ptr>
00698 XMLFilesBackend::storedObjects() const
00699 {
00700   DBG << std::endl;
00701   std::list<ResObject::Ptr> objects;
00702 
00703   std::set<Resolvable::Kind>::const_iterator it_kinds;
00704   for ( it_kinds = d->kinds.begin() ; it_kinds != d->kinds.end(); ++it_kinds )
00705   {
00706     Resolvable::Kind kind = (*it_kinds);
00707     std::list<ResObject::Ptr> objects_for_kind = storedObjects(kind);
00708     std::list<ResObject::Ptr>::iterator it;
00709     for( it = objects_for_kind.begin(); it != objects_for_kind.end(); ++it)
00710     {
00711       //DBG << "adding objects back" << std::endl;
00712       objects.push_back(*it);
00713     }
00714   }
00715   return objects;
00716 }
00717 
00718 std::list<ResObject::Ptr>
00719 XMLFilesBackend::storedObjects(const Resolvable::Kind kind) const
00720 {
00721   std::list<ResObject::Ptr> objects;
00722   Pathname dir_path(dirForResolvableKind(kind));
00723   DBG << "Reading objects of kind " << resolvableKindToString(kind) << " in " << dir_path << std::endl;
00724   // return empty list if the dir does not exist
00725   if ( ! PathInfo( dir_path ).isExist() )
00726   {
00727     ERR << "path " << dir_path << " does not exists. Required to read objects of kind " << resolvableKindToString(kind) << std::endl;
00728     return std::list<ResObject::Ptr>();
00729   }
00730 
00731   list<string> files;
00732   filesystem::readdir( files, dir_path, false /* ignore hidden .name files */ );
00733 
00734   for ( list<string>::const_iterator it = files.begin(); it != files.end(); ++it )
00735   {
00736     Pathname curr_file = dir_path + (*it);
00737     DBG << "[" << resolvableKindToString( kind, false ) << "] - " << curr_file << std::endl;
00738     std::list<ResObject::Ptr> objects_for_file;
00739     objects_for_file = resolvablesFromFile( curr_file.asString(), kind);
00740     for ( std::list<ResObject::Ptr>::iterator it = objects_for_file.begin(); it != objects_for_file.end(); ++it)
00741       objects.push_back(*it);
00742   }
00743 
00744   MIL << "done reading " <<  objects.size() << " stored objects for file of kind " << resolvableKindToString(kind) << std::endl;
00745   return objects;
00746 }
00747 
00748 std::list<ResObject::Ptr>
00749 XMLFilesBackend::storedObjects(const Resolvable::Kind kind, const std::string & name, bool partial_match) const
00750 {
00751   std::list<ResObject::Ptr> result;
00752   std::list<ResObject::Ptr> all;
00753   all = storedObjects(kind);
00754   std::list<ResObject::Ptr>::const_iterator it;
00755   for( it = all.begin(); it != all.end(); ++it)
00756   {
00757     ResObject::Ptr item = *it;
00758     if (item->name() == name )
00759       result.push_back(item);
00760   }
00761   MIL << "done reading stored objects of kind " << resolvableKindToString(kind) << " and keyword [" << name <<"]" << std::endl;
00762   return result;
00763 }
00764 
00765 Patch::Ptr
00766 XMLFilesBackend::createPatch( const zypp::parser::xmlstore::XMLPatchData & parsed ) const
00767 {
00768   try
00769   {
00770     detail::ResImplTraits<XMLPatchImpl>::Ptr impl(new XMLPatchImpl());
00771     impl->_patch_id = parsed.patchId;
00772     impl->_timestamp = str::strtonum<time_t>(parsed.timestamp);
00773     impl->_category = parsed.category;
00774     impl->_reboot_needed = parsed.rebootNeeded;
00775     impl->_affects_pkg_manager = parsed.packageManager;
00776     // impl._atoms -> std::list<shared_ptr<YUMPatchAtom> > parsed.atoms */
00777 
00778     impl->_summary = parsed.summary;
00779     impl->_description = parsed.summary;
00780 
00781     impl->_install_notify = parsed.install_notify;
00782     impl->_delete_notify = parsed.delete_notify;
00783     impl->_license_to_confirm = parsed.license_to_confirm;
00784     impl->_vendor = parsed.vendor;
00785     impl->_size = parsed.size;
00786     impl->_downloadSize = parsed.downloadSize;
00787     impl->_install_only = parsed.install_only;
00788     impl->_build_time = parsed.build_time;
00789     impl->_install_time = parsed.install_time;
00790 
00791     Arch arch;
00792     if (!parsed.arch.empty())
00793       arch = Arch(parsed.arch);
00794 
00795     // Collect basic Resolvable data
00796     NVRAD dataCollect( parsed.name,
00797                        Edition( parsed.ver, parsed.rel, parsed.epoch ), arch,
00798                        createDependencies(parsed, ResTraits<Patch>::kind) );
00799     Patch::Ptr patch = detail::makeResolvableFromImpl( dataCollect, impl );
00800     CapFactory _f;
00801 
00802     //MIL << parsed.atoms.size() << " to process" << std::endl;
00803 
00804     // now process the atoms
00805     ResObject::Ptr atom;
00806     for (std::list<XMLPatchAtomData_Ptr >::const_iterator it = parsed.atoms.begin(); it != parsed.atoms.end(); it++)
00807     {
00808       switch ((*it)->atomType())
00809       {
00810         case XMLPatchAtomData::Atom:
00811         {
00812           // atoms are mostly used for packages
00813           // we dont create a package resolvable and then add it to the atoms list, because we
00814           // dont know if the package is in the pool or not. It is different to Scripts and Messages
00815           // that are actually contributed to the Patch itself, instead we create and atom, make
00816           // the patch require the atom, the atom require and freshens the package.
00817 
00818           // get the parsed patch atom data
00819           XMLPatchAtomData_Ptr atom_data = dynamic_pointer_cast<XMLPatchAtomData>(*it);
00820           atom = createAtom(*atom_data);
00821           impl->_atoms.push_back(atom);
00822           break;
00823         }
00824         case XMLPatchAtomData::Message:
00825         {
00826           XMLPatchMessageData_Ptr message_data = dynamic_pointer_cast<XMLPatchMessageData>(*it);
00827           atom = createMessage(*message_data);
00828           impl->_atoms.push_back(atom);
00829           break;
00830         }
00831         case XMLPatchAtomData::Script:
00832         {
00833           XMLPatchScriptData_Ptr script_data = dynamic_pointer_cast<XMLPatchScriptData>(*it);
00834           atom = createScript(*script_data);
00835           impl->_atoms.push_back(atom);
00836           break;
00837         }
00838         default:
00839           ERR << "Unknown type of atom" << endl;
00840       }
00841       // the patch should depends on its atoms, so we inject a requires on the just created atom resolvable
00842       Capability cap( _f.parse(atom->kind(), atom->name(), Rel::EQ, atom->edition() ));
00843       patch->injectRequires(cap);
00844     }
00845     return patch;
00846   }
00847   catch (const Exception & excpt_r)
00848   {
00849     ZYPP_CAUGHT(excpt_r);
00850     Exception nexcpt("Cannot create patch object");
00851     nexcpt.remember(excpt_r);
00852     ZYPP_THROW(nexcpt);
00853   }
00854   return 0L;
00855 }
00856 
00857 Atom::Ptr
00858 XMLFilesBackend::createAtom( const zypp::parser::xmlstore::XMLPatchAtomData & parsed ) const
00859 {
00860   try
00861   {
00862     detail::ResImplTraits<XMLAtomImpl>::Ptr impl(new XMLAtomImpl());
00863 
00864     Arch arch;
00865     if (!parsed.arch.empty())
00866       arch = Arch(parsed.arch);
00867 
00868     // Collect basic Resolvable data
00869     NVRAD dataCollect( parsed.name, Edition( parsed.ver, parsed.rel, parsed.epoch ), arch, createDependencies(parsed, ResTraits<Atom>::kind) );
00870 
00871     impl->_summary = parsed.summary;
00872     impl->_description = parsed.summary;
00873 
00874     impl->_install_notify = parsed.install_notify;
00875     impl->_delete_notify = parsed.delete_notify;
00876     impl->_license_to_confirm = parsed.license_to_confirm;
00877     impl->_vendor = parsed.vendor;
00878     impl->_size = parsed.size;
00879     impl->_downloadSize = parsed.downloadSize;
00880     impl->_install_only = parsed.install_only;
00881     impl->_build_time = parsed.build_time;
00882     impl->_install_time = parsed.install_time;
00883 
00884     Atom::Ptr atom = detail::makeResolvableFromImpl( dataCollect, impl);
00885     return atom;
00886   }
00887   catch (const Exception & excpt_r)
00888   {
00889     ZYPP_CAUGHT(excpt_r);
00890     Exception nexcpt("Cannot create atom object");
00891     nexcpt.remember(excpt_r);
00892     ZYPP_THROW(nexcpt);
00893   }
00894   return 0L;
00895 }
00896 
00897 Message::Ptr
00898 XMLFilesBackend::createMessage( const zypp::parser::xmlstore::XMLPatchMessageData & parsed ) const
00899 {
00900   try
00901   {
00902     detail::ResImplTraits<XMLMessageImpl>::Ptr impl(new XMLMessageImpl());
00903     impl->_text = parsed.text;
00904 
00905     Arch arch;
00906     if (!parsed.arch.empty())
00907       arch = Arch(parsed.arch);
00908 
00909     impl->_summary = parsed.summary;
00910     impl->_description = parsed.summary;
00911 
00912     impl->_install_notify = parsed.install_notify;
00913     impl->_delete_notify = parsed.delete_notify;
00914     impl->_license_to_confirm = parsed.license_to_confirm;
00915     impl->_vendor = parsed.vendor;
00916     impl->_size = parsed.size;
00917     impl->_downloadSize = parsed.downloadSize;
00918     impl->_install_only = parsed.install_only;
00919     impl->_build_time = parsed.build_time;
00920     impl->_install_time = parsed.install_time;
00921 
00922     // Collect basic Resolvable data
00923     NVRAD dataCollect( parsed.name, Edition( parsed.ver, parsed.rel, parsed.epoch ), arch, createDependencies(parsed, ResTraits<Message>::kind) );
00924     Message::Ptr message = detail::makeResolvableFromImpl( dataCollect, impl);
00925     return message;
00926   }
00927   catch (const Exception & excpt_r)
00928   {
00929     ZYPP_CAUGHT(excpt_r);
00930     Exception nexcpt("Cannot create message object");
00931     nexcpt.remember(excpt_r);
00932     ZYPP_THROW(nexcpt);
00933   }
00934   return 0L;
00935 }
00936 
00937 Script::Ptr
00938 XMLFilesBackend::createScript(const zypp::parser::xmlstore::XMLPatchScriptData & parsed ) const
00939 {
00940   try
00941   {
00942     detail::ResImplTraits<XMLScriptImpl>::Ptr impl(new XMLScriptImpl());
00943 
00944     impl->_doScript = parsed.doScript;
00945     impl->_undoScript = parsed.undoScript;
00946 
00947     Arch arch;
00948     if (!parsed.arch.empty())
00949       arch = Arch(parsed.arch);
00950 
00951     impl->_summary = parsed.summary;
00952     impl->_description = parsed.summary;
00953 
00954     impl->_install_notify = parsed.install_notify;
00955     impl->_delete_notify = parsed.delete_notify;
00956     impl->_license_to_confirm = parsed.license_to_confirm;
00957     impl->_vendor = parsed.vendor;
00958     impl->_size = parsed.size;
00959     impl->_downloadSize = parsed.downloadSize;
00960     impl->_install_only = parsed.install_only;
00961     impl->_build_time = parsed.build_time;
00962     impl->_install_time = parsed.install_time;
00963 
00964     // Collect basic Resolvable data
00965     NVRAD dataCollect( parsed.name, Edition( parsed.ver, parsed.rel, parsed.epoch ), arch, createDependencies(parsed, ResTraits<Script>::kind));
00966     Script::Ptr script = detail::makeResolvableFromImpl( dataCollect, impl );
00967     return script;
00968   }
00969   catch (const Exception & excpt_r)
00970   {
00971     ZYPP_CAUGHT(excpt_r);
00972     Exception nexcpt("Cannot create script object");
00973     nexcpt.remember(excpt_r);
00974     ZYPP_THROW(nexcpt);
00975   }
00976   catch (const std::exception & excpt_r)
00977   {
00978     ERR << excpt_r.what() << endl;
00979     ZYPP_THROW(Exception("Cannot create script object"));
00980   }
00981   return 0L;
00982 }
00983 
00984 Language::Ptr
00985 XMLFilesBackend::createLanguage( const zypp::parser::xmlstore::XMLLanguageData & parsed ) const
00986 {
00987   try
00988   {
00989     return Language::installedInstance( Locale(parsed.name) );
00990   }
00991   catch (const Exception & excpt_r)
00992   {
00993     ZYPP_CAUGHT(excpt_r);
00994     Exception nexcpt("Cannot create language object");
00995     nexcpt.remember(excpt_r);
00996     ZYPP_THROW(nexcpt);
00997   }
00998   return 0L;
00999 }
01000 
01001 
01002 Product::Ptr
01003 XMLFilesBackend::createProduct( const zypp::parser::xmlstore::XMLProductData & parsed ) const
01004 {
01005   try
01006   {
01007     detail::ResImplTraits<XMLProductImpl>::Ptr impl(new XMLProductImpl());
01008 
01009     Edition parser_edition = ( parsed.parser_version.empty() ? Edition::noedition : Edition(parsed.parser_version) );
01010 
01011     impl->_summary = parsed.summary;
01012     impl->_description = parsed.summary;
01013 
01014     impl->_install_notify = parsed.install_notify;
01015     impl->_delete_notify = parsed.delete_notify;
01016     impl->_license_to_confirm = parsed.license_to_confirm;
01017     impl->_vendor = parsed.vendor;
01018     impl->_size = parsed.size;
01019     impl->_downloadSize = parsed.downloadSize;
01020     impl->_install_only = parsed.install_only;
01021     impl->_build_time = parsed.build_time;
01022     impl->_install_time = parsed.install_time;
01023 
01024     impl->_type = parsed.type;
01025     impl->_short_name = parsed.short_name;
01026     impl->_dist_name = parsed.dist_name;
01027     impl->_dist_version = parsed.dist_version;
01028 
01029     if ( parsed.releasenotesurl.size() > 0 )
01030       impl->_release_notes_url = parsed.releasenotesurl;
01031     else
01032       impl->_release_notes_url = Url();
01033 
01034     // update_urls
01035     list<string> update_urls = parsed.update_urls;
01036     for ( list<string>::const_iterator it = update_urls.begin(); it != update_urls.end(); ++it )
01037     {
01038       try
01039       {
01040         Url u(*it);
01041         impl->_update_urls.push_back (u);
01042       }
01043       catch ( const Exception &e )
01044       {
01045         ZYPP_CAUGHT(e);
01046         Exception ne("Error parsing update url: " + e.msg());
01047         ne.remember(e);
01048         ZYPP_THROW(ne);
01049       }
01050     }
01051 
01052     // extra_urls
01053     list<string> extra_urls = parsed.extra_urls;
01054     for ( list<string>::const_iterator it = extra_urls.begin(); it != extra_urls.end(); ++it )
01055     {
01056       try
01057       {
01058         Url u(*it);
01059         impl->_extra_urls.push_back (u);
01060       }
01061       catch ( const Exception &e )
01062       {
01063         ZYPP_CAUGHT(e);
01064         Exception ne("Error parsing extra url: " + e.msg());
01065         ne.remember(e);
01066         ZYPP_THROW(ne);
01067       }
01068     }
01069 
01070     // extra_urls
01071     list<string> optional_urls = parsed.optional_urls;
01072     for ( list<string>::const_iterator it = optional_urls.begin(); it != optional_urls.end(); ++it )
01073     {
01074       try
01075       {
01076         Url u(*it);
01077         impl->_optional_urls.push_back (u);
01078       }
01079       catch ( const Exception &e )
01080       {
01081         ZYPP_CAUGHT(e);
01082         Exception ne("Error parsing optional url: " + e.msg());
01083         ne.remember(e);
01084         ZYPP_THROW(ne);
01085       }
01086     }
01087 
01088     impl->_flags = parsed.flags;
01089 
01090     Arch arch;
01091     if (!parsed.arch.empty())
01092       arch = Arch(parsed.arch);
01093 
01094     Edition prod_edition( parsed.ver, parsed.rel, parsed.epoch );
01095     string prod_name(parsed.name);
01096     // check for product name to see if it was written with distname
01097     // as name as part of https://bugzilla.novell.com/show_bug.cgi?id=205392
01098     bool save_new_product_again_workaround = false;
01099     if ( parser_edition == Edition::noedition )
01100     {
01101       MIL << "Product " << parsed.name << " " << prod_edition << " possibly suffers from bug #205392. checking..." << endl;
01102       PRODUCT_TABLE_ENTRY *all_products = products_table();
01103       while ( all_products->dist_name != 0L )
01104       {
01105         //MIL << "Checking " << parsed.name << " " << prod_edition << " with " << all_products->dist_name << " " << all_products->dist_version << endl;
01106         if ( ( parsed.name == all_products->dist_name ) && ( prod_edition.asString() == all_products->dist_version ) )
01107         {
01108           MIL << "[ATTENTION] Detected bug #205392. Product " << parsed.name << " " << prod_edition << " will be changed to " << all_products->product_name << " " << all_products->product_version << std::endl;
01109 
01110           // save pathname of the old wrong product
01111           Pathname wrong_product = Pathname(dirForResolvableKind(ResTraits<zypp::Product>::kind)) + fileNameForNVR( NVR( parsed.name, prod_edition) );
01112 
01113           // ok, potentially this is a wrong product, well, IT IS!
01114           // overwrte those here as they are used in dataCollect
01115           prod_name = string(all_products->product_name);
01116           prod_edition = Edition(all_products->product_version);
01117 
01118           // those were already set, so reset them.
01119           impl->_dist_name = all_products->dist_name;
01120           impl->_dist_version = Edition(all_products->dist_version);
01121 
01122           // ok, now mark for save this product and delete the old one
01123           deleteFileObject( wrong_product );
01124           MIL << "Fix for bug #205392 Old product deleted." << std::endl;
01125           save_new_product_again_workaround = true;
01126           break;
01127         }
01128         ++all_products;
01129       }
01130 
01131     }
01132 
01133     // replace spaces to underscores
01134     std::replace(prod_name.begin(), prod_name.end(), ' ', '_');
01135 
01136     // Collect basic Resolvable data
01137     NVRAD dataCollect( prod_name, prod_edition, arch, createDependencies(parsed, ResTraits<Product>::kind) );
01138     Product::Ptr product = detail::makeResolvableFromImpl( dataCollect, impl );
01139 
01140     if ( save_new_product_again_workaround )
01141     {
01142       const_cast<XMLFilesBackend *>(this)->storeObject(product);
01143       MIL << "Fixed Product saved. Fix for bug #205392. complete" << std::endl;
01144     }
01145 
01146     return product;
01147   }
01148   catch (const Exception & excpt_r)
01149   {
01150     ZYPP_CAUGHT(excpt_r);
01151     Exception nexcpt("Cannot create product object");
01152     nexcpt.remember(excpt_r);
01153     ZYPP_THROW(nexcpt);
01154   }
01155   return 0L;
01156 }
01157 
01158 Pattern::Ptr
01159 XMLFilesBackend::createPattern( const zypp::parser::xmlstore::XMLPatternData & parsed ) const
01160 {
01161   try
01162   {
01163     detail::ResImplTraits<XMLPatternImpl>::Ptr impl(new XMLPatternImpl());
01164 
01165     impl->_summary = parsed.summary;
01166     impl->_description = parsed.summary;
01167 
01168     impl->_install_notify = parsed.install_notify;
01169     impl->_delete_notify = parsed.delete_notify;
01170     impl->_license_to_confirm = parsed.license_to_confirm;
01171     impl->_vendor = parsed.vendor;
01172     impl->_size = parsed.size;
01173     impl->_downloadSize = parsed.downloadSize;
01174     impl->_install_only = parsed.install_only;
01175     impl->_build_time = parsed.build_time;
01176     impl->_install_time = parsed.install_time;
01177 
01178     impl->_user_visible = parsed.userVisible;
01179     impl->_default = ((parsed.default_ == "false" ) ? false : true );
01180     impl->_category = parsed.category;
01181     impl->_icon = parsed.icon;
01182     impl->_script = parsed.script;
01183 
01184     Arch arch;
01185     if (!parsed.arch.empty())
01186       arch = Arch(parsed.arch);
01187 
01188     // Workaround for bug #307743:
01189     // Hijack installed patterns with empty vendor.
01190     if ( impl->_vendor.empty() )
01191     {
01192       impl->_vendor = "SUSE (assumed)";
01193     }
01194 
01195     // Collect basic Resolvable data
01196     NVRAD dataCollect( parsed.name, Edition( parsed.ver, parsed.rel, parsed.epoch ), arch, createDependencies( parsed, ResTraits<Pattern>::kind));
01197     Pattern::Ptr pattern = detail::makeResolvableFromImpl( dataCollect, impl );
01198     return pattern;
01199   }
01200   catch (const Exception & excpt_r)
01201   {
01202     ZYPP_CAUGHT(excpt_r);
01203     Exception nexcpt("Cannot create installation pattern object");
01204     nexcpt.remember(excpt_r);
01205     ZYPP_THROW(nexcpt);
01206   }
01207   return 0L;
01208 }
01209 
01210 Selection::Ptr
01211 XMLFilesBackend::createSelection( const zypp::parser::xmlstore::XMLPatternData & parsed ) const
01212 {
01213   try
01214   {
01215     detail::ResImplTraits<XMLSelectionImpl>::Ptr impl(new XMLSelectionImpl());
01216 
01217     impl->_summary = parsed.summary;
01218     impl->_description = parsed.summary;
01219 
01220     impl->_install_notify = parsed.install_notify;
01221     impl->_delete_notify = parsed.delete_notify;
01222     impl->_license_to_confirm = parsed.license_to_confirm;
01223     impl->_vendor = parsed.vendor;
01224     impl->_size = parsed.size;
01225     impl->_downloadSize = parsed.downloadSize;
01226     impl->_install_only = parsed.install_only;
01227     impl->_build_time = parsed.build_time;
01228     impl->_install_time = parsed.install_time;
01229 
01230     impl->_visible = parsed.userVisible;
01231     impl->_name = parsed.name;
01232     //impl->_default = ((parsed.default_ == "false" ) ? false : true );
01233     impl->_category = parsed.category;
01234 
01235     Arch arch;
01236     if (!parsed.arch.empty())
01237       arch = Arch(parsed.arch);
01238 
01239     // Collect basic Resolvable data
01240     NVRAD dataCollect( parsed.name, Edition( parsed.ver, parsed.rel, parsed.epoch ), arch, createDependencies( parsed, ResTraits<Pattern>::kind));
01241     Selection::Ptr selection = detail::makeResolvableFromImpl( dataCollect, impl );
01242     return selection;
01243   }
01244   catch (const Exception & excpt_r)
01245   {
01246     ZYPP_CAUGHT(excpt_r);
01247     Exception nexcpt("Cannot create installation selection object");
01248     nexcpt.remember(excpt_r);
01249     ZYPP_THROW(nexcpt);
01250   }
01251   return 0L;
01252 }
01253 
01254 Dependencies
01255 XMLFilesBackend::createDependencies( const zypp::parser::xmlstore::XMLResObjectData & parsed, const Resolvable::Kind my_kind ) const
01256 {
01257   Dependencies _deps;
01258   for (std::list<XMLDependency>::const_iterator it = parsed.provides.begin(); it != parsed.provides.end(); it++)
01259   {
01260     _deps[Dep::PROVIDES].insert(createCapability(*it, my_kind));
01261   }
01262   for (std::list<XMLDependency>::const_iterator it = parsed.conflicts.begin(); it != parsed.conflicts.end(); it++)
01263   {
01264     _deps[Dep::CONFLICTS].insert(createCapability(*it, my_kind));
01265   }
01266 
01267   for (std::list<XMLDependency>::const_iterator it = parsed.obsoletes.begin(); it != parsed.obsoletes.end(); it++)
01268   {
01269     _deps[Dep::OBSOLETES].insert(createCapability(*it, my_kind));
01270   }
01271 
01272   for (std::list<XMLDependency>::const_iterator it = parsed.freshens.begin(); it != parsed.freshens.end(); it++)
01273   {
01274     _deps[Dep::FRESHENS].insert(createCapability(*it, my_kind));
01275   }
01276 
01277   for (std::list<XMLDependency>::const_iterator it = parsed.recommends.begin(); it != parsed.recommends.end(); it++)
01278   {
01279     _deps[Dep::RECOMMENDS].insert(createCapability(*it, my_kind));
01280   }
01281 
01282   for (std::list<XMLDependency>::const_iterator it = parsed.suggests.begin(); it != parsed.suggests.end(); it++)
01283   {
01284     _deps[Dep::SUGGESTS].insert(createCapability(*it, my_kind));
01285   }
01286 
01287   for (std::list<XMLDependency>::const_iterator it = parsed.enhances.begin(); it != parsed.enhances.end(); it++)
01288   {
01289     _deps[Dep::ENHANCES].insert(createCapability(*it, my_kind));
01290   }
01291 
01292   for (std::list<XMLDependency>::const_iterator it = parsed.requires.begin(); it != parsed.requires.end(); it++)
01293   {
01294     _deps[Dep::REQUIRES].insert(createCapability(*it, my_kind));
01295   }
01296 
01297   for (std::list<XMLDependency>::const_iterator it = parsed.prerequires.begin(); it != parsed.prerequires.end(); it++)
01298   {
01299     _deps[Dep::PREREQUIRES].insert(createCapability(*it, my_kind));
01300   }
01301   return _deps;
01302 }
01303 
01304 Capability
01305 XMLFilesBackend::createCapability(const XMLDependency & dep, const Resolvable::Kind & my_kind) const
01306 {
01307   CapFactory _f;
01308   Resolvable::Kind _kind = dep.kind == "" ? my_kind : Resolvable::Kind(dep.kind);
01309   Capability cap;
01310   cap = _f.parse( _kind, dep.encoded );
01311   return cap;
01312 }
01313 
01315 //
01316 //      METHOD NAME : XMLFilesBackend::~XMLFilesBackend
01317 //      METHOD TYPE : Dtor
01318 //
01319 XMLFilesBackend::~XMLFilesBackend()
01320 {
01321   delete d;
01322 }
01323 
01325 //
01326 //      METHOD NAME : XMLFilesBackend::doTest()
01327 //      METHOD TYPE : Dtor
01328 //
01329 void XMLFilesBackend::doTest()
01330 {}
01331 
01332 /******************************************************************
01333 **
01334 **      FUNCTION NAME : operator<<
01335 **      FUNCTION TYPE : std::ostream &
01336 */
01337 std::ostream & operator<<( std::ostream & str, const XMLFilesBackend & obj )
01338 {
01339         return str;
01340 }
01341 
01343 } // namespace storage
01346 } // namespace zypp

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