]> git.mxchange.org Git - simgear.git/commitdiff
Package management tweaks.
authorJames Turner <zakalawe@mac.com>
Sun, 3 Mar 2013 15:03:25 +0000 (15:03 +0000)
committerJames Turner <zakalawe@mac.com>
Sun, 3 Mar 2013 15:03:25 +0000 (15:03 +0000)
simgear/package/Catalog.cxx
simgear/package/Install.cxx
simgear/package/Root.cxx
simgear/package/Root.hxx

index 9a7a71f1909c3fdb434f79b41692addf0717b8df..67b4eb19b910ff28a618e2cd3bad2c189a11a704 100644 (file)
@@ -80,7 +80,7 @@ protected:
         }
         
         std::string ver(m_owner->root()->catalogVersion());
-        if (props->getStringValue("version") != ver) {
+        if (!checkVersion(ver, props)) {
             SG_LOG(SG_GENERAL, SG_WARN, "downloaded catalog " << m_owner->url() << ", version mismatch:\n\t"
                    << props->getStringValue("version") << " vs required " << ver);
             m_owner->refreshComplete(Delegate::FAIL_VERSION);
@@ -101,6 +101,16 @@ protected:
     }
     
 private:
+    bool checkVersion(const std::string& aVersion, SGPropertyNode* aProps)
+    {
+        BOOST_FOREACH(SGPropertyNode* v, aProps->getChildren("version")) {
+            if (v->getStringValue() == aVersion) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
     Catalog* m_owner;  
     std::string m_buffer;
 };
@@ -129,7 +139,7 @@ Catalog* Catalog::createFromUrl(Root* aRoot, const std::string& aUrl)
 {
     Catalog* c = new Catalog(aRoot);
     Downloader* dl = new Downloader(c, aUrl);
-    aRoot->getHTTPClient()->makeRequest(dl);
+    aRoot->makeHTTPRequest(dl);
     
     return c;
 }
@@ -195,7 +205,7 @@ Catalog::packagesNeedingUpdate() const
 void Catalog::refresh()
 {
     Downloader* dl = new Downloader(this, url());
-    m_root->getHTTPClient()->makeRequest(dl);
+    m_root->makeHTTPRequest(dl);
     m_root->catalogRefreshBegin(this);
 }
 
index a702b0efae597e704fd896cde28beaf8ebfb7b50..93b779990dbd20f18afb67ceaff55d1d876882e0 100644 (file)
@@ -306,7 +306,7 @@ void Install::startUpdate()
     }
     
     m_download = new PackageArchiveDownloader(this);
-    m_package->catalog()->root()->getHTTPClient()->makeRequest(m_download);
+    m_package->catalog()->root()->makeHTTPRequest(m_download);
     m_package->catalog()->root()->startInstall(this);
 }
 
index c91719138735562f4b06d9b1ead393fd064786a5..75eef3bb3c53c1dea737c1cf857daba1abef9f53 100644 (file)
@@ -19,6 +19,9 @@
 
 #include <boost/foreach.hpp>
 #include <cstring>
+#include <map>
+#include <deque>
+#include <set>
 
 #include <simgear/debug/logstream.hxx>
 #include <simgear/props/props_io.hxx>
@@ -34,42 +37,81 @@ namespace simgear {
     
 namespace pkg {
 
+typedef std::map<std::string, Catalog*> CatalogDict;
+    
+class Root::RootPrivate
+{
+public:
+    RootPrivate() :
+        http(NULL),
+        maxAgeSeconds(60 * 60 * 24),
+        delegate(NULL)
+    {
+        
+    }
+    
+    SGPath path;
+    std::string locale;
+    HTTP::Client* http;
+    CatalogDict catalogs;
+    unsigned int maxAgeSeconds;
+    Delegate* delegate;
+    std::string version;
+    
+    std::set<Catalog*> refreshing;
+    std::deque<Install*> updateDeque;
+    std::deque<HTTP::Request_ptr> httpPendingRequests;
+};
+    
+SGPath Root::path() const
+{
+    return d->path;
+}
+    
 void Root::setMaxAgeSeconds(int seconds)
 {
-    m_maxAgeSeconds = seconds;
+    d->maxAgeSeconds = seconds;
 }
 
 void Root::setHTTPClient(HTTP::Client* aHTTP)
 {
-    m_http = aHTTP;
+    d->http = aHTTP;
+    BOOST_FOREACH(HTTP::Request_ptr req, d->httpPendingRequests) {
+        d->http->makeRequest(req);
+    }
+
+    d->httpPendingRequests.clear();
 }
 
-HTTP::Client* Root::getHTTPClient() const
+void Root::makeHTTPRequest(HTTP::Request *req)
 {
-    return m_http;
+    if (d->http) {
+        d->http->makeRequest(req);
+        return;
+    }
+    
+    d->httpPendingRequests.push_back(req);
 }
-
+    
 Root::Root(const SGPath& aPath, const std::string& aVersion) :
-    m_path(aPath),
-    m_http(NULL),
-    m_maxAgeSeconds(60 * 60 * 24),
-    m_delegate(NULL),
-    m_version(aVersion)
+    d(new RootPrivate)
 {
+    d->path = aPath;
+    d->version = aVersion;
     if (getenv("LOCALE")) {
-        m_locale = getenv("LOCALE");
+        d->locale = getenv("LOCALE");
     }
     
-    Dir d(aPath);
-    if (!d.exists()) {
-        d.create(0755);
+    Dir dir(aPath);
+    if (!dir.exists()) {
+        dir.create(0755);
         return;
     }
     
-    BOOST_FOREACH(SGPath c, d.children(Dir::TYPE_DIR)) {
+    BOOST_FOREACH(SGPath c, dir.children(Dir::TYPE_DIR)) {
         Catalog* cat = Catalog::createFromPath(this, c);
         if (cat) {
-           m_catalogs[cat->id()] = cat;     
+           d->catalogs[cat->id()] = cat;
         }
     } // of child directories iteration
 }
@@ -81,13 +123,13 @@ Root::~Root()
     
 std::string Root::catalogVersion() const
 {
-    return m_version;
+    return d->version;
 }
     
 Catalog* Root::getCatalogById(const std::string& aId) const
 {
-    CatalogDict::const_iterator it = m_catalogs.find(aId);
-    if (it == m_catalogs.end()) {
+    CatalogDict::const_iterator it = d->catalogs.find(aId);
+    if (it == d->catalogs.end()) {
         return NULL;
     }
     
@@ -101,8 +143,8 @@ Package* Root::getPackageById(const std::string& aName) const
     Package* pkg = NULL;
     if (lastDot == std::string::npos) {
         // naked package ID
-        CatalogDict::const_iterator it = m_catalogs.begin();
-        for (; it != m_catalogs.end(); ++it) {
+        CatalogDict::const_iterator it = d->catalogs.begin();
+        for (; it != d->catalogs.end(); ++it) {
             pkg = it->second->getPackageById(aName);
             if (pkg) {
                 return pkg;
@@ -125,8 +167,8 @@ Package* Root::getPackageById(const std::string& aName) const
 CatalogList Root::catalogs() const
 {
     CatalogList r;
-    CatalogDict::const_iterator it = m_catalogs.begin();
-    for (; it != m_catalogs.end(); ++it) {
+    CatalogDict::const_iterator it = d->catalogs.begin();
+    for (; it != d->catalogs.end(); ++it) {
         r.push_back(it->second);
     }
     
@@ -138,8 +180,8 @@ Root::packagesMatching(const SGPropertyNode* aFilter) const
 {
     PackageList r;
     
-    CatalogDict::const_iterator it = m_catalogs.begin();
-    for (; it != m_catalogs.end(); ++it) {
+    CatalogDict::const_iterator it = d->catalogs.begin();
+    for (; it != d->catalogs.end(); ++it) {
         PackageList r2(it->second->packagesMatching(aFilter));
         r.insert(r.end(), r2.begin(), r2.end());
     }
@@ -152,8 +194,8 @@ Root::packagesNeedingUpdate() const
 {
     PackageList r;
     
-    CatalogDict::const_iterator it = m_catalogs.begin();
-    for (; it != m_catalogs.end(); ++it) {
+    CatalogDict::const_iterator it = d->catalogs.begin();
+    for (; it != d->catalogs.end(); ++it) {
         PackageList r2(it->second->packagesNeedingUpdate());
         r.insert(r.end(), r2.begin(), r2.end());
     }
@@ -163,9 +205,9 @@ Root::packagesNeedingUpdate() const
 
 void Root::refresh(bool aForce)
 {
-    CatalogDict::iterator it = m_catalogs.begin();
-    for (; it != m_catalogs.end(); ++it) {
-        if (aForce || (it->second->ageInSeconds() > m_maxAgeSeconds)) {
+    CatalogDict::iterator it = d->catalogs.begin();
+    for (; it != d->catalogs.end(); ++it) {
+        if (aForce || (it->second->ageInSeconds() > d->maxAgeSeconds)) {
             it->second->refresh();
         }
     }
@@ -173,17 +215,17 @@ void Root::refresh(bool aForce)
 
 void Root::setDelegate(simgear::pkg::Delegate *aDelegate)
 {
-    m_delegate = aDelegate;
+    d->delegate = aDelegate;
 }
     
 void Root::setLocale(const std::string& aLocale)
 {
-    m_locale = aLocale;
+    d->locale = aLocale;
 }
 
 std::string Root::getLocale() const
 {
-    return m_locale;
+    return d->locale;
 }
 
 void Root::scheduleToUpdate(Install* aInstall)
@@ -199,8 +241,8 @@ void Root::scheduleToUpdate(Install* aInstall)
         dep->install();
     }
 
-    bool wasEmpty = m_updateDeque.empty();    
-    m_updateDeque.push_back(aInstall);
+    bool wasEmpty = d->updateDeque.empty();
+    d->updateDeque.push_back(aInstall);
     
     if (wasEmpty) {
         aInstall->startUpdate();
@@ -209,35 +251,35 @@ void Root::scheduleToUpdate(Install* aInstall)
 
 void Root::startInstall(Install* aInstall)
 {
-    if (m_delegate) {
-        m_delegate->startInstall(aInstall);
+    if (d->delegate) {
+        d->delegate->startInstall(aInstall);
     }
 }
 
 void Root::installProgress(Install* aInstall, unsigned int aBytes, unsigned int aTotal)
 {
-    if (m_delegate) {
-        m_delegate->installProgress(aInstall, aBytes, aTotal);
+    if (d->delegate) {
+        d->delegate->installProgress(aInstall, aBytes, aTotal);
     }
 }
 
 void Root::startNext(Install* aCurrent)
 {
-    if (m_updateDeque.front() != aCurrent) {
+    if (d->updateDeque.front() != aCurrent) {
         SG_LOG(SG_GENERAL, SG_ALERT, "current install of package not head of the deque");
     } else {
-        m_updateDeque.pop_front();
+        d->updateDeque.pop_front();
     }
     
-    if (!m_updateDeque.empty()) {
-        m_updateDeque.front()->startUpdate();
+    if (!d->updateDeque.empty()) {
+        d->updateDeque.front()->startUpdate();
     }
 }
 
 void Root::finishInstall(Install* aInstall)
 {
-    if (m_delegate) {
-        m_delegate->finishInstall(aInstall);
+    if (d->delegate) {
+        d->delegate->finishInstall(aInstall);
     }
     
     startNext(aInstall);
@@ -247,8 +289,8 @@ void Root::failedInstall(Install* aInstall, Delegate::FailureCode aReason)
 {
     SG_LOG(SG_GENERAL, SG_ALERT, "failed to install package:" 
         << aInstall->package()->id() << ":" << aReason);
-    if (m_delegate) {
-        m_delegate->failedInstall(aInstall, aReason);
+    if (d->delegate) {
+        d->delegate->failedInstall(aInstall, aReason);
     }
     
     startNext(aInstall);
@@ -256,15 +298,15 @@ void Root::failedInstall(Install* aInstall, Delegate::FailureCode aReason)
 
 void Root::catalogRefreshBegin(Catalog* aCat)
 {
-    m_refreshing.insert(aCat);
+    d->refreshing.insert(aCat);
 }
 
 void Root::catalogRefreshComplete(Catalog* aCat, Delegate::FailureCode aReason)
 {
-    CatalogDict::iterator catIt = m_catalogs.find(aCat->id());
+    CatalogDict::iterator catIt = d->catalogs.find(aCat->id());
     if (aReason != Delegate::FAIL_SUCCESS) {
-        if (m_delegate) {
-            m_delegate->failedRefresh(aCat, aReason);
+        if (d->delegate) {
+            d->delegate->failedRefresh(aCat, aReason);
         }
         
         // if the failure is permanent, delete the catalog from our
@@ -272,17 +314,17 @@ void Root::catalogRefreshComplete(Catalog* aCat, Delegate::FailureCode aReason)
         bool isPermanentFailure = (aReason == Delegate::FAIL_VERSION);
         if (isPermanentFailure) {
             SG_LOG(SG_GENERAL, SG_WARN, "permanent failure for catalog:" << aCat->id());
-            m_catalogs.erase(catIt);
+            d->catalogs.erase(catIt);
         }
-    } else if (catIt == m_catalogs.end()) {
+    } else if (catIt == d->catalogs.end()) {
         // first fresh, add to our storage now
-        m_catalogs.insert(catIt, CatalogDict::value_type(aCat->id(), aCat));
+        d->catalogs.insert(catIt, CatalogDict::value_type(aCat->id(), aCat));
     }
     
-    m_refreshing.erase(aCat);
-    if (m_refreshing.empty()) {
-        if (m_delegate) {
-            m_delegate->refreshComplete();
+    d->refreshing.erase(aCat);
+    if (d->refreshing.empty()) {
+        if (d->delegate) {
+            d->delegate->refreshComplete();
         }
     }
 }
index ef232187d0d7c548e3c56964c8a69b9a6a631bea..cc38df77a8fa31382a337599f129f77899097fa8 100644 (file)
@@ -19,9 +19,7 @@
 #define SG_PACKAGE_ROOT_HXX
 
 #include <vector>
-#include <map>
-#include <deque>
-#include <set>
+#include <memory> // for auto_ptr
 
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/package/Delegate.hxx>
@@ -31,7 +29,10 @@ class SGPropertyNode;
 namespace simgear
 {
     
-namespace HTTP { class Client; }
+namespace HTTP {
+    class Client;
+    class Request;
+}
     
 namespace pkg
 {
@@ -44,16 +45,13 @@ class Install;
 typedef std::vector<Package*> PackageList;
 typedef std::vector<Catalog*> CatalogList;
 
-typedef std::map<std::string, Catalog*> CatalogDict;
-
 class Root
 {
 public:
     Root(const SGPath& aPath, const std::string& aVersion);
     virtual ~Root();
     
-    SGPath path() const
-        { return m_path; }
+    SGPath path() const;
     
     void setLocale(const std::string& aLocale);
         
@@ -67,8 +65,13 @@ public:
 
     void setHTTPClient(HTTP::Client* aHTTP);
 
-    HTTP::Client* getHTTPClient() const;
-
+    /**
+     * Submit an HTTP request. The Root may delay or queue requests if it needs
+     * too, for example during startup when the HTTP engine may not have been
+     * set yet.
+     */
+    void makeHTTPRequest(HTTP::Request* req);
+    
     /**
      * the version string of the root. Catalogs must match this version,
      * or they will be ignored / rejected.
@@ -112,18 +115,10 @@ private:
     void installProgress(Install* aInstall, unsigned int aBytes, unsigned int aTotal);
     void finishInstall(Install* aInstall);    
     void failedInstall(Install* aInstall, Delegate::FailureCode aReason);
-    
-    SGPath m_path;
-    std::string m_locale;
-    HTTP::Client* m_http;
-    CatalogDict m_catalogs;
-    unsigned int m_maxAgeSeconds;
-    Delegate* m_delegate;
-    std::string m_version;
-    
-    std::set<Catalog*> m_refreshing;
-    std::deque<Install*> m_updateDeque;
-};  
+
+    class RootPrivate;
+    std::auto_ptr<RootPrivate> d;
+};
     
 } // of namespace pkg