summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2012-02-15 21:20:45 +0000
committerrandomdan <randomdan@localhost>2012-02-15 21:20:45 +0000
commitef236c6da476c67305db11eb80db13d39603798f (patch)
treefed2cc834419b6877a39ab2aeae1aa568a4852c2
parentImproved script component caching, performance tweaks and related fixes for p... (diff)
downloadproject2-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.cpp46
-rw-r--r--project2/xml/xmlScriptParser.h3
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;
};