From ef236c6da476c67305db11eb80db13d39603798f Mon Sep 17 00:00:00 2001 From: randomdan Date: Wed, 15 Feb 2012 21:20:45 +0000 Subject: Implement our own XInclude code that keeps track of files used and file times allowing for properly implementing script caching's isCurrent --- project2/xml/xmlScriptParser.cpp | 46 ++++++++++++++++++++++++++++++++++------ 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 #include +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(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(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 Files; + Files files; }; -- cgit v1.2.3