summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2011-03-09 16:43:04 +0000
committerrandomdan <randomdan@localhost>2011-03-09 16:43:04 +0000
commit589f65d5748e0055a534d797c9b98206bafedc57 (patch)
tree62de5a89db702ba83f14a5a7a91d19535a06a388
parentA good start on docs, WTD (diff)
downloadproject2-589f65d5748e0055a534d797c9b98206bafedc57.tar.bz2
project2-589f65d5748e0055a534d797c9b98206bafedc57.tar.xz
project2-589f65d5748e0055a534d797c9b98206bafedc57.zip
Allow specifying all sorts of previously hardcoded things, most importantly paths
Rework the CGI stage structure to support custom presentations in the event of errors Changes to the Jamfile to ensure each component is complete in itself
-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;
};