From 48b7bbbf7d3acc5a62d49f6f521a026dbff5cfe6 Mon Sep 17 00:00:00 2001 From: Marius Tomaschewski Date: Tue, 31 Jan 2006 17:18:50 +0000 Subject: [PATCH] - Added first draft of the media manager --- zypp/media/Makefile.am | 6 +- zypp/media/MediaManager.cc | 283 +++++++++++++++++++++++++++++++++++++++++++++ zypp/media/MediaManager.h | 183 +++++++++++++++++++++++++++++ 3 files changed, 470 insertions(+), 2 deletions(-) create mode 100644 zypp/media/MediaManager.cc create mode 100644 zypp/media/MediaManager.h diff --git a/zypp/media/Makefile.am b/zypp/media/Makefile.am index 035653c..c845f93 100644 --- a/zypp/media/Makefile.am +++ b/zypp/media/Makefile.am @@ -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 index 0000000..d9f1415 --- /dev/null +++ b/zypp/media/MediaManager.cc @@ -0,0 +1,283 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/media/MediaManager.cc + * +*/ +#include +#include +//#include +//#include +#include +#include + +#include +#include +#include + +#include +#include +#include + + +////////////////////////////////////////////////////////////////////// +namespace zypp +{ //////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////// + namespace media + { ////////////////////////////////////////////////////////////////// + + using zypp::thread::Mutex; + using zypp::thread::MutexLock; + + ////////////////////////////////////////////////////////////////// + namespace // anonymous + { //////////////////////////////////////////////////////////////// + + + // ------------------------------------------------------------- + // STATIC + static Mutex g_Mutex; + + typedef std::map MediaVfyMap; + typedef std::map 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::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 index 0000000..9717dca --- /dev/null +++ b/zypp/media/MediaManager.h @@ -0,0 +1,183 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/media/MediaManager.h + * +*/ +#ifndef ZYPP_MEDIA_MEDIAMANAGER_H +#define ZYPP_MEDIA_MEDIAMANAGER_H + +#include +#include +#include +#include +#include + + +////////////////////////////////////////////////////////////////////// +namespace zypp +{ //////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////// + namespace media + { ////////////////////////////////////////////////////////////////// + + typedef zypp::RW_pointer 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 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 m_impl; + }; + + + ////////////////////////////////////////////////////////////////// + } // namespace media + //////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////// +} // namespace zypp +////////////////////////////////////////////////////////////////////// + +#endif // ZYPP_MEDIA_MEDIAMANAGER_H + +/* +** vim: set ts=2 sts=2 sw=2 ai et: +*/ -- 2.7.4