source factory now produces source from URL and directory, adapted both
authorJiri Srain <jsrain@suse.cz>
Thu, 19 Jan 2006 10:07:50 +0000 (10:07 +0000)
committerJiri Srain <jsrain@suse.cz>
Thu, 19 Jan 2006 10:07:50 +0000 (10:07 +0000)
YUM and SuSEtags sources

14 files changed:
devel/devel.jsrain/SourceRead.cc
zypp/SourceFactory.cc
zypp/SourceFactory.h
zypp/base/String.cc
zypp/base/String.h
zypp/media/MediaAccess.h
zypp/parser/yum/YUMParserData.h
zypp/parser/yum/YUMPatternParser.h
zypp/source/SourceImpl.cc
zypp/source/SourceImpl.h
zypp/source/susetags/SuseTagsImpl.cc
zypp/source/susetags/SuseTagsImpl.h
zypp/source/yum/YUMSourceImpl.cc
zypp/source/yum/YUMSourceImpl.h

index 2424ec7..25c6f52 100644 (file)
@@ -1,18 +1,13 @@
 #include <iostream>
 #include <fstream>
-#include <zypp/base/Logger.h>
-#include <zypp/detail/MessageImpl.h>
-#include <zypp/Message.h>
-#include <zypp/parser/yum/YUMParser.h>
-#include <zypp/base/Logger.h>
 #include <map>
-#include "zypp/source/yum/YUMSource.h"
-
+#include "zypp/base/Logger.h"
+#include "zypp/SourceFactory.h"
+#include "zypp/Source.h"
+#include "zypp/source/SourceImpl.h"
 
 using namespace std;
 using namespace zypp;
-using namespace zypp::source::yum;
-
 
 /******************************************************************
 **
@@ -25,10 +20,19 @@ using namespace zypp::source::yum;
 int main( int argc, char * argv[] )
 {
   INT << "===[START]==========================================" << endl;
-  YUMSource src;
-
-  src.parseSourceMetadata("repodata");
-
+  SourceFactory _f;
+  Pathname p = "/";
+  Url url = Url("ftp://cml.suse.cz/netboot/find/SUSE-10.1-CD-OSS-i386-Alpha4-CD1");
+//  Url url = Url("http://lide.suse.cz/~~jsrain/devel.jsrain");
+//  Url url = Url("dir:/local/zypp/libzypp/devel/devel.jsrain");
+  Source s = _f.createFrom( url, p );
+  ResStore store = s.resolvables();
+  for (ResStore::const_iterator it = store.begin();
+       it != store.end(); it++)
+  {
+    ERR << **it << endl;
+  }
+  ERR << store << endl;
   INT << "===[END]============================================" << endl;
   return 0;
 }
index d968def..c614478 100644 (file)
  *
 */
 #include <iostream>
+#include <fstream>
 #include "zypp/base/Logger.h"
 #include "zypp/base/Exception.h"
+#include "zypp/base/String.h"
 
 #include "zypp/SourceFactory.h"
 #include "zypp/source/Builtin.h"
+#include "zypp/media/MediaAccess.h"
 
 using std::endl;
+using namespace zypp::source;
 
 ///////////////////////////////////////////////////////////////////
 namespace zypp
@@ -73,6 +77,73 @@ namespace zypp
 
     return Source( impl_r );
   }
+  void SourceFactory::listProducts( const Url & url_r, ProductSet & products_r )
+  {
+    if (! url_r.isValid())
+      ZYPP_THROW( Exception("Empty URL passed to SourceFactory") );
+
+    // open the media
+    media::MediaAccess::Ptr media = new media::MediaAccess();
+    media->open( url_r );
+    media->attach();
+    Pathname products_file = Pathname("media.1/products");
+    media->provideFile (products_file);
+    products_file = media->localPath (products_file);
+    scanProductsFile (products_file, products_r);
+    media->release();
+    media->close();
+  }
+
+  Source SourceFactory::createFrom( const Url & url_r, const Pathname & path_r )
+  {
+    if (! url_r.isValid())
+      ZYPP_THROW( Exception("Empty URL passed to SourceFactory") );
+
+    // open the media
+    media::MediaAccess::Ptr media;
+    try {
+      media = new media::MediaAccess();
+      media->open( url_r );
+      media->attach();
+      try
+      {
+       MIL << "Trying the YUM source" << endl;
+       Source::Impl_Ptr impl = new yum::YUMSourceImpl(media, path_r);
+ERR << "Impl created" << endl;
+       return Source(impl);
+      }
+      catch (const Exception & excpt_r)
+      {
+       ZYPP_CAUGHT(excpt_r);
+       WAR << "Not YUM source, trying next type" << endl;
+      }
+      catch (...)
+      {
+       INT << "Unknown exception" << endl;
+      }
+      try
+      {
+       MIL << "Trying the SUSE tags source" << endl;
+       Source::Impl_Ptr impl = new susetags::SuseTagsImpl(media, path_r);
+       return Source(impl);
+      }
+      catch (const Exception & excpt_r)
+      {
+       ZYPP_CAUGHT(excpt_r);
+       WAR << "Not SUSE tags source, trying next type" << endl;
+      }
+    }
+    catch (const media::MediaException & excpt_r)
+    {
+      ZYPP_CAUGHT(excpt_r);
+    }
+    catch (const Exception & excpt_r)
+    {
+      ZYPP_CAUGHT(excpt_r);
+    }
+    ZYPP_THROW(Exception("Cannot create the installatino source"));
+  }
 
   /******************************************************************
   **
@@ -84,6 +155,29 @@ namespace zypp
     return str << "SourceFactory";
   }
 
+  void SourceFactory::scanProductsFile( const Pathname & file_r, ProductSet & pset_r ) const
+  {
+    std::ifstream pfile( file_r.asString().c_str() );
+    while ( pfile.good() ) {
+
+      std::string value = str::getline( pfile, str::TRIM );
+      if ( pfile.bad() ) {
+        ERR << "Error parsing " << file_r << endl;
+        ZYPP_THROW(Exception("Error parsing " + file_r.asString()));
+      }
+      if ( pfile.fail() ) {
+        break; // no data on last line
+      }
+      std::string tag = str::stripFirstWord( value, true );
+
+      if ( tag.size() ) {
+        pset_r.insert( ProductEntry( tag, value ) );
+      }
+    }
+  }
+
+
+
   /////////////////////////////////////////////////////////////////
 } // namespace zypp
 ///////////////////////////////////////////////////////////////////
index 798c88c..9d6dd16 100644 (file)
@@ -17,6 +17,8 @@
 #include "zypp/base/PtrTypes.h"
 
 #include "zypp/Source.h"
+#include "zypp/Url.h"
+#include "zypp/Pathname.h"
 
 ///////////////////////////////////////////////////////////////////
 namespace zypp
@@ -46,11 +48,39 @@ namespace zypp
     */
     Source createFrom( const Source::Impl_Ptr & impl_r );
 
+    /** Construct source from an implementation.
+     * \throw EXCEPTION on fail
+    */
+    Source createFrom( const Url & url_r, const Pathname & path_r = "/" );
+
   private:
     /** Implementation  */
     class Impl;
     /** Pointer to implementation */
     RW_pointer<Impl> _pimpl;
+
+  public:
+   struct ProductEntry {
+      Pathname    _dir;
+      std::string _name;
+      ProductEntry( const Pathname & dir_r = "/", const std::string & name_r = std::string() ){
+        _dir  = dir_r;
+        _name = name_r;
+      }
+      bool operator<( const ProductEntry & rhs ) const {
+        return( _dir.asString() < rhs._dir.asString() );
+      }
+    };
+
+    typedef std::set<ProductEntry> ProductSet;
+
+    /** Check which products are available on the media
+     * \throw Exception or MediaException on fail
+     */
+    void listProducts( const Url & url_r, ProductSet & products_r );
+
+  private:
+    void scanProductsFile( const Pathname & file_r, ProductSet & pset_r ) const;
   };
   ///////////////////////////////////////////////////////////////////
 
index 8f20996..6cdefde 100644 (file)
@@ -120,6 +120,75 @@ namespace zypp
 
       return ret;
     }
+    /******************************************************************
+    **
+    ** FUNCTION NAME : stripFirstWord
+    ** FUNCTION TYPE : std::string
+    **
+    ** DESCRIPTION :
+    */
+    std::string stripFirstWord( std::string & line, const bool ltrim_first )
+    {
+      if ( ltrim_first )
+        line = ltrim( line );
+    
+      if ( line.empty() )
+        return line;
+    
+      std::string ret;
+      std::string::size_type p = line.find_first_of( " \t" );
+    
+      if ( p == std::string::npos ) {
+        // no ws on line
+        ret = line;
+        line.erase();
+      } else if ( p == 0 ) {
+        // starts with ws
+        // ret remains empty
+        line = ltrim( line );
+      }
+      else {
+        // strip word and ltim line
+        ret = line.substr( 0, p );
+        line = ltrim( line.erase( 0, p ) );
+      }
+      return ret;
+    }
+
+    /******************************************************************
+    **
+    **
+    **      FUNCTION NAME : getline
+    **      FUNCTION TYPE : std::string
+    **
+    **      DESCRIPTION :
+    */
+    static inline std::string _getline( std::istream & str, const Trim trim_r )
+    {
+      const unsigned tmpBuffLen = 1024;
+      char           tmpBuff[tmpBuffLen];
+
+      std::string ret;
+      do {
+        str.clear();
+        str.getline( tmpBuff, tmpBuffLen ); // always writes '\0' terminated
+        ret += tmpBuff;
+      } while( str.rdstate() == std::ios::failbit );
+    
+      return trim( ret, trim_r );
+    }
+    
+    std::string getline( std::istream & str, const Trim trim_r )
+    {
+      return _getline(str, trim_r);
+    }
+    
+    std::string getline( std::istream & str, bool trim )
+    {
+      return _getline(str, trim?TRIM:NO_TRIM);
+    }
+
+
 
     /////////////////////////////////////////////////////////////////
   } // namespace str
index 088e0a3..e8022ec 100644 (file)
@@ -301,6 +301,12 @@ namespace zypp
     { return trim( s, R_TRIM ); }
     //@}
 
+    std::string stripFirstWord( std::string & line, const bool ltrim_first );
+
+    std::string getline( std::istream & str, bool trim = false );
+
+    std::string getline( std::istream & str, const Trim trim_r );
+
     /////////////////////////////////////////////////////////////////
   } // namespace str
   ///////////////////////////////////////////////////////////////////
index 604ff5c..1aaed4e 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "zypp/media/MediaException.h"
 #include "zypp/Url.h"
+#include "zypp/base/Logger.h"
 
 namespace zypp {
   namespace media {
index 92deba4..84cf927 100644 (file)
@@ -453,6 +453,7 @@ namespace zypp {
       std::ostream& operator<<(std::ostream &out, const YUMRepomdData& data);
       std::ostream& operator<<(std::ostream &out, const YUMPrimaryData& data);
       std::ostream& operator<<(std::ostream &out, const YUMGroupData& data);
+      std::ostream& operator<<(std::ostream &out, const YUMPatternData& data);
       std::ostream& operator<<(std::ostream &out, const YUMFileListData& data);
       std::ostream& operator<<(std::ostream& out, const YUMOtherData& data);
       std::ostream& operator<<(std::ostream& out, const YUMPatchData& data);
index 3b62e1e..b76629c 100644 (file)
@@ -26,10 +26,10 @@ namespace zypp {
 
       /**
       *
-      * @short Parser for YUM group files.
+      * @short Parser for YUM pattern files.
       *
       * Use this class as an iterator that produces, one after one,
-      * YUMPatternData_Ptr(s) for the XML group elements.
+      * YUMPatternData_Ptr(s) for the XML pattern elements.
       * Here's an example:
       *
       * for (YUMPatternParser iter(anIstream, baseUrl),
index 04a85f5..220906a 100644 (file)
@@ -30,7 +30,10 @@ namespace zypp
     // METHOD NAME : SourceImpl::SourceImpl
     // METHOD TYPE : Ctor
     //
-    SourceImpl::SourceImpl()
+    SourceImpl::SourceImpl(media::MediaAccess::Ptr & media_r,
+                           const Pathname & path_r)
+    : _media (media_r)
+    , _path(path_r)
     {}
 
     ///////////////////////////////////////////////////////////////////
@@ -41,6 +44,12 @@ namespace zypp
     SourceImpl::~SourceImpl()
     {}
 
+    const Pathname SourceImpl::provideFile(const Pathname & file_r)
+    {
+      _media->provideFile (file_r);
+      return _media->localPath (file_r);
+    }
+
     /////////////////////////////////////////////////////////////////
   } // namespace source
   ///////////////////////////////////////////////////////////////////
index 375d5e0..f4e43fd 100644 (file)
@@ -19,6 +19,9 @@
 #include "zypp/base/PtrTypes.h"
 #include "zypp/ResStore.h"
 
+#include "zypp/Pathname.h"
+#include "zypp/media/MediaAccess.h"
+
 ///////////////////////////////////////////////////////////////////
 namespace zypp
 { /////////////////////////////////////////////////////////////////
@@ -42,8 +45,12 @@ namespace zypp
       friend std::ostream & operator<<( std::ostream & str, const SourceImpl & obj );
 
     public:
+      /** Ctor, FIXME it is here only because of target storage */
+      SourceImpl()
+      {}
       /** Ctor. */
-      SourceImpl();
+      SourceImpl(media::MediaAccess::Ptr & media_r,
+                 const Pathname & path_r = "/");
       /** Dtor. */
       virtual ~SourceImpl();
 
@@ -53,6 +60,9 @@ namespace zypp
       const ResStore & resolvables() const
       { return _store; }
 
+      /** Provide a file to local filesystem */
+      const Pathname provideFile(const Pathname & file);
+
       /** Overload to realize stream output. */
       virtual std::ostream & dumpOn( std::ostream & str ) const
       { return str << "SourceImpl"; }
@@ -60,6 +70,10 @@ namespace zypp
     protected:
       /** All resolvables provided by this source. */
       ResStore _store;
+      /** Handle to media which contains this source */
+      media::MediaAccess::Ptr _media;
+      /** Path to the source on the media */
+      Pathname _path;
     };
     ///////////////////////////////////////////////////////////////////
 
index 54a24f8..790cff8 100644 (file)
@@ -35,20 +35,22 @@ namespace zypp
       //       METHOD NAME : SuseTagsImpl::SuseTagsImpl
       //       METHOD TYPE : Ctor
       //
-      SuseTagsImpl::SuseTagsImpl( const Pathname & localDir_r )
+      SuseTagsImpl::SuseTagsImpl( media::MediaAccess::Ptr & media_r, const Pathname & path_r )
+      : SourceImpl(media_r, path_r)
       {
-        PathInfo p( localDir_r );
+        Pathname p = provideFile(path_r + "suse/setup/descr/packages");
+/*        PathInfo p( localDir_r );
         if ( p.isDir() )
           p( localDir_r + "packages" );
         if ( ! p.isFile() )
           ZYPP_THROW( Exception( p.asString()+" is not a file" ) );
         if ( ! p.userMayR() )
           ZYPP_THROW( Exception( p.asString()+" no permission to read" ) );
-
+*/
         DBG << "Going to parse " << p << endl;
-        std::list<Package::Ptr> content( parsePackages( p.path() ) );
+        std::list<Package::Ptr> content( parsePackages( p ) );
         _store.insert( content.begin(), content.end() );
-        DBG << "SuseTagsImpl (fake) from " << p.path() << ": "
+        DBG << "SuseTagsImpl (fake) from " << p << ": "
             << content.size() << " packages" << endl;
       }
 
index 7fee0c4..39e596b 100644 (file)
@@ -38,7 +38,7 @@ namespace zypp
         /** \deprecated Interim ctor
          * \throw EXCEPTION on parse error
         */
-        SuseTagsImpl( const Pathname & localDir_r );
+        SuseTagsImpl( media::MediaAccess::Ptr & media_r, const Pathname & path_r = "/" );
         /** Dtor */
         ~SuseTagsImpl();
 
index 9e38775..b553476 100644 (file)
@@ -47,10 +47,9 @@ namespace zypp
 
       /** Default ctor
       */
-      YUMSourceImpl::YUMSourceImpl()
-      {}
-
-      void YUMSourceImpl::parseSourceMetadata(std::string path)
+      YUMSourceImpl::YUMSourceImpl(media::MediaAccess::Ptr & media_r,
+                                  const Pathname & path_r)
+      : SourceImpl(media_r, path_r)
       {
        std::list<YUMRepomdData_Ptr> repo_primary;
        std::list<YUMRepomdData_Ptr> repo_files;
@@ -62,9 +61,9 @@ namespace zypp
 
        try {
        // first read list of all files in the reposotory
-       std::string filename = path + "/repmod.xml";
+        Pathname filename = provideFile(path_r + "/repomd.xml");
        DBG << "Reading file " << filename << endl;
-       ifstream repo_st(filename.c_str());
+       ifstream repo_st(filename.asString().c_str());
        YUMRepomdParser repomd(repo_st, "");
 
        for(;
@@ -79,6 +78,8 @@ namespace zypp
            repo_other.push_back(*repomd);
          else if ((*repomd)->type == "group")
            repo_group.push_back(*repomd);
+         else if ((*repomd)->type == "pattern")
+           repo_pattern.push_back(*repomd);
          else if ((*repomd)->type == "product")
            repo_product.push_back(*repomd);
          else if ((*repomd)->type == "patches")
@@ -90,7 +91,7 @@ namespace zypp
        catch (...)
        {
        ERR << "Cannot read repomd file, cannot initialize source" << endl;
-//     ZYPP_THROW( Exception("Cannot read repomd file, cannot initialize source") );
+       ZYPP_THROW( Exception("Cannot read repomd file, cannot initialize source") );
        }
        try {
        // now put other and filelist data to structures for easier find
@@ -102,9 +103,9 @@ namespace zypp
             it++)
        {
          // TODO check checksum
-         string filename = (*it)->location;
+         Pathname filename = provideFile(path_r + (*it)->location);
          DBG << "Reading file " << filename << endl;
-         ifstream st(filename.c_str());
+         ifstream st(filename.asString().c_str());
          YUMFileListParser filelist(st, "");
          for (;
               ! filelist.atEnd();
@@ -126,9 +127,9 @@ namespace zypp
             it++)
        {
          // TODO check checksum
-         string filename = (*it)->location;
+         Pathname filename = provideFile(path_r + (*it)->location);
          DBG << "Reading file " << filename << endl;
-         ifstream st(filename.c_str());
+         ifstream st(filename.asString().c_str());
          YUMOtherParser other(st, "");
          for (;
               ! other.atEnd();
@@ -151,9 +152,9 @@ namespace zypp
             it++)
        {
          // TODO check checksum
-         string filename = (*it)->location;
+         Pathname filename = provideFile(path_r + (*it)->location);
          DBG << "Reading file " << filename << endl;
-         ifstream st(filename.c_str());
+         ifstream st(filename.asString().c_str());
          YUMPrimaryParser prim(st, "");
          for (;
               !prim.atEnd();
@@ -196,9 +197,9 @@ namespace zypp
             it++)
        {
          // TODO check checksum
-         string filename = (*it)->location;
+         Pathname filename = provideFile(path_r + (*it)->location);
          DBG << "Reading file " << filename << endl;
-         ifstream st(filename.c_str());
+         ifstream st(filename.asString().c_str());
          YUMGroupParser group(st, "");
          for (;
               !group.atEnd();
@@ -222,9 +223,9 @@ namespace zypp
             it++)
        {
          // TODO check checksum
-         string filename = (*it)->location;
+         Pathname filename = provideFile(path_r + (*it)->location);
          DBG << "Reading file " << filename << endl;
-         ifstream st(filename.c_str());
+         ifstream st(filename.asString().c_str());
          YUMPatternParser pattern(st, "");
          for (;
               !pattern.atEnd();
@@ -248,9 +249,9 @@ namespace zypp
             it++)
        {
          // TODO check checksum
-         string filename = (*it)->location;
+         Pathname filename = provideFile(path_r + (*it)->location);
          DBG << "Reading file " << filename << endl;
-         ifstream st(filename.c_str());
+         ifstream st(filename.asString().c_str());
          YUMProductParser product(st, "");
          for (;
               !product.atEnd();
@@ -275,9 +276,9 @@ namespace zypp
             it++)
        {
          // TODO check checksum
-         string filename = (*it)->location;
+         Pathname filename = provideFile(path_r + (*it)->location);
          DBG << "Reading file " << filename << endl;
-         ifstream st(filename.c_str());
+         ifstream st(filename.asString().c_str());
          YUMPatchesParser patch(st, "");
          for (;
               !patch.atEnd();
@@ -295,9 +296,9 @@ namespace zypp
             it != patch_files.end();
             it++)
        {
-           std::string filename = *it;
+           Pathname filename = provideFile(path_r + *it);
            DBG << "Reading file " << filename << endl;
-           ifstream st(filename.c_str());
+           ifstream st(filename.asString().c_str());
            YUMPatchParser ptch(st, "");
            for(;
                !ptch.atEnd();
index e024dfc..04abaa9 100644 (file)
@@ -42,10 +42,11 @@ namespace zypp
       class YUMSourceImpl : public SourceImpl
       {
       public:
+       /** Ctor, FIXME it is here only because of target storage */
+        YUMSourceImpl()
+       {}
         /** Default ctor */
-        YUMSourceImpl();
-
-       void parseSourceMetadata(std::string path);
+        YUMSourceImpl(media::MediaAccess::Ptr & media_r, const Pathname & path_r = "/");
 
        Package::Ptr createPackage(
          const zypp::parser::yum::YUMPrimaryData & parsed,