summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--project2/Jamfile.jam29
-rw-r--r--project2/cgi/cgiAppEngine.cpp273
-rw-r--r--project2/cgi/cgiAppEngine.h78
-rw-r--r--project2/cgi/cgiEnvironment.cpp12
-rw-r--r--project2/cgi/cgiEnvironment.h6
-rw-r--r--project2/cgi/cgiHttpHeader.cpp29
-rw-r--r--project2/cgi/cgiHttpHeader.h20
-rw-r--r--project2/cgi/cgiStageCustomError.cpp44
-rw-r--r--project2/cgi/cgiStageCustomNotFound.cpp43
-rw-r--r--project2/cgi/cgiStageDefaultError.cpp52
-rw-r--r--project2/cgi/cgiStageDefaultNotFound.cpp44
-rw-r--r--project2/cgi/cgiStageInitial.cpp19
-rw-r--r--project2/cgi/cgiStagePresent.cpp44
-rw-r--r--project2/cgi/cgiStageRequest.cpp60
-rw-r--r--project2/cgi/p2webFCgi.cpp1
-rw-r--r--project2/commonObjects.cpp5
-rw-r--r--project2/console/consoleAppEngine.cpp2
-rw-r--r--project2/environment.cpp24
-rw-r--r--project2/environment.h8
-rw-r--r--project2/if.cpp5
-rw-r--r--project2/iterate.cpp3
-rw-r--r--project2/rowView.cpp3
-rw-r--r--project2/sqlMergeTask.cpp3
-rw-r--r--project2/xmlPresenter.cpp31
-rw-r--r--project2/xmlPresenter.h6
25 files changed, 563 insertions, 281 deletions
diff --git a/project2/Jamfile.jam b/project2/Jamfile.jam
index 1d9ba9b..0b8425e 100644
--- a/project2/Jamfile.jam
+++ b/project2/Jamfile.jam
@@ -16,6 +16,7 @@ alias libxslt : : : :
lib fcgi : : <name>fcgi ;
lib fcgi++ : : <name>fcgi++ ;
lib boost_regex : : <name>boost_regex ;
+lib boost_system : : <name>boost_system ;
lib boost_filesystem : : <name>boost_filesystem ;
lib boost_date_time : : <name>boost_date_time ;
lib boost_program_options : : <name>boost_program_options ;
@@ -39,6 +40,11 @@ feature uuid : boost ossp : propagated ;
feature odbc : yes no ;
feature pq : yes no ;
+project
+ : requirements
+ <variant>debug:<linkflags>-Wl,-z,defs <cflags>"-W -Wall -Werror -Wwrite-strings"
+ ;
+
lib p2uuid :
uuid.cpp
:
@@ -58,6 +64,7 @@ lib p2common :
:
<include>../libmisc
<library>libxmlpp
+ <library>boost_system
<library>boost_filesystem
<library>boost_date_time
<library>boost_program_options
@@ -65,10 +72,11 @@ lib p2common :
lib p2xml :
xmlRows.cpp xslRows.cpp
- p2url
:
<include>../libmisc
<library>libxmlpp
+ <library>p2common
+ <library>p2url
<library>libxslt
;
@@ -77,6 +85,8 @@ lib p2processes :
:
<include>../libmisc
<library>libxmlpp
+ <library>p2common
+ <library>p2files
;
lib p2files :
@@ -87,6 +97,8 @@ lib p2files :
<include>../libmisc
<library>libxmlpp
<library>boost_filesystem
+ <library>boost_system
+ <library>p2common
;
lib p2regex :
@@ -95,6 +107,7 @@ lib p2regex :
<include>../libmisc
<library>boost_regex
<library>libxmlpp
+ <library>p2common
;
lib p2xmlSession :
@@ -102,8 +115,8 @@ lib p2xmlSession :
:
<include>../libmisc
<library>libxmlpp
- : :
<library>p2uuid
+ <library>p2common
;
obj rdbmsDataSource :
@@ -123,6 +136,7 @@ lib p2sql :
<odbc>yes:<library>../libodbcpp//odbcpp
<pq>yes:<library>../libpqpp//pqpp
<library>libxmlpp
+ <library>p2common
<include>../libmisc
: :
<odbc>yes:<library>../libodbcpp//odbcpp
@@ -134,9 +148,13 @@ lib p2url :
curlHelper.cpp
../libmisc/curlsup.cpp
:
+ <library>p2common
+ <library>p2files
<include>../libmisc
<library>libxmlpp
<library>curl
+ : :
+ <library>curl
;
lib p2mail :
@@ -146,6 +164,7 @@ lib p2mail :
<library>libxmlpp
<library>libxslt
<library>esmtp
+ <library>p2common
;
lib p2web :
@@ -155,9 +174,13 @@ lib p2web :
<library>cgicc
<library>glibmm
<library>libxmlpp
+ <library>p2common
+ <library>p2uuid
+ <library>boost_program_options
+ <library>boost_regex
+ <library>p2xmlSession
: :
<library>p2parts
- <library>p2xmlSession
;
exe p2cgi :
diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp
index 7df0279..547506d 100644
--- a/project2/cgi/cgiAppEngine.cpp
+++ b/project2/cgi/cgiAppEngine.cpp
@@ -2,14 +2,12 @@
#include <cgicc/Cgicc.h>
#include <cgicc/HTTPHeader.h>
#include "cgiEnvironment.h"
-#include "../xmlObjectLoader.h"
#include "../iterate.h"
#include "../logger.h"
#include <boost/bind.hpp>
#include <boost/regex.hpp>
#include <boost/foreach.hpp>
#include "../sessionXml.h"
-#include <cxxabi.h>
#include <boost/date_time/microsec_time_clock.hpp>
const std::string SESSIONID = "sessionID";
@@ -20,32 +18,6 @@ SessionContainer * sessionsContainer = new SessionContainerXml();
SimpleMessageException(UnknownDomain);
-class Project2HttpHeader : public cgicc::HTTPHeader {
- public:
- typedef std::map<std::string, const Glib::ustring> Headers;
- Project2HttpHeader(const std::string & s, const std::string & t) :
- cgicc::HTTPHeader("")
- {
- addHeader("Status", s);
- addHeader("Content-Type", t);
- }
- void addHeader(const std::string & name, const Glib::ustring & value) {
- headers.erase(name);
- headers.insert(Headers::value_type(name, value));
- }
- void render(std::ostream & out) const {
- BOOST_FOREACH(const Headers::value_type & h, headers) {
- out << h.first << ": " << h.second << std::endl;
- }
- BOOST_FOREACH(const cgicc::HTTPCookie & cookie, getCookies()) {
- out << cookie << std::endl;
- }
- out << std::endl;
- }
- private:
- Headers headers;
-};
-
static
int
xmlWrite(void * _out, const char * buf, int len)
@@ -64,20 +36,7 @@ CgiApplicationEngine::CgiApplicationEngine(const CgiEnvironment * e) :
sessionID = c.getValue();
}
}
- try {
- if (_env->getRequestMethod() == "POST") {
- currentStage = new RequestStage(e->elems[0]);
- }
- else {
- currentStage = new PresentStage(e->elems.size() > 0 ? e->elems[0] : "index");
- }
- }
- catch (const XmlScriptParser::NotFound & nf) {
- currentStage = new NotFoundStage(_env, nf);
- }
- catch (const std::exception & ex) {
- currentStage = new ErrorStage(_env, ex);
- }
+ currentStage = new InitialStage(e);
}
CgiApplicationEngine::~CgiApplicationEngine()
@@ -114,25 +73,41 @@ void
CgiApplicationEngine::process() const
{
startTime = boost::date_time::microsec_clock<boost::posix_time::ptime>::universal_time();
- try {
- for (StagePtr nextStage; (nextStage = currentStage->run()); ) {
- currentStage = nextStage;
+ bool triedNotFound = false;
+ bool triedOnError = false;
+ StagePtr nextStage;
+ do {
+ try {
+ nextStage = currentStage->run();
}
- }
- catch (const XmlScriptParser::NotFound & nf) {
- currentStage = new NotFoundStage(_env, nf);
- }
- catch (const std::exception & ex) {
- currentStage = new ErrorStage(_env, ex);
- }
+ catch (const XmlScriptParser::NotFound & nf) {
+ if (_env->notFoundPresent.empty() || triedNotFound) {
+ nextStage = new DefaultNotFoundStage(_env, nf);
+ }
+ else {
+ triedNotFound = true;
+ nextStage = new CustomNotFoundStage(_env, nf);
+ }
+ }
+ catch (const std::exception & ex) {
+ if (_env->onErrorPresent.empty() || triedOnError) {
+ nextStage = new DefaultErrorStage(_env, ex);
+ }
+ else {
+ triedNotFound = true;
+ nextStage = new CustomErrorStage(_env, ex);
+ }
+ }
+ } while (nextStage && (currentStage = nextStage));
endTime = boost::date_time::microsec_clock<boost::posix_time::ptime>::universal_time();
- const Presenter * p = boost::dynamic_pointer_cast<const Presenter>(currentStage).get();
+ PresenterPtr p = boost::dynamic_pointer_cast<Presenter>(currentStage);
if (p) {
- addAppData(p);
+ addAppData(p.get());
}
}
-CgiApplicationEngine::Stage::Stage()
+CgiApplicationEngine::Stage::Stage(const CgiEnvironment * env) :
+ e(env)
{
}
@@ -140,59 +115,36 @@ CgiApplicationEngine::Stage::~Stage()
{
}
-CgiApplicationEngine::PresentStage::PresentStage(const std::string & id) :
- XmlProcessPresenter("present", id, false)
-{
-}
-
-CgiApplicationEngine::PresentStage::~PresentStage()
-{
-}
-
-CgiApplicationEngine::StagePtr
-CgiApplicationEngine::PresentStage::run()
-{
- BOOST_FOREACH(ParamCheckers::value_type pc, parameterChecks.get<bySOOrder>()) {
- if (!pc->performCheck()) {
- return new PresentStage(pc->present);
- }
- }
- execute();
- return NULL;
-}
-
CgiApplicationEngine::HttpHeaderPtr
-CgiApplicationEngine::PresentStage::getHeader() const
+CgiApplicationEngine::Stage::getHeader() const
{
- Project2HttpHeader * header = new Project2HttpHeader("200 OK", contentType);
- header->addHeader("Cache-control", "no-cache");
- return HttpHeaderPtr(header);
+ return CgiApplicationEngine::HttpHeaderPtr();
}
CgiApplicationEngine::XmlDocPtr
-CgiApplicationEngine::PresentStage::getDataDocument() const
+CgiApplicationEngine::Stage::getDataDocument() const
{
- return XmlProcessPresenter::getDataDocument();
+ return XmlDocPtr();
}
void
CgiApplicationEngine::addEnvData(const Presenter * p) const
{
// These were for debug... but why not pass them on?
- p->addField("servername", "project2", env()->getServerName());
- p->addField("scriptname", "project2", env()->getScriptName());
+ p->addField("servername", env()->getXmlPrefix(), env()->getServerName());
+ p->addField("scriptname", env()->getXmlPrefix(), env()->getScriptName());
// URL elements
- p->pushSub("uriElems", "project2");
+ p->pushSub("uriElems", env()->getXmlPrefix());
BOOST_FOREACH(std::string s, _env->elems) {
- p->addField("uriElem", "project2", s);
+ p->addField("uriElem", env()->getXmlPrefix(), s);
}
p->popSub();
// Parameters
- p->pushSub("params", "project2");
+ p->pushSub("params", env()->getXmlPrefix());
BOOST_FOREACH(cgicc::FormEntry fe, _env->cgi->getElements()) {
- p->pushSub("param", "project2");
+ p->pushSub("param", env()->getXmlPrefix());
p->addAttr("name", fe.getName());
p->addAttr("value", fe.getValue());
p->popSub();
@@ -205,11 +157,11 @@ CgiApplicationEngine::addAppData(const Presenter * p) const
{
// Sessions variables
if (!sessionID.is_nil()) {
- p->pushSub("session", "project2");
+ p->pushSub("session", env()->getXmlPrefix());
p->addField("id", sessionID.str());
Session::Values session(sessionsContainer->GetSession(sessionID)->GetValuesCopy());
BOOST_FOREACH(Session::Values::value_type sv, session) {
- p->pushSub("var", "project2");
+ p->pushSub("var", env()->getXmlPrefix());
p->addAttr("value", sv.second);
p->addAttr("name", sv.first);
p->popSub();
@@ -218,7 +170,7 @@ CgiApplicationEngine::addAppData(const Presenter * p) const
}
// Timing info
- p->pushSub("timing", "project2");
+ p->pushSub("timing", env()->getXmlPrefix());
p->addAttr("start", startTime);
if (!endTime.is_not_a_date_time()) {
p->addAttr("end", endTime);
@@ -227,60 +179,6 @@ CgiApplicationEngine::addAppData(const Presenter * p) const
p->popSub();
}
-CgiApplicationEngine::RequestStage::RequestStage(const std::string & id)
-{
- XmlScriptParser request("request", id, false);
- xmlpp::Element * requestRoot = request.get_document()->get_root_node();
- present = requestRoot->get_attribute_value("present");
- rollbackBeforeHandle = requestRoot->get_attribute_value("rollbackBeforeHandle") == "true";
- localErrorHandling = requestRoot->get_attribute_value("errorHandling") == "local";
-
- LoaderBase loader("http://project2.randomdan.homeip.net", true);
- loader.supportedStorers.insert(Storer::into(&parameterChecks));
- loader.supportedStorers.insert(Storer::into(&rowSets));
- loader.supportedStorers.insert(Storer::into(&tasks));
- loader.collectAll(this, requestRoot, true);
-}
-CgiApplicationEngine::RequestStage::~RequestStage()
-{
-}
-CgiApplicationEngine::StagePtr
-CgiApplicationEngine::RequestStage::run()
-{
- BOOST_FOREACH(const ParamCheckers::value_type & pc, parameterChecks.get<bySOOrder>()) {
- if (!pc->performCheck()) {
- return new PresentStage(pc->present);
- }
- }
- RequestHost::run();
- return present.empty() ? NULL : new PresentStage(present);
-}
-
-CgiApplicationEngine::HttpHeaderPtr
-CgiApplicationEngine::RequestStage::getHeader() const
-{
- return HttpHeaderPtr(new Project2HttpHeader("200 OK", "text/xml"));
-}
-
-CgiApplicationEngine::XmlDocPtr
-CgiApplicationEngine::RequestStage::getDataDocument() const
-{
- return XmlPresenter::getDataDocument();
-}
-
-const Glib::ustring CgiApplicationEngine::RequestStage::resp("request");
-const Glib::ustring CgiApplicationEngine::RequestStage::style;
-const Glib::ustring &
-CgiApplicationEngine::RequestStage::getResponseRootNodeName() const
-{
- return resp;
-}
-const Glib::ustring &
-CgiApplicationEngine::RequestStage::getResponseStyle() const
-{
- return style;
-}
-
SessionPtr
CgiApplicationEngine::session() const
{
@@ -310,89 +208,4 @@ CgiApplicationEngine::loadEngineSection(const xmlpp::Element * e) const
domplat.push_back(DomainPlatforms::value_type(e->get_attribute_value("name"), e->get_attribute_value("platform")));
}
-CgiApplicationEngine::FailStage::FailStage(const CgiEnvironment * e) :
- env(e)
-{
-}
-
-CgiApplicationEngine::FailStage::~FailStage()
-{
-}
-
-const Glib::ustring &
-CgiApplicationEngine::FailStage::getResponseStyle() const
-{
- return env->errorTransformStyle;
-}
-
-CgiApplicationEngine::StagePtr
-CgiApplicationEngine::FailStage::run()
-{
- return NULL;
-}
-
-CgiApplicationEngine::NotFoundStage::NotFoundStage(const CgiEnvironment * e, const XmlScriptParser::NotFound & nf) :
- CgiApplicationEngine::FailStage(e)
-{
- initDoc();
- responseDoc->get_root_node()->add_child("resource")->set_child_text(nf.what());
-}
-
-CgiApplicationEngine::NotFoundStage::~NotFoundStage()
-{
-}
-
-CgiApplicationEngine::HttpHeaderPtr
-CgiApplicationEngine::NotFoundStage::getHeader() const
-{
- return HttpHeaderPtr(new Project2HttpHeader("404 Not found", env->errorContentType));
-}
-
-const Glib::ustring CgiApplicationEngine::NotFoundStage::resp("notfound");
-const Glib::ustring &
-CgiApplicationEngine::NotFoundStage::getResponseRootNodeName() const
-{
- return resp;
-}
-
-CgiApplicationEngine::XmlDocPtr
-CgiApplicationEngine::NotFoundStage::getDataDocument() const
-{
- return XmlPresenter::getDataDocument();
-}
-
-CgiApplicationEngine::ErrorStage::ErrorStage(const CgiEnvironment * e, const std::exception & ex) :
- CgiApplicationEngine::FailStage(e)
-{
- initDoc();
- char * buf = __cxxabiv1::__cxa_demangle(typeid(ex).name(), NULL, NULL, NULL);
- Logger()->messagef(LOG_ERR, "%s: Request errored: %s: %s", __FUNCTION__, buf, ex.what());
- responseDoc->get_root_node()->add_child("type")->set_child_text(buf);
- responseDoc->get_root_node()->add_child("what")->set_child_text(ex.what());
- free(buf);
-}
-
-CgiApplicationEngine::ErrorStage::~ErrorStage()
-{
-}
-
-CgiApplicationEngine::HttpHeaderPtr
-CgiApplicationEngine::ErrorStage::getHeader() const
-{
- return HttpHeaderPtr(new Project2HttpHeader("500 Internal Server Error", env->errorContentType));
-}
-
-const Glib::ustring CgiApplicationEngine::ErrorStage::resp("error");
-const Glib::ustring &
-CgiApplicationEngine::ErrorStage::getResponseRootNodeName() const
-{
- return resp;
-}
-
-CgiApplicationEngine::XmlDocPtr
-CgiApplicationEngine::ErrorStage::getDataDocument() const
-{
- return XmlPresenter::getDataDocument();
-}
-
diff --git a/project2/cgi/cgiAppEngine.h b/project2/cgi/cgiAppEngine.h
index cfab7c4..de9b95a 100644
--- a/project2/cgi/cgiAppEngine.h
+++ b/project2/cgi/cgiAppEngine.h
@@ -47,19 +47,29 @@ class CgiApplicationEngine : public ApplicationEngine {
class Stage;
typedef boost::intrusive_ptr<Stage> StagePtr;
+ /// Base class for a stage iteration that should eventually produce a response for the client
class Stage : public virtual CommonObjects {
public:
- Stage();
+ Stage(const CgiEnvironment * e);
virtual ~Stage() = 0;
virtual StagePtr run() = 0;
- virtual XmlDocPtr getDataDocument() const = 0;
- virtual HttpHeaderPtr getHeader() const = 0;
+ virtual XmlDocPtr getDataDocument() const;
+ virtual HttpHeaderPtr getHeader() const;
+ protected:
+ const CgiEnvironment * e;
+ };
+
+ /// Stage implementation used to bootstrap the iteration process based on the CGI environment
+ class InitialStage : public Stage {
+ public:
+ InitialStage(const CgiEnvironment * e);
+ virtual StagePtr run();
};
+ /// Stage to process POST requests
class RequestStage : public Stage, public XmlPresenter, RequestHost {
public:
- RequestStage(const std::string & id);
- virtual ~RequestStage();
+ RequestStage(const CgiEnvironment *, const std::string & id);
virtual StagePtr run();
virtual XmlDocPtr getDataDocument() const;
@@ -77,51 +87,73 @@ class CgiApplicationEngine : public ApplicationEngine {
static const Glib::ustring style;
};
- class PresentStage : public Stage, public XmlProcessPresenter {
+ /// Stage to process GET requests and follow up RequestStages
+ class PresentStage : public virtual Stage, public XmlProcessPresenter {
public:
- PresentStage(const std::string & id);
- virtual ~PresentStage();
+ PresentStage(const CgiEnvironment * e, const std::string & id);
+ PresentStage(const CgiEnvironment * e, const std::string & group, const std::string & id);
virtual StagePtr run();
virtual XmlDocPtr getDataDocument() const;
virtual HttpHeaderPtr getHeader() const;
};
- class FailStage : public Stage, public XmlPresenter {
+ /// The built-in fail-safe not found stage
+ class DefaultNotFoundStage : public virtual Stage, public XmlPresenter {
public:
- FailStage(const CgiEnvironment *);
- virtual ~FailStage();
+ DefaultNotFoundStage(const CgiEnvironment *, const XmlScriptParser::NotFound &);
- virtual const Glib::ustring & getResponseStyle() const;
+ virtual XmlDocPtr getDataDocument() const;
+ virtual HttpHeaderPtr getHeader() const;
virtual StagePtr run();
+ virtual const Glib::ustring & getResponseRootNodeName() const;
+ virtual const Glib::ustring & getResponseStyle() const;
+ private:
+ static const Glib::ustring resp;
+ const CgiEnvironment * e;
+ const XmlScriptParser::NotFound nf;
+ };
- protected:
- const CgiEnvironment * env;
+ /// Custom not found handling stage
+ class CustomNotFoundStage : public DefaultNotFoundStage, public PresentStage {
+ public:
+ CustomNotFoundStage(const CgiEnvironment *, const XmlScriptParser::NotFound &);
+ virtual StagePtr run();
+ virtual XmlDocPtr getDataDocument() const;
+ virtual HttpHeaderPtr getHeader() const;
+ virtual const Glib::ustring & getResponseRootNodeName() const;
+ virtual const Glib::ustring & getResponseStyle() const;
};
- class NotFoundStage : public FailStage {
+ /// The built-in fail-safe unhandled error stage
+ class DefaultErrorStage : public virtual Stage, public XmlPresenter {
public:
- NotFoundStage(const CgiEnvironment *, const XmlScriptParser::NotFound &);
- virtual ~NotFoundStage();
+ DefaultErrorStage(const CgiEnvironment *, const std::exception &);
+ ~DefaultErrorStage();
virtual XmlDocPtr getDataDocument() const;
virtual HttpHeaderPtr getHeader() const;
+ virtual StagePtr run();
virtual const Glib::ustring & getResponseRootNodeName() const;
+ virtual const Glib::ustring & getResponseStyle() const;
private:
static const Glib::ustring resp;
+ const CgiEnvironment * e;
+ char * buf;
+ std::string what;
};
- class ErrorStage : public FailStage {
+ /// Custom unhandled error handling stage
+ class CustomErrorStage : public DefaultErrorStage, public PresentStage {
public:
- ErrorStage(const CgiEnvironment *, const std::exception &);
- virtual ~ErrorStage();
-
+ CustomErrorStage(const CgiEnvironment *, const std::exception &);
+ virtual StagePtr run();
virtual XmlDocPtr getDataDocument() const;
virtual HttpHeaderPtr getHeader() const;
virtual const Glib::ustring & getResponseRootNodeName() const;
- private:
- static const Glib::ustring resp;
+ virtual const Glib::ustring & getResponseStyle() const;
};
+
mutable StagePtr currentStage;
mutable UUID sessionID;
};
diff --git a/project2/cgi/cgiEnvironment.cpp b/project2/cgi/cgiEnvironment.cpp
index 43f45f2..e8d5ba3 100644
--- a/project2/cgi/cgiEnvironment.cpp
+++ b/project2/cgi/cgiEnvironment.cpp
@@ -28,10 +28,22 @@ CgiEnvironment::addOptions(boost::program_options::positional_options_descriptio
{
boost::program_options::options_description cgi("Project2 CGI options");
cgi.add_options()
+ ("defaultpresent", boost::program_options::value(&defaultPresent)->default_value("index"),
+ "The present script to use when no other is specified")
+ ("presentroot", boost::program_options::value(&presentRoot)->default_value("present"),
+ "The folder in which to find presentation scripts")
+ ("requestroot", boost::program_options::value(&requestRoot)->default_value("request"),
+ "The folder in which to find request scripts")
+ ("errorpresentroot", boost::program_options::value(&errorPresentRoot)->default_value("error"),
+ "The folder in which to find presentation scripts for error handling")
("errorcontenttype", boost::program_options::value(&errorContentType)->default_value("text/xml"),
"The Content-Type to use in HTTP headers in event of an error")
("errortransformstyle", boost::program_options::value(&errorTransformStyle),
"The xml-stylesheet to specify in the data document in event of an error")
+ ("notfoundpresent", boost::program_options::value(&notFoundPresent),
+ "The present script to use when the requested script does not exist")
+ ("onerrorpresent", boost::program_options::value(&onErrorPresent),
+ "The present script to use when the requested script (or child) fails")
#ifndef NDEBUG
("dumpdatadoc", boost::program_options::value(&dumpdatadoc),
"Write a copy of the data document before sending it to the web server")
diff --git a/project2/cgi/cgiEnvironment.h b/project2/cgi/cgiEnvironment.h
index c9b33fa..ce765bf 100644
--- a/project2/cgi/cgiEnvironment.h
+++ b/project2/cgi/cgiEnvironment.h
@@ -32,6 +32,12 @@ class CgiEnvironment : public Environment, public cgicc::CgiEnvironment {
#endif
Glib::ustring errorContentType;
Glib::ustring errorTransformStyle;
+ std::string defaultPresent;
+ std::string presentRoot;
+ std::string requestRoot;
+ std::string errorPresentRoot;
+ std::string notFoundPresent;
+ std::string onErrorPresent;
};
#endif
diff --git a/project2/cgi/cgiHttpHeader.cpp b/project2/cgi/cgiHttpHeader.cpp
new file mode 100644
index 0000000..37a48c9
--- /dev/null
+++ b/project2/cgi/cgiHttpHeader.cpp
@@ -0,0 +1,29 @@
+#include "cgiHttpHeader.h"
+#include <boost/foreach.hpp>
+
+Project2HttpHeader::Project2HttpHeader(const std::string & s, const std::string & t) :
+ cgicc::HTTPHeader("")
+{
+ addHeader("Status", s);
+ addHeader("Content-Type", t);
+}
+
+void
+Project2HttpHeader::addHeader(const std::string & name, const Glib::ustring & value)
+{
+ headers.erase(name);
+ headers.insert(Headers::value_type(name, value));
+}
+
+void
+Project2HttpHeader::render(std::ostream & out) const
+{
+ BOOST_FOREACH(const Headers::value_type & h, headers) {
+ out << h.first << ": " << h.second << std::endl;
+ }
+ BOOST_FOREACH(const cgicc::HTTPCookie & cookie, getCookies()) {
+ out << cookie << std::endl;
+ }
+ out << std::endl;
+}
+
diff --git a/project2/cgi/cgiHttpHeader.h b/project2/cgi/cgiHttpHeader.h
new file mode 100644
index 0000000..f84c707
--- /dev/null
+++ b/project2/cgi/cgiHttpHeader.h
@@ -0,0 +1,20 @@
+#ifndef HTTP_HEADER_H
+#define HTTP_HEADER_H
+
+#include <cgicc/HTTPHeader.h>
+#include <string>
+#include <map>
+#include <glibmm/ustring.h>
+
+class Project2HttpHeader : public cgicc::HTTPHeader {
+ public:
+ typedef std::map<std::string, const Glib::ustring> Headers;
+ Project2HttpHeader(const std::string & s, const std::string & t);
+ void addHeader(const std::string & name, const Glib::ustring & value);
+ void render(std::ostream & out) const;
+ private:
+ Headers headers;
+};
+
+#endif
+
diff --git a/project2/cgi/cgiStageCustomError.cpp b/project2/cgi/cgiStageCustomError.cpp
new file mode 100644
index 0000000..a3fbc1f
--- /dev/null
+++ b/project2/cgi/cgiStageCustomError.cpp
@@ -0,0 +1,44 @@
+#include "cgiAppEngine.h"
+#include "cgiEnvironment.h"
+#include "cgiHttpHeader.h"
+#include "../logger.h"
+
+CgiApplicationEngine::CustomErrorStage::CustomErrorStage(const CgiEnvironment * env, const std::exception & ex) :
+ CgiApplicationEngine::Stage(env),
+ CgiApplicationEngine::DefaultErrorStage(env, ex),
+ CgiApplicationEngine::PresentStage(env, env->errorPresentRoot, env->onErrorPresent)
+{
+}
+
+CgiApplicationEngine::HttpHeaderPtr
+CgiApplicationEngine::CustomErrorStage::getHeader() const
+{
+ return CgiApplicationEngine::DefaultErrorStage::getHeader();
+}
+
+CgiApplicationEngine::StagePtr
+CgiApplicationEngine::CustomErrorStage::run()
+{
+ CgiApplicationEngine::DefaultErrorStage::run();
+ return CgiApplicationEngine::PresentStage::run();
+}
+
+const Glib::ustring &
+CgiApplicationEngine::CustomErrorStage::getResponseRootNodeName() const
+{
+ return CgiApplicationEngine::PresentStage::getResponseRootNodeName();
+}
+
+CgiApplicationEngine::XmlDocPtr
+CgiApplicationEngine::CustomErrorStage::getDataDocument() const
+{
+ return CgiApplicationEngine::PresentStage::getDataDocument();
+}
+
+const Glib::ustring &
+CgiApplicationEngine::CustomErrorStage::getResponseStyle() const
+{
+ return CgiApplicationEngine::PresentStage::getResponseStyle();
+}
+
+
diff --git a/project2/cgi/cgiStageCustomNotFound.cpp b/project2/cgi/cgiStageCustomNotFound.cpp
new file mode 100644
index 0000000..a2d33dc
--- /dev/null
+++ b/project2/cgi/cgiStageCustomNotFound.cpp
@@ -0,0 +1,43 @@
+#include "cgiAppEngine.h"
+#include "cgiEnvironment.h"
+#include "cgiHttpHeader.h"
+#include "../logger.h"
+
+CgiApplicationEngine::CustomNotFoundStage::CustomNotFoundStage(const CgiEnvironment * env, const XmlScriptParser::NotFound & notfound) :
+ CgiApplicationEngine::Stage(env),
+ CgiApplicationEngine::DefaultNotFoundStage(env, notfound),
+ CgiApplicationEngine::PresentStage(env, env->errorPresentRoot, env->notFoundPresent)
+{
+}
+
+CgiApplicationEngine::HttpHeaderPtr
+CgiApplicationEngine::CustomNotFoundStage::getHeader() const
+{
+ return CgiApplicationEngine::DefaultNotFoundStage::getHeader();
+}
+
+CgiApplicationEngine::StagePtr
+CgiApplicationEngine::CustomNotFoundStage::run()
+{
+ CgiApplicationEngine::DefaultNotFoundStage::run();
+ return CgiApplicationEngine::PresentStage::run();
+}
+
+const Glib::ustring &
+CgiApplicationEngine::CustomNotFoundStage::getResponseRootNodeName() const
+{
+ return CgiApplicationEngine::PresentStage::getResponseRootNodeName();
+}
+
+CgiApplicationEngine::XmlDocPtr
+CgiApplicationEngine::CustomNotFoundStage::getDataDocument() const
+{
+ return CgiApplicationEngine::PresentStage::getDataDocument();
+}
+
+const Glib::ustring &
+CgiApplicationEngine::CustomNotFoundStage::getResponseStyle() const
+{
+ return CgiApplicationEngine::PresentStage::getResponseStyle();
+}
+
diff --git a/project2/cgi/cgiStageDefaultError.cpp b/project2/cgi/cgiStageDefaultError.cpp
new file mode 100644
index 0000000..c881da1
--- /dev/null
+++ b/project2/cgi/cgiStageDefaultError.cpp
@@ -0,0 +1,52 @@
+#include "cgiAppEngine.h"
+#include "cgiHttpHeader.h"
+#include "../logger.h"
+#include "cgiEnvironment.h"
+#include <cxxabi.h>
+
+const Glib::ustring CgiApplicationEngine::DefaultErrorStage::resp("error");
+
+CgiApplicationEngine::DefaultErrorStage::DefaultErrorStage(const CgiEnvironment * env, const std::exception & ex) :
+ CgiApplicationEngine::Stage(env),
+ buf(__cxxabiv1::__cxa_demangle(typeid(ex).name(), NULL, NULL, NULL)),
+ what(ex.what())
+{
+}
+
+CgiApplicationEngine::DefaultErrorStage::~DefaultErrorStage()
+{
+ free(buf);
+}
+
+CgiApplicationEngine::HttpHeaderPtr
+CgiApplicationEngine::DefaultErrorStage::getHeader() const
+{
+ return HttpHeaderPtr(new Project2HttpHeader("500 Internal Server Error", e->errorContentType));
+}
+
+CgiApplicationEngine::StagePtr
+CgiApplicationEngine::DefaultErrorStage::run()
+{
+ addField("error-type", e->getXmlPrefix(), buf);
+ addField("error-what", e->getXmlPrefix(), what.c_str());
+ return NULL;
+}
+
+const Glib::ustring &
+CgiApplicationEngine::DefaultErrorStage::getResponseRootNodeName() const
+{
+ return resp;
+}
+
+CgiApplicationEngine::XmlDocPtr
+CgiApplicationEngine::DefaultErrorStage::getDataDocument() const
+{
+ return XmlPresenter::getDataDocument();
+}
+
+const Glib::ustring &
+CgiApplicationEngine::DefaultErrorStage::getResponseStyle() const
+{
+ return e->errorTransformStyle;
+}
+
diff --git a/project2/cgi/cgiStageDefaultNotFound.cpp b/project2/cgi/cgiStageDefaultNotFound.cpp
new file mode 100644
index 0000000..f32ad1f
--- /dev/null
+++ b/project2/cgi/cgiStageDefaultNotFound.cpp
@@ -0,0 +1,44 @@
+#include "cgiAppEngine.h"
+#include "cgiEnvironment.h"
+#include "cgiHttpHeader.h"
+#include "../logger.h"
+
+CgiApplicationEngine::DefaultNotFoundStage::DefaultNotFoundStage(const CgiEnvironment * env, const XmlScriptParser::NotFound & notfound) :
+ CgiApplicationEngine::Stage(env),
+ nf(notfound)
+{
+ Logger()->messagef(LOG_ERR, "%s: Resource not found: %s", __FUNCTION__, nf.what());
+}
+
+CgiApplicationEngine::HttpHeaderPtr
+CgiApplicationEngine::DefaultNotFoundStage::getHeader() const
+{
+ return HttpHeaderPtr(new Project2HttpHeader("404 Not found", e->errorContentType));
+}
+
+CgiApplicationEngine::StagePtr
+CgiApplicationEngine::DefaultNotFoundStage::run()
+{
+ addField("missing-resource", e->getXmlPrefix(), nf.what());
+ return NULL;
+}
+
+const Glib::ustring CgiApplicationEngine::DefaultNotFoundStage::resp("notfound");
+const Glib::ustring &
+CgiApplicationEngine::DefaultNotFoundStage::getResponseRootNodeName() const
+{
+ return resp;
+}
+
+CgiApplicationEngine::XmlDocPtr
+CgiApplicationEngine::DefaultNotFoundStage::getDataDocument() const
+{
+ return XmlPresenter::getDataDocument();
+}
+
+const Glib::ustring &
+CgiApplicationEngine::DefaultNotFoundStage::getResponseStyle() const
+{
+ return e->errorTransformStyle;
+}
+
diff --git a/project2/cgi/cgiStageInitial.cpp b/project2/cgi/cgiStageInitial.cpp
new file mode 100644
index 0000000..a9315bc
--- /dev/null
+++ b/project2/cgi/cgiStageInitial.cpp
@@ -0,0 +1,19 @@
+#include "cgiAppEngine.h"
+#include "cgiEnvironment.h"
+
+CgiApplicationEngine::InitialStage::InitialStage(const CgiEnvironment * env) :
+ CgiApplicationEngine::Stage(env)
+{
+}
+
+CgiApplicationEngine::StagePtr
+CgiApplicationEngine::InitialStage::run()
+{
+ if (e->getRequestMethod() == "POST") {
+ return new RequestStage(e, e->elems[0]);
+ }
+ else {
+ return new PresentStage(e, e->elems.empty() ? e->defaultPresent : e->elems[0]);
+ }
+}
+
diff --git a/project2/cgi/cgiStagePresent.cpp b/project2/cgi/cgiStagePresent.cpp
new file mode 100644
index 0000000..9dcf124
--- /dev/null
+++ b/project2/cgi/cgiStagePresent.cpp
@@ -0,0 +1,44 @@
+#include "cgiAppEngine.h"
+#include "cgiEnvironment.h"
+#include "cgiHttpHeader.h"
+#include <boost/foreach.hpp>
+
+CgiApplicationEngine::PresentStage::PresentStage(const CgiEnvironment * e, const std::string & id) :
+ CgiApplicationEngine::Stage(e),
+ XmlProcessPresenter(e->presentRoot, id, false)
+{
+}
+
+CgiApplicationEngine::PresentStage::PresentStage(const CgiEnvironment * e, const std::string & group, const std::string & id) :
+ CgiApplicationEngine::Stage(e),
+ XmlProcessPresenter(group, id, false)
+{
+}
+
+CgiApplicationEngine::StagePtr
+CgiApplicationEngine::PresentStage::run()
+{
+ BOOST_FOREACH(ParamCheckers::value_type pc, parameterChecks.get<bySOOrder>()) {
+ if (!pc->performCheck()) {
+ return new PresentStage(e, pc->present);
+ }
+ }
+ execute();
+ return NULL;
+}
+
+CgiApplicationEngine::HttpHeaderPtr
+CgiApplicationEngine::PresentStage::getHeader() const
+{
+ Project2HttpHeader * header = new Project2HttpHeader("200 OK", contentType);
+ header->addHeader("Cache-control", "no-cache");
+ return HttpHeaderPtr(header);
+}
+
+CgiApplicationEngine::XmlDocPtr
+CgiApplicationEngine::PresentStage::getDataDocument() const
+{
+ return XmlProcessPresenter::getDataDocument();
+}
+
+
diff --git a/project2/cgi/cgiStageRequest.cpp b/project2/cgi/cgiStageRequest.cpp
new file mode 100644
index 0000000..6602527
--- /dev/null
+++ b/project2/cgi/cgiStageRequest.cpp
@@ -0,0 +1,60 @@
+#include "cgiAppEngine.h"
+#include "cgiEnvironment.h"
+#include "cgiHttpHeader.h"
+#include "../xmlObjectLoader.h"
+#include <boost/foreach.hpp>
+
+CgiApplicationEngine::RequestStage::RequestStage(const CgiEnvironment * e, const std::string & id) :
+ CgiApplicationEngine::Stage(e)
+{
+ XmlScriptParser request(e->requestRoot, id, false);
+ xmlpp::Element * requestRoot = request.get_document()->get_root_node();
+ present = requestRoot->get_attribute_value("present");
+ rollbackBeforeHandle = requestRoot->get_attribute_value("rollbackBeforeHandle") == "true";
+ localErrorHandling = requestRoot->get_attribute_value("errorHandling") == "local";
+
+ LoaderBase loader(ApplicationEngine::getCurrent()->env()->getXmlNamespace(), true);
+ loader.supportedStorers.insert(Storer::into(&parameterChecks));
+ loader.supportedStorers.insert(Storer::into(&rowSets));
+ loader.supportedStorers.insert(Storer::into(&tasks));
+ loader.collectAll(this, requestRoot, true);
+}
+
+CgiApplicationEngine::StagePtr
+CgiApplicationEngine::RequestStage::run()
+{
+ BOOST_FOREACH(const ParamCheckers::value_type & pc, parameterChecks.get<bySOOrder>()) {
+ if (!pc->performCheck()) {
+ return new PresentStage(e, pc->present);
+ }
+ }
+ RequestHost::run();
+ return present.empty() ? NULL : new PresentStage(e, present);
+}
+
+CgiApplicationEngine::HttpHeaderPtr
+CgiApplicationEngine::RequestStage::getHeader() const
+{
+ return HttpHeaderPtr(new Project2HttpHeader("200 OK", "text/xml"));
+}
+
+CgiApplicationEngine::XmlDocPtr
+CgiApplicationEngine::RequestStage::getDataDocument() const
+{
+ return XmlPresenter::getDataDocument();
+}
+
+const Glib::ustring CgiApplicationEngine::RequestStage::resp("request");
+const Glib::ustring CgiApplicationEngine::RequestStage::style;
+const Glib::ustring &
+CgiApplicationEngine::RequestStage::getResponseRootNodeName() const
+{
+ return resp;
+}
+const Glib::ustring &
+CgiApplicationEngine::RequestStage::getResponseStyle() const
+{
+ return style;
+}
+
+
diff --git a/project2/cgi/p2webFCgi.cpp b/project2/cgi/p2webFCgi.cpp
index d501787..d1aa29e 100644
--- a/project2/cgi/p2webFCgi.cpp
+++ b/project2/cgi/p2webFCgi.cpp
@@ -1,7 +1,6 @@
#include "cgiCommon.h"
#include "FCgiIO.h"
#include "../xmlObjectLoader.h"
-#include "../logger.h"
time_t lastPeriodic = 0;
time_t periodicDelay = 600;
diff --git a/project2/commonObjects.cpp b/project2/commonObjects.cpp
index b6a3b7d..d661588 100644
--- a/project2/commonObjects.cpp
+++ b/project2/commonObjects.cpp
@@ -1,4 +1,5 @@
#include "commonObjects.h"
+#include "appEngine.h"
#include "xmlObjectLoader.h"
#include "xmlScriptParser.h"
@@ -21,9 +22,9 @@ CommonObjects::getSource(const std::string & name) const
CommonObjects::DataSources::index<bySOName>::type::const_iterator
CommonObjects::loadDataSource(const std::string & name) const
{
- XmlScriptParser xml("datasources", name, true);
+ XmlScriptParser xml(ApplicationEngine::getCurrent()->env()->getDatasourceRoot(), name, true);
- LoaderBase loader("http://project2.randomdan.homeip.net", true);
+ LoaderBase loader(ApplicationEngine::getCurrent()->env()->getXmlNamespace(), true);
loader.supportedStorers.insert(Storer::into(&datasources));
loader.collectAll(xml.get_document()->get_root_node(), false);
diff --git a/project2/console/consoleAppEngine.cpp b/project2/console/consoleAppEngine.cpp
index a45f704..7a08f69 100644
--- a/project2/console/consoleAppEngine.cpp
+++ b/project2/console/consoleAppEngine.cpp
@@ -64,7 +64,7 @@ ConsoleApplicationEngine::ConsoleApplicationEngine(const ConsoleEnvironment * en
rollbackBeforeHandle = requestRoot->get_attribute_value("rollbackBeforeHandle") == "true";
localErrorHandling = requestRoot->get_attribute_value("errorHandling") == "local";
- LoaderBase loader("http://project2.randomdan.homeip.net", true);
+ LoaderBase loader(ApplicationEngine::getCurrent()->env()->getXmlNamespace(), true);
loader.supportedStorers.insert(Storer::into(&parameterChecks));
loader.supportedStorers.insert(Storer::into(&tasks));
loader.supportedStorers.insert(Storer::into(&rowSets));
diff --git a/project2/environment.cpp b/project2/environment.cpp
index a3985ca..a3a3d5e 100644
--- a/project2/environment.cpp
+++ b/project2/environment.cpp
@@ -28,6 +28,12 @@ Environment::init()
"Log to syslog with level <arg> (default OFF)")
("consoleloglevel,c", po::value(&clLevel)->default_value(LOG_WARNING),
"Log to console with level <arg> (default WARNING)")
+ ("datasourceroot", boost::program_options::value(&datasourceRoot)->default_value("datasources"),
+ "The folder in which to find datasource definitions")
+ ("xmlnamespace", boost::program_options::value(&xmlNamespace)->default_value("http://project2.randomdan.homeip.net"),
+ "The XML namespace to use for Project2 components and responses")
+ ("xmlprefix", boost::program_options::value(&xmlPrefix)->default_value("project2"),
+ "The XML namespace prefix to use for the Project2 XML namespace")
;
allOptions.add(common).add(addOptions(posOptions));
optionsBuilt = true;
@@ -58,3 +64,21 @@ Environment::~Environment()
Logger()->clear();
}
+const std::string &
+Environment::getDatasourceRoot() const
+{
+ return datasourceRoot;
+}
+
+const Glib::ustring &
+Environment::getXmlNamespace() const
+{
+ return xmlNamespace;
+}
+
+const Glib::ustring &
+Environment::getXmlPrefix() const
+{
+ return xmlPrefix;
+}
+
diff --git a/project2/environment.h b/project2/environment.h
index 99f9253..5c66518 100644
--- a/project2/environment.h
+++ b/project2/environment.h
@@ -13,6 +13,10 @@ class Environment {
void init();
+ const std::string & getDatasourceRoot() const;
+ const Glib::ustring & getXmlNamespace() const;
+ const Glib::ustring & getXmlPrefix() const;
+
virtual Glib::ustring getParamUri(unsigned int idx) const = 0;
virtual Glib::ustring getParamQuery(const std::string & idx) const = 0;
@@ -30,6 +34,10 @@ class Environment {
static int clLevel;
static int slLevel;
+
+ std::string datasourceRoot;
+ Glib::ustring xmlNamespace;
+ Glib::ustring xmlPrefix;
};
#endif
diff --git a/project2/if.cpp b/project2/if.cpp
index b1b98a6..01368cc 100644
--- a/project2/if.cpp
+++ b/project2/if.cpp
@@ -1,4 +1,5 @@
#include "if.h"
+#include "appEngine.h"
#include "logger.h"
#include "xmlObjectLoader.h"
#include <boost/foreach.hpp>
@@ -10,7 +11,7 @@ SimpleMessageException(IfModeIsNonsense);
IfSet::IfSet(const xmlpp::Element * e) :
mode(e->get_attribute_value("mode") == "or" ? Or : And)
{
- LoaderBase loader("http://project2.randomdan.homeip.net", true);
+ LoaderBase loader(ApplicationEngine::getCurrent()->env()->getXmlNamespace(), true);
loader.supportedStorers.insert(Storer::into(&checks));
loader.collectAll(e, true, IgnoreUnsupported);
}
@@ -44,7 +45,7 @@ If::If(const xmlpp::Element * e) :
IfSet(e),
localErrorHandling(e->get_attribute_value("errorHandling") == "local")
{
- LoaderBase loader("http://project2.randomdan.homeip.net", true);
+ LoaderBase loader(ApplicationEngine::getCurrent()->env()->getXmlNamespace(), true);
loader.supportedStorers.insert(Storer::into(&subNOEs));
loader.supportedStorers.insert(Storer::into(&subViews));
loader.collectAll(e, true, IgnoreUnsupported);
diff --git a/project2/iterate.cpp b/project2/iterate.cpp
index ccf289e..b06d7e1 100644
--- a/project2/iterate.cpp
+++ b/project2/iterate.cpp
@@ -1,4 +1,5 @@
#include "iterate.h"
+#include "appEngine.h"
#include <boost/foreach.hpp>
#include "xmlObjectLoader.h"
@@ -10,7 +11,7 @@ Iterate::Iterate(const xmlpp::Element * p) :
RowProcessor(p),
localErrorHandling(p->get_attribute_value("errorHandling") == "local")
{
- LoaderBase loader("http://project2.randomdan.homeip.net", true);
+ LoaderBase loader(ApplicationEngine::getCurrent()->env()->getXmlNamespace(), true);
loader.supportedStorers.insert(Storer::into(&subNOEs));
loader.collectAll(p, true, IgnoreUnsupported);
}
diff --git a/project2/rowView.cpp b/project2/rowView.cpp
index e036dd7..541bf5e 100644
--- a/project2/rowView.cpp
+++ b/project2/rowView.cpp
@@ -1,4 +1,5 @@
#include "rowView.h"
+#include "appEngine.h"
#include "presenter.h"
#include "xmlObjectLoader.h"
#include <boost/foreach.hpp>
@@ -20,7 +21,7 @@ RowView::RowView(const xmlpp::Element * p) :
Variable::makeParent(elem->get_child_text()->get_content(), elem->get_attribute_value("source") == "attribute", 0)));
}
}
- LoaderBase loader("http://project2.randomdan.homeip.net", true);
+ LoaderBase loader(ApplicationEngine::getCurrent()->env()->getXmlNamespace(), true);
loader.supportedStorers.insert(Storer::into(&subViews));
loader.collectAll(p, true, IgnoreUnsupported);
}
diff --git a/project2/sqlMergeTask.cpp b/project2/sqlMergeTask.cpp
index 0160a7f..ab8546b 100644
--- a/project2/sqlMergeTask.cpp
+++ b/project2/sqlMergeTask.cpp
@@ -1,4 +1,5 @@
#include "sqlMergeTask.h"
+#include "appEngine.h"
#include "commonObjects.h"
#include "rdbmsDataSource.h"
#include "exceptions.h"
@@ -56,7 +57,7 @@ SqlMergeTask::SqlMergeTask(const xmlpp::Element * p) :
dtable(p->get_attribute_value("targettable")),
dtablet(stringf("tmp_%s_%d", dtable.c_str(), getpid()))
{
- LoaderBase loader("http://project2.randomdan.homeip.net", true);
+ LoaderBase loader(ApplicationEngine::getCurrent()->env()->getXmlNamespace(), true);
loader.supportedStorers.insert(Storer::into(&sources));
loader.collectAll(p, true);
diff --git a/project2/xmlPresenter.cpp b/project2/xmlPresenter.cpp
index 244c96c..494a88e 100644
--- a/project2/xmlPresenter.cpp
+++ b/project2/xmlPresenter.cpp
@@ -1,6 +1,7 @@
#include "xmlPresenter.h"
#include "xmlObjectLoader.h"
#include "variables.h"
+#include "appEngine.h"
XmlPresenter::XmlPresenter() :
responseDoc(XmlDocumentPtr(new xmlpp::Document("1.0")))
@@ -12,17 +13,21 @@ XmlPresenter::~XmlPresenter()
}
void
-XmlPresenter::initDoc()
+XmlPresenter::createDoc() const
{
- nodeStack.push_back(responseDoc->create_root_node(getResponseRootNodeName()));
- xmlNewNs(nodeStack.back()->cobj(), BAD_CAST "http://project2.randomdan.homeip.net", BAD_CAST "project2");
- // XSLT Style
- char * buf;
- if (!getResponseStyle().empty() && asprintf(&buf, "type=\"text/xsl\" href=\"%s\"",
- getResponseStyle().c_str()) > 0) {
- xmlAddPrevSibling(nodeStack.back()->cobj(),
- xmlNewDocPI(responseDoc->cobj(), BAD_CAST "xml-stylesheet", BAD_CAST buf));
- free(buf);
+ if (nodeStack.empty()) {
+ nodeStack.push_back(responseDoc->create_root_node(getResponseRootNodeName()));
+ xmlNewNs(nodeStack.back()->cobj(),
+ BAD_CAST ApplicationEngine::getCurrent()->env()->getXmlNamespace().c_str(),
+ BAD_CAST ApplicationEngine::getCurrent()->env()->getXmlPrefix().c_str());
+ // XSLT Style
+ char * buf;
+ if (!getResponseStyle().empty() && asprintf(&buf, "type=\"text/xsl\" href=\"%s\"",
+ getResponseStyle().c_str()) > 0) {
+ xmlAddPrevSibling(nodeStack.back()->cobj(),
+ xmlNewDocPI(responseDoc->cobj(), BAD_CAST "xml-stylesheet", BAD_CAST buf));
+ free(buf);
+ }
}
}
@@ -32,12 +37,11 @@ XmlProcessPresenter::XmlProcessPresenter(const std::string & group, const std::s
responseStyle(present.get_document()->get_root_node()->get_attribute_value("style")),
contentType(present.get_document()->get_root_node()->get_attribute_value("contenttype"))
{
- LoaderBase loader("http://project2.randomdan.homeip.net", true);
+ LoaderBase loader(ApplicationEngine::getCurrent()->env()->getXmlNamespace(), true);
loader.supportedStorers.insert(Storer::into(&rowSets));
loader.supportedStorers.insert(Storer::into(&views));
loader.supportedStorers.insert(Storer::into(&parameterChecks));
loader.collectAll(this, present.get_document()->get_root_node(), true);
- initDoc();
}
XmlProcessPresenter::~XmlProcessPresenter()
@@ -65,6 +69,7 @@ XmlPresenter::getDataDocument() const
void
XmlPresenter::pushSub(const Glib::ustring & name, const Glib::ustring & ns) const
{
+ createDoc();
nodeStack.push_back(nodeStack.back()->add_child(name, ns));
}
@@ -72,6 +77,7 @@ void
XmlPresenter::addAttr(const Glib::ustring & name, const Glib::ustring & ns, const VariableType & value) const
{
if (!boost::get<Null>(&value)) {
+ createDoc();
nodeStack.back()->set_attribute(name, value, ns);
}
}
@@ -80,6 +86,7 @@ void
XmlPresenter::setText(const VariableType & value) const
{
if (!boost::get<Null>(&value)) {
+ createDoc();
nodeStack.back()->set_child_text(value);
}
}
diff --git a/project2/xmlPresenter.h b/project2/xmlPresenter.h
index 8ced38f..cc1312a 100644
--- a/project2/xmlPresenter.h
+++ b/project2/xmlPresenter.h
@@ -23,11 +23,9 @@ class XmlPresenter : public Presenter {
virtual const Glib::ustring & getResponseRootNodeName() const = 0;
virtual const Glib::ustring & getResponseStyle() const = 0;
- protected:
- void initDoc();
- XmlDocumentPtr responseDoc;
-
private:
+ void createDoc() const;
+ XmlDocumentPtr responseDoc;
mutable std::vector<xmlpp::Element *> nodeStack;
};