- Added first draft of the media manager
authorMarius Tomaschewski <mt@suse.de>
Tue, 31 Jan 2006 17:18:50 +0000 (17:18 +0000)
committerMarius Tomaschewski <mt@suse.de>
Tue, 31 Jan 2006 17:18:50 +0000 (17:18 +0000)
zypp/media/Makefile.am
zypp/media/MediaManager.cc [new file with mode: 0644]
zypp/media/MediaManager.h [new file with mode: 0644]

index 035653c..c845f93 100644 (file)
@@ -22,7 +22,8 @@ mediainclude_HEADERS =                \
        MediaSMB.h              \
        MediaCIFS.h             \
        ProxyInfo.h             \
-       MediaCurl.h
+       MediaCurl.h             \
+       MediaManager.h
 
 
 noinst_LTLIBRARIES =   lib@PACKAGE@_media.la
@@ -41,7 +42,8 @@ lib@PACKAGE@_media_la_SOURCES = \
        MediaSMB.cc             \
        MediaCIFS.cc            \
        ProxyInfo.cc            \
-       MediaCurl.cc
+       MediaCurl.cc            \
+       MediaManager.cc
 
 
 lib@PACKAGE@_media_la_LIBADD = proxyinfo/lib@PACKAGE@_media_proxyinfo.la \
diff --git a/zypp/media/MediaManager.cc b/zypp/media/MediaManager.cc
new file mode 100644 (file)
index 0000000..d9f1415
--- /dev/null
@@ -0,0 +1,283 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/MediaManager.cc
+ *
+*/
+#include <zypp/media/MediaException.h>
+#include <zypp/media/MediaManager.h>
+//#include <zypp/media/Mount.h>
+//#include <zypp/media/Hal.h>
+#include <zypp/thread/Mutex.h>
+#include <zypp/thread/MutexLock.h>
+
+#include <zypp/base/Logger.h>
+#include <zypp/Pathname.h>
+#include <zypp/PathInfo.h>
+
+#include <map>
+#include <list>
+#include <iostream>
+
+
+//////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ////////////////////////////////////////////////////////////////////
+
+  ////////////////////////////////////////////////////////////////////
+  namespace media
+  { //////////////////////////////////////////////////////////////////
+
+    using zypp::thread::Mutex;
+    using zypp::thread::MutexLock;
+
+    //////////////////////////////////////////////////////////////////
+    namespace // anonymous
+    { ////////////////////////////////////////////////////////////////
+
+
+      // -------------------------------------------------------------
+      // STATIC
+      static Mutex  g_Mutex;
+
+      typedef std::map<MediaId, MediaVerifierRef> MediaVfyMap;
+      typedef std::map<MediaId, MediaAccessRef>   MediaAccMap;
+
+
+      ////////////////////////////////////////////////////////////////
+    } // anonymous
+    //////////////////////////////////////////////////////////////////
+
+
+    // ---------------------------------------------------------------
+    class MediaManager::Impl
+    {
+    private:
+    /*
+      time_t       mtab_mtime;
+      MountEntries mtab_table;
+    */
+      MediaId      last_mediaid;
+
+    public:
+      MediaVfyMap  mediaVfyMap;
+      MediaAccMap  mediaAccMap;
+
+      Impl()
+        : /* mtab_mtime(0)
+        , */ last_mediaid(0)
+      {}
+
+      ~Impl()
+      {}
+
+      MediaId
+      nextMediaId()
+      {
+        return last_mediaid++;
+      }
+
+      bool hasMediaAcc(MediaId mediaId) const
+      {
+        return mediaAccMap.find(mediaId) != mediaAccMap.end();
+      }
+
+      bool hasVerifier(MediaId mediaId) const
+      {
+        return mediaVfyMap.find(mediaId) != mediaVfyMap.end();
+      }
+
+      /*
+      MountEntries
+      getMountEntries()
+      {
+        if( mtab_mtime == 0 ||
+            mtab_mtime != zypp::PathInfo("/etc/mtab").mtime())
+        {
+          mtab_table = Mount::getEntries("/etc/mtab");
+        }
+        return mtab_table;
+      }
+      */
+    };
+
+
+    // ---------------------------------------------------------------
+    // STATIC
+    zypp::RW_pointer<MediaManager::Impl> MediaManager::m_impl(NULL);
+
+
+    // ---------------------------------------------------------------
+    MediaManager::MediaManager()
+    {
+      MutexLock lock(g_Mutex);
+      if( !m_impl)
+      {
+        m_impl.reset( new MediaManager::Impl());
+      }
+    }
+
+    // ---------------------------------------------------------------
+    MediaManager::~MediaManager()
+    {
+    }
+
+    // ---------------------------------------------------------------
+    MediaId
+    MediaManager::open(const Url &url /*, ... */)
+    {
+      MutexLock lock(g_Mutex);
+
+      // check if we already have this url
+      MediaAccMap::const_iterator a(m_impl->mediaAccMap.begin());
+      for( ; a != m_impl->mediaAccMap.end(); ++a)
+      {
+        // FIXME: not sufficient. each handler should provide
+        //        method to compare its type of media url
+        //        and MediaAccess to choose right handler...
+        if( a->second->url().asString() == url.asString())
+        {
+          return a->first;
+        }
+      }
+
+      // create new access handler for it
+      MediaAccessRef accRef( new MediaAccess());
+      MediaId        nextId( m_impl->nextMediaId());
+
+      m_impl->mediaAccMap[nextId] = accRef;
+
+      accRef->open(url, "");
+
+      return nextId;
+    }
+
+    // ---------------------------------------------------------------
+    void
+    MediaManager::close(MediaId mediaId)
+    {
+      MutexLock lock(g_Mutex);
+
+      if( !m_impl->hasMediaAcc( mediaId))
+        ZYPP_THROW(MediaException("Invalid media id"));
+
+      if( m_impl->hasVerifier( mediaId))
+        ZYPP_THROW(MediaException("Remove verifier first"));
+
+      if( m_impl->mediaAccMap[mediaId]->isAttached())
+        ZYPP_THROW(MediaException("Release media first"));
+
+      m_impl->mediaAccMap[mediaId]->close();
+      m_impl->mediaAccMap.erase(mediaId);
+    }
+
+    // ---------------------------------------------------------------
+    void
+    MediaManager::attach(MediaId mediaId, bool next)
+    {
+      MutexLock lock(g_Mutex);
+
+      if( !m_impl->hasMediaAcc( mediaId))
+        ZYPP_THROW(MediaException("Invalid media id"));
+
+      if( !m_impl->hasVerifier( mediaId))
+        ZYPP_THROW(MediaException("Add a verifier first"));
+
+      m_impl->mediaAccMap[mediaId]->attach(next);
+    }
+
+    // ---------------------------------------------------------------
+    void
+    MediaManager::release(MediaId mediaId, bool eject)
+    {
+      MutexLock lock(g_Mutex);
+
+      if( !m_impl->hasMediaAcc( mediaId))
+        ZYPP_THROW(MediaException("Invalid media id"));
+
+      if( !m_impl->hasVerifier( mediaId))
+        ZYPP_THROW(MediaException("Add a verifier first"));
+
+      m_impl->mediaAccMap[mediaId]->release(eject);
+    }
+
+    // ---------------------------------------------------------------
+    void
+    MediaManager::addVerifier(MediaId mediaId, MediaVerifierRef &ref)
+    {
+      MutexLock lock(g_Mutex);
+
+      if( !ref)
+        ZYPP_THROW(MediaException("Invalid (empty) verifier reference"));
+
+      if( !m_impl->hasMediaAcc( mediaId))
+        ZYPP_THROW(MediaException("Invalid media id"));
+
+      if( m_impl->hasVerifier( mediaId))
+        ZYPP_THROW(MediaException("Remove verifier first"));
+
+      m_impl->mediaVfyMap[mediaId] = ref;
+    }
+
+    // ---------------------------------------------------------------
+    void
+    MediaManager::delVerifier(MediaId mediaId)
+    {
+      MutexLock lock(g_Mutex);
+
+      if( !m_impl->hasMediaAcc( mediaId))
+        ZYPP_THROW(MediaException("Invalid media id"));
+
+      if( !m_impl->hasVerifier( mediaId))
+        ZYPP_THROW(MediaException("Remove verifier first"));
+
+      m_impl->mediaVfyMap.erase(mediaId);
+    }
+
+    // ---------------------------------------------------------------
+    void
+    MediaManager::provideFile(MediaId mediaId, MediaNr mediaNr,
+                              const Pathname &filename,
+                              bool cached, bool checkonly) const
+    {
+      MutexLock lock(g_Mutex);
+
+      if( !m_impl->hasMediaAcc( mediaId))
+        ZYPP_THROW(MediaException("Invalid media id"));
+
+      if( !m_impl->hasVerifier( mediaId))
+        ZYPP_THROW(MediaException("No verifier avaliable"));
+
+      if( !m_impl->mediaAccMap[mediaId]->isAttached())
+      {
+        m_impl->mediaAccMap[mediaId]->attach(false);
+
+        // FIXME: exact communication workflow
+        if( !m_impl->mediaVfyMap[mediaId]->isDesiredMedia(
+             m_impl->mediaAccMap[mediaId], mediaNr))
+        {
+          m_impl->mediaAccMap[mediaId]->release(true);
+
+          ZYPP_THROW(MediaFileNotFoundException(
+            m_impl->mediaAccMap[mediaId]->url(), filename
+          ));
+        }
+      }
+      m_impl->mediaAccMap[mediaId]->provideFile(filename, cached, checkonly);
+    }
+
+    //////////////////////////////////////////////////////////////////
+  } // namespace media
+  ////////////////////////////////////////////////////////////////////
+
+  ////////////////////////////////////////////////////////////////////
+} // namespace zypp
+//////////////////////////////////////////////////////////////////////
+/*
+** vim: set ts=2 sts=2 sw=2 ai et:
+*/
diff --git a/zypp/media/MediaManager.h b/zypp/media/MediaManager.h
new file mode 100644 (file)
index 0000000..9717dca
--- /dev/null
@@ -0,0 +1,183 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/MediaManager.h
+ *
+*/
+#ifndef ZYPP_MEDIA_MEDIAMANAGER_H
+#define ZYPP_MEDIA_MEDIAMANAGER_H
+
+#include <zypp/media/MediaAccess.h>
+#include <zypp/base/NonCopyable.h>
+#include <zypp/base/PtrTypes.h>
+#include <zypp/Pathname.h>
+#include <zypp/Url.h>
+
+
+//////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ////////////////////////////////////////////////////////////////////
+
+  ////////////////////////////////////////////////////////////////////
+  namespace media
+  { //////////////////////////////////////////////////////////////////
+
+    typedef zypp::RW_pointer<MediaAccess> MediaAccessRef;
+    typedef unsigned int                  MediaId;
+    typedef unsigned int                  MediaNr;
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : MediaVerifierBase
+    //
+    /**
+     * Interface to implement a media verifier.
+     */
+    class MediaVerifierBase //: public zypp::NonCopyable
+    {
+    public:
+      MediaVerifierBase()
+      {}
+
+      virtual
+      ~MediaVerifierBase()
+      {}
+
+      /*
+      **
+      ** Do we need this?
+      ** Returns the (cached) count of physical media
+      ** (e.g. nr CDs on SLES10) of the set.
+      **
+      virtual MediaNr
+      mediaCount() const { return 0; }
+      */
+
+      /*
+      ** Check if the specified attached media in the source
+      ** contains desired media number (e.g. SLES10 CD1).
+      ** If not:
+      **   - ask user for correct media
+      **   - it will return retry/abort/....,
+      **     behave according to it
+      ** TODO: exact workflow, need callbacks?
+      */
+      virtual bool
+      isDesiredMedia(MediaAccessRef &ref, MediaNr mediaNr)
+      {
+        return false;
+      }
+
+      /*
+      ** FIXME: signal function to trigger user interactions?
+      */
+    };
+
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : MediaVerifierRef
+    //
+    /**
+     * A shared reference to the MediaVerifier implementation.
+     */
+    typedef zypp::RW_pointer<MediaVerifierBase> MediaVerifierRef;
+
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : MediaManager
+    //
+    /**
+     * FIXME: may have static methods... perhaps we should
+     *        use a zypp::media::manager namespace instead?
+     */
+    class MediaManager: public zypp::base::NonCopyable
+    {
+    public:
+      MediaManager();
+      ~MediaManager();
+
+      /**
+       * open the media, return the ID, throw exception on fail
+       */
+      MediaId
+      open(const Url &url /*, preferedAttachPoint, ... */);
+
+      /**
+       * close the media
+       */
+      void
+      close(MediaId id);
+
+      /**
+       * attach the media using the concrete handler
+       */
+      void attach(MediaId mediaId, bool next = false);
+
+      /**
+       * Release the attached media and optionally eject.
+       */
+      void release(MediaId mediaId, bool eject = false);
+
+      /**
+       * Add verifier for specified media id.
+       */
+      void addVerifier(MediaId mediaId, MediaVerifierRef &ref);
+
+      /**
+       * Remove verifier for specified media id.
+       */
+      void delVerifier(MediaId mediaId);
+
+      /**
+       * Provide provide file denoted by relative path below of the
+       * 'attach point' of the specified media and the path prefix
+       * on the media.
+       *
+       * @param cached  If cached is set to true, the function checks, if
+       *                the file already exists and doesn't download it again
+       *                if it does. Currently only the existence is checked,
+       *                no other file attributes.
+       * @param checkonly If this and 'cached' are set to true only the
+       *                  existence of the file is checked but it's not
+       *                  downloaded. If 'cached' is unset an errer is
+       *                  returned always.
+       *
+       * \throws MediaException
+       *
+       */
+      void provideFile(MediaId mediaId,
+                       MediaNr mediaNr,
+                       const Pathname &filename,
+                       bool            cached    = false,
+                       bool            checkonly = false) const;
+
+      /*
+      ** FIXME: other from MediaHandler/MediaAccess interface...
+      */
+
+    private:
+      class  Impl;
+      static zypp::RW_pointer<MediaManager::Impl> m_impl;
+    };
+
+
+    //////////////////////////////////////////////////////////////////
+  } // namespace media
+  ////////////////////////////////////////////////////////////////////
+
+  ////////////////////////////////////////////////////////////////////
+} // namespace zypp
+//////////////////////////////////////////////////////////////////////
+
+#endif // ZYPP_MEDIA_MEDIAMANAGER_H
+
+/*
+** vim: set ts=2 sts=2 sw=2 ai et:
+*/