diff options
author | randomdan <randomdan@localhost> | 2012-02-15 21:20:45 +0000 |
---|---|---|
committer | randomdan <randomdan@localhost> | 2012-02-15 21:20:45 +0000 |
commit | ef236c6da476c67305db11eb80db13d39603798f (patch) | |
tree | fed2cc834419b6877a39ab2aeae1aa568a4852c2 | |
parent | Improved script component caching, performance tweaks and related fixes for p... (diff) | |
download | project2-ef236c6da476c67305db11eb80db13d39603798f.tar.bz2 project2-ef236c6da476c67305db11eb80db13d39603798f.tar.xz project2-ef236c6da476c67305db11eb80db13d39603798f.zip |
Implement our own XInclude code that keeps track of files used and file times allowing for properly implementing script caching's isCurrent
-rw-r--r-- | project2/xml/xmlScriptParser.cpp | 46 | ||||
-rw-r--r-- | project2/xml/xmlScriptParser.h | 3 |
2 files changed, 42 insertions, 7 deletions
diff --git a/project2/xml/xmlScriptParser.cpp b/project2/xml/xmlScriptParser.cpp index d2ee6e7..5091f31 100644 --- a/project2/xml/xmlScriptParser.cpp +++ b/project2/xml/xmlScriptParser.cpp @@ -3,9 +3,11 @@ #include "scripts.h" #include "commonObjects.h" #include "variables-modliteral.h" -#include <libxml/xinclude.h> #include <boost/filesystem/convenience.hpp> +static const std::string XIncludeNS("http://www.w3.org/2001/XInclude"); +static const std::string XIncludeInclude("include"); + XmlScriptParser::XmlScriptParser(const boost::filesystem::path & file) { try { @@ -14,13 +16,39 @@ XmlScriptParser::XmlScriptParser(const boost::filesystem::path & file) catch (const xmlpp::internal_error &) { throw NotReadable(file.string()); } - for (int x; (x = xmlXIncludeProcessFlags(get_document()->cobj(), XML_PARSE_NOXINCNODE)); ) { - if (x < 0) { - throw IncludesError(file.string()); + doIncludes(get_document()->get_root_node(), file); + files.insert(Files::value_type(file, boost::filesystem::last_write_time(file))); +} + +void +XmlScriptParser::doIncludes(xmlpp::Element * e, const boost::filesystem::path & f) +{ + if (e->get_namespace_uri().raw() == XIncludeNS && e->get_name().raw() == XIncludeInclude) { + boost::filesystem::path inc = f.parent_path(); + BOOST_FOREACH(boost::filesystem::path c, boost::filesystem::path(e->get_attribute_value("href").raw())) { + if (c.string() == "..") { + inc = inc.parent_path(); + } + else { + inc /= c; + } + } + if (xmlpp::Element * c = dynamic_cast<xmlpp::Element *>(e->import_node( + xmlpp::DomParser(inc.string()).get_document()->get_root_node()))) { + doIncludes(c, inc); + } + files.insert(Files::value_type(inc, boost::filesystem::last_write_time(inc))); + } + else { + BOOST_FOREACH(xmlpp::Node * n, e->get_children()) { + if (xmlpp::Element * c = dynamic_cast<xmlpp::Element *>(n)) { + doIncludes(c, f); + } } } } + ScriptNodePtr XmlScriptParser::root() const { @@ -34,14 +62,18 @@ void XmlScriptParser::load(const CommonObjects * co, bool childrenOnly) const { ScriptReader::load(co, childrenOnly); - // call me when isCurrent is false - _root.reset(); } bool XmlScriptParser::isCurrent() const { - return false; + BOOST_FOREACH(const Files::value_type & f, files) { + if (boost::filesystem::last_write_time(f.first) != f.second) { + _root.reset(); + return false; + } + } + return true; } class XmlScriptReaderLoader : public ScriptReaderLoader { diff --git a/project2/xml/xmlScriptParser.h b/project2/xml/xmlScriptParser.h index 8fa35c9..2d2d5db 100644 --- a/project2/xml/xmlScriptParser.h +++ b/project2/xml/xmlScriptParser.h @@ -44,6 +44,9 @@ class XmlScriptParser : public xmlpp::DomParser, public ScriptReader { bool isCurrent() const; private: mutable ScriptNodePtr _root; + void doIncludes(xmlpp::Element * e, const boost::filesystem::path & f); + typedef std::map<boost::filesystem::path, std::time_t> Files; + Files files; }; |