diff options
Diffstat (limited to 'project2/envproc.cpp')
-rw-r--r-- | project2/envproc.cpp | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/project2/envproc.cpp b/project2/envproc.cpp new file mode 100644 index 0000000..0313c0f --- /dev/null +++ b/project2/envproc.cpp @@ -0,0 +1,78 @@ +#include "envproc.h" +#include "rdbmsDataSource.h" +#include "sqlView.h" +#include <map> +#include <libxml/tree.h> +#include <libxml/xinclude.h> +#include <boost/shared_ptr.hpp> +#include <boost/any.hpp> +#include <boost/foreach.hpp> + +void +EnvironmentProcessor::init() +{ + elems = regexExtractSet("/([^/?]+)", request_uri.c_str()); + params = regexExtractMulti("&?([^=]+)=?([^&]*)", query_string.c_str(), 2); + page = elems.size() > 0 ? elems[0] : "index"; +} + +template <class X, class Y> +void +collectAll(std::map<ustring, Y> & objs, xmlNodePtr node, const ustring & name) +{ + if (name == node->name) { + fprintf(stderr, "Found a %s\n", name.c_str()); + try { + objs[xmlGetProp(node, BAD_CAST "name")] = Y(new X(node)); + fprintf(stderr, "Load succeeded\n"); + } + catch (const std::exception & e) { + // Assume the XML node is what we thought it was + fprintf(stderr, "Load failed (%s)\n", e.what()); + } + catch (...) { + // Assume the XML node is what we thought it was + fprintf(stderr, "Load failed\n"); + } + } + else { + for (xmlNodePtr child = node->children; child; child = child->next) { + collectAll<X, Y>(objs, child, name); + } + } +} + +xmlDocPtr +EnvironmentProcessor::process() +{ + xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0"); + xmlDocPtr pageXDoc = xmlReadFile(("present/" + page + ".xml").c_str(), NULL, XML_PARSE_XINCLUDE); + while (xmlXIncludeProcess(pageXDoc) > 0); + xmlNodePtr root = xmlDocGetRootElement(pageXDoc); + // Collect datasources + RdbmsDataSources rdbmsDataSources; + collectAll<_RdbmsDataSource>(rdbmsDataSources, root, BAD_CAST "rdbmsdatasource"); + // Collect views + SqlViews sqlViews; + collectAll<_SqlView>(sqlViews, root, BAD_CAST "sqlview"); + // + xmlNodePtr root_node = xmlNewNode(NULL, xmlGetProp(root, BAD_CAST "root")); + try { + BOOST_FOREACH(SqlViews::value_type s, sqlViews) { + s.second->execute(rdbmsDataSources, root_node); + } + } + catch (...) { + } + xmlDocSetRootElement(doc, root_node); + char * buf; + if (asprintf(&buf, "type=\"text/xsl\" href=\"%s\"", + xmlGetProp(root, BAD_CAST "style")) > 0) { + xmlAddPrevSibling(root_node, + xmlNewDocPI(doc, BAD_CAST "xml-stylesheet", BAD_CAST buf)); + } + free(buf); + xmlFreeDoc(pageXDoc); + return doc; +} + |