#include #include #include "xmlDocumentCache.h" #include #include #include #include #include #include "exceptions.h" #include "curlHelper.h" #include "safeMapFind.h" XmlDocumentCache::Documents XmlDocumentCache::documents; XmlDocumentCache::Queued XmlDocumentCache::queued; AdHoc::Net::CurlMultiHandle XmlDocumentCache::cbf; SimpleMessageException(XmlParseError); SimpleMessageException(DownloadFailed); template static XmlDocumentCache::DocumentPtr helperThrow(const std::string & msg) { throw Exception(msg); } static XmlDocumentCache::DocumentPtr helperReturnDocument(XmlDocumentCache::DomParserPtr dp) { return dp->get_document(); } XmlDocumentCache::DocumentPtr XmlDocumentCache::getDocument(const Glib::ustring & url, const char * encoding, ExecContext * ec) const { Documents::const_iterator i = documents.find(url); if (i == documents.end()) { queue(url, encoding, ec); cbf.performAll(); queued.clear(); } return AdHoc::safeMapLookup(documents, url)(); } void XmlDocumentCache::queue(const Glib::ustring & url, const char *, ExecContext *) const { if (queued.find(url) == queued.end()) { cbf.addCurl(url, [url](std::istream & strm) { try { DomParserPtr doc = DomParserPtr(new xmlpp::DomParser()); doc->parse_stream(strm); XmlDocumentCache::documents.insert(XmlDocumentCache::Documents::value_type(url, boost::bind(helperReturnDocument, doc))); } catch (const AdHoc::Net::CurlException & error) { Logger()->messagebf(LOG_DEBUG, "Download of '%s' failed with error '%s'", url, error.message); XmlDocumentCache::documents.insert(XmlDocumentCache::Documents::value_type(url, boost::bind(helperThrow, error.message))); } })->setopt(CURLOPT_ENCODING, "deflate, gzip"); queued.insert(url); } } class XmlDocumentCacheClearer : public LifeCycle { public: typedef bool KeyType; void onIteration() override { Logger()->messagef(LOG_DEBUG, "%s: Clearing XML document cache", __PRETTY_FUNCTION__); XmlDocumentCache::documents.clear(); Logger()->messagef(LOG_DEBUG, "%s: Cleared XML document cache", __PRETTY_FUNCTION__); } }; NAMEDPLUGIN("XmlDocumentCacheClearer", XmlDocumentCacheClearer, LifeCycle);