diff options
200 files changed, 1450 insertions, 1660 deletions
diff --git a/project2/basics/aggregates/avg.cpp b/project2/basics/aggregates/avg.cpp index 62239b3..900bc5f 100644 --- a/project2/basics/aggregates/avg.cpp +++ b/project2/basics/aggregates/avg.cpp @@ -12,7 +12,7 @@ class Average : public ValueAggregate { { vals.clear(); } - void pushValue(const VariableType & v) const + void pushValue(const VariableType & v, ExecContext *) const { if (!v.isNull()) { vals.push_back(v); diff --git a/project2/basics/aggregates/count.cpp b/project2/basics/aggregates/count.cpp index 725be72..be22783 100644 --- a/project2/basics/aggregates/count.cpp +++ b/project2/basics/aggregates/count.cpp @@ -11,7 +11,7 @@ class Count : public ValueAggregate { { c = 0; } - void pushValue(const VariableType & v) const + void pushValue(const VariableType & v, ExecContext *) const { if (!v.isNull()) { c += 1; diff --git a/project2/basics/aggregates/countDistinct.cpp b/project2/basics/aggregates/countDistinct.cpp index b471911..205b932 100644 --- a/project2/basics/aggregates/countDistinct.cpp +++ b/project2/basics/aggregates/countDistinct.cpp @@ -10,7 +10,7 @@ class CountDistinct : public ValueAggregate { { result.clear(); } - void pushValue(const VariableType & v) const + void pushValue(const VariableType & v, ExecContext *) const { result.insert(v); } diff --git a/project2/basics/aggregates/distinct.cpp b/project2/basics/aggregates/distinct.cpp index ebac934..6039588 100644 --- a/project2/basics/aggregates/distinct.cpp +++ b/project2/basics/aggregates/distinct.cpp @@ -11,7 +11,7 @@ class Distinct : public SetAggregate { { result.clear(); } - void pushValue(const VariableType & v) const + void pushValue(const VariableType & v, ExecContext *) const { result.insert(v); } diff --git a/project2/basics/aggregates/join.cpp b/project2/basics/aggregates/join.cpp index 841eb9a..405c093 100644 --- a/project2/basics/aggregates/join.cpp +++ b/project2/basics/aggregates/join.cpp @@ -13,10 +13,10 @@ class Join : public ValueAggregate { sum.clear(); first = true; } - void pushValue(const VariableType & v) const + void pushValue(const VariableType & v, ExecContext * ec) const { if (!first) { - sum += sep().as<Glib::ustring>(); + sum += sep(ec).as<Glib::ustring>(); } sum += v.as<Glib::ustring>(); first = false; diff --git a/project2/basics/aggregates/max.cpp b/project2/basics/aggregates/max.cpp index ef904ed..6304647 100644 --- a/project2/basics/aggregates/max.cpp +++ b/project2/basics/aggregates/max.cpp @@ -8,7 +8,7 @@ class Max : public ValueAggregate { { result = VariableType(); } - void pushValue(const VariableType & v) const + void pushValue(const VariableType & v, ExecContext *) const { if (result < v) { result = v; diff --git a/project2/basics/aggregates/min.cpp b/project2/basics/aggregates/min.cpp index ee0bf3d..75b0b87 100644 --- a/project2/basics/aggregates/min.cpp +++ b/project2/basics/aggregates/min.cpp @@ -12,7 +12,7 @@ class Min : public ValueAggregate { result = VariableType(); first = true; } - void pushValue(const VariableType & v) const + void pushValue(const VariableType & v, ExecContext *) const { if (first || v < result) { result = v; diff --git a/project2/basics/aggregates/sum.cpp b/project2/basics/aggregates/sum.cpp index 9bc1120..68a9cd4 100644 --- a/project2/basics/aggregates/sum.cpp +++ b/project2/basics/aggregates/sum.cpp @@ -11,7 +11,7 @@ class Sum : public ValueAggregate { { sum = 0; } - void pushValue(const VariableType & v) const + void pushValue(const VariableType & v, ExecContext *) const { sum += v.as<double>(); } diff --git a/project2/basics/functions/dates.cpp b/project2/basics/functions/dates.cpp index f2dcb20..b19b921 100644 --- a/project2/basics/functions/dates.cpp +++ b/project2/basics/functions/dates.cpp @@ -16,10 +16,10 @@ class ParseDate : public VariableImpl { format(e, "format") { } - VariableType value() const + VariableType value(ExecContext * ec) const { - const char * s = string(); - const char * f = format(); + const char * s = string(ec); + const char * f = format(ec); struct tm tm; memset(&tm, 0, sizeof(struct tm)); mktime(&tm); @@ -27,7 +27,7 @@ class ParseDate : public VariableImpl { if (!e || *e) { Logger()->messagef(LOG_ERR, "%s: check failed (parse) for '%s' against '%s' (remaining chars='%s')", __PRETTY_FUNCTION__, s, f, e); - throw DateParseError(string(), format()); + throw DateParseError(string(ec), format(ec)); } return boost::posix_time::ptime(boost::posix_time::ptime_from_tm(tm)); } @@ -44,13 +44,13 @@ class FormatDate : public VariableImpl { format(e, "format") { } - VariableType value() const + VariableType value(ExecContext * ec) const { std::stringstream ss; boost::date_time::time_facet<boost::posix_time::ptime, char> * ft = new boost::date_time::time_facet<boost::posix_time::ptime, char>(); ss.imbue(std::locale(ss.getloc(), ft)); - ft->format(format()); - ss << boost::get<boost::posix_time::ptime>(date()); + ft->format(format(ec)); + ss << boost::get<boost::posix_time::ptime>(date(ec)); return ss.str(); } private: @@ -66,9 +66,9 @@ class AdjustDate : public VariableImpl { offset(e, "offset") { } - VariableType value() const + VariableType value(ExecContext * ec) const { - return boost::get<boost::posix_time::ptime>(date()) + boost::posix_time::duration_from_string(offset()); + return boost::get<boost::posix_time::ptime>(date(ec)) + boost::posix_time::duration_from_string(offset(ec)); } private: Variable date; @@ -81,7 +81,7 @@ class CurrentDate : public VariableImpl { CurrentDate(ScriptNodePtr) { } - VariableType value() const + VariableType value(ExecContext *) const { return boost::posix_time::microsec_clock::universal_time(); } diff --git a/project2/basics/functions/strings.cpp b/project2/basics/functions/strings.cpp index d4ba7b7..735a781 100644 --- a/project2/basics/functions/strings.cpp +++ b/project2/basics/functions/strings.cpp @@ -10,9 +10,9 @@ class Trim : public VariableImpl { string(e, "string") { } - VariableType value() const + VariableType value(ExecContext * ec) const { - Glib::ustring str = string(); + Glib::ustring str = string(ec); Glib::ustring::const_iterator b = str.begin(); while (Glib::Unicode::isspace(*b)) ++b; Glib::ustring::const_iterator e = str.end(); diff --git a/project2/basics/pch.hpp b/project2/basics/pch.hpp index d52b275..0421cfb 100644 --- a/project2/basics/pch.hpp +++ b/project2/basics/pch.hpp @@ -4,7 +4,6 @@ #include <aggregate.h> #include <algorithm> -#include <appEngine.h> #include <boost/algorithm/string/predicate.hpp> #include <boost/bind.hpp> #include <boost/date_time.hpp> diff --git a/project2/basics/tests/compoundTest.cpp b/project2/basics/tests/compoundTest.cpp index b361db5..119026e 100644 --- a/project2/basics/tests/compoundTest.cpp +++ b/project2/basics/tests/compoundTest.cpp @@ -20,11 +20,11 @@ class All : public CompoundTest { SourceObject(s), CompoundTest(s) { } - bool passes() const { + bool passes(ExecContext * ec) const { if (tests.empty()) { throw NoTestsToPerform(); } - return (std::find_if(tests.begin(), tests.end(), !boost::bind(&Test::passes, _1)) == tests.end()); + return (std::find_if(tests.begin(), tests.end(), !boost::bind(&Test::passes, _1, ec)) == tests.end()); } }; DECLARE_LOADER("all", All); @@ -35,11 +35,11 @@ class Any : public CompoundTest { SourceObject(s), CompoundTest(s) { } - bool passes() const { + bool passes(ExecContext * ec) const { if (tests.empty()) { throw NoTestsToPerform(); } - return (std::find_if(tests.begin(), tests.end(), boost::bind(&Test::passes, _1)) != tests.end()); + return (std::find_if(tests.begin(), tests.end(), boost::bind(&Test::passes, _1, ec)) != tests.end()); } }; DECLARE_LOADER("any", Any); @@ -50,11 +50,11 @@ class None : public CompoundTest { SourceObject(s), CompoundTest(s) { } - bool passes() const { + bool passes(ExecContext * ec) const { if (tests.empty()) { throw NoTestsToPerform(); } - return (std::find_if(tests.begin(), tests.end(), boost::bind(&Test::passes, _1)) == tests.end()); + return (std::find_if(tests.begin(), tests.end(), boost::bind(&Test::passes, _1, ec)) == tests.end()); } }; DECLARE_LOADER("none", None); @@ -67,11 +67,11 @@ class Not : public Test { { s->script->loader.addLoadTarget(s, Storer::into<ElementLoader>(&test)); } - bool passes() const { + bool passes(ExecContext * ec) const { if (!test) { throw NoTestsToPerform(); } - return !test->passes(); + return !test->passes(ec); } private: TestPtr test; diff --git a/project2/basics/tests/equals.cpp b/project2/basics/tests/equals.cpp index ba8c695..6c7a74f 100644 --- a/project2/basics/tests/equals.cpp +++ b/project2/basics/tests/equals.cpp @@ -13,8 +13,8 @@ class Equals : public Test { { } - bool passes() const { - return (a() == b()); + bool passes(ExecContext * ec) const { + return (a(ec) == b(ec)); } private: diff --git a/project2/basics/tests/isdistinct.cpp b/project2/basics/tests/isdistinct.cpp index ab7bf1b..303f88d 100644 --- a/project2/basics/tests/isdistinct.cpp +++ b/project2/basics/tests/isdistinct.cpp @@ -17,13 +17,13 @@ class IsDistinct : public Test, IHaveParameters { void loadComplete(const CommonObjects *) { - findComponent(scope())->registerFor(RowProcessor::Complete, boost::bind(&IsDistinct::reset, this)); + findComponent(scope(NULL))->registerFor(RowProcessor::Complete, boost::bind(&IsDistinct::reset, this)); } - bool passes() const { + bool passes(ExecContext * ec) const { Vars row; BOOST_FOREACH(const Parameters::value_type & p, parameters) { - row.push_back(p.second()); + row.push_back(p.second(ec)); } return previous.insert(row).second; } diff --git a/project2/basics/tests/isuniq.cpp b/project2/basics/tests/isuniq.cpp index c14ea84..e33aba8 100644 --- a/project2/basics/tests/isuniq.cpp +++ b/project2/basics/tests/isuniq.cpp @@ -17,21 +17,21 @@ class IsUniq : public Test, IHaveParameters { void loadComplete(const CommonObjects *) { - findComponent(scope())->registerFor(RowProcessor::Complete, boost::bind(&IsUniq::reset, this)); + findComponent(scope(NULL))->registerFor(RowProcessor::Complete, boost::bind(&IsUniq::reset, this)); } - bool passes() const { + bool passes(ExecContext * ec) const { if (previous.size() > 0) { Vars row; BOOST_FOREACH(const Parameters::value_type & p, parameters) { - row.push_back(p.second()); + row.push_back(p.second(ec)); } std::swap(row, previous); return row != previous; } else { BOOST_FOREACH(const Parameters::value_type & p, parameters) { - previous.push_back(p.second()); + previous.push_back(p.second(ec)); } return true; } diff --git a/project2/basics/tests/validDateCheck.cpp b/project2/basics/tests/validDateCheck.cpp index 8dffd9d..b1ab5a3 100644 --- a/project2/basics/tests/validDateCheck.cpp +++ b/project2/basics/tests/validDateCheck.cpp @@ -13,7 +13,7 @@ class ValidDateTest : public Test { Test(p), applyTo(p, "apply-to"), format(p, "format"), - warnLev(p->value("warn", true).as<bool>() ? LOG_WARNING : LOG_INFO) + warnLev(p->value("warn", true, NULL).as<bool>() ? LOG_WARNING : LOG_INFO) { } @@ -22,13 +22,13 @@ class ValidDateTest : public Test { } bool - passes() const + passes(ExecContext * ec) const { struct tm tm, ftm; memset(&tm, 0, sizeof(struct tm)); mktime(&tm); - const char * at = applyTo(); - const char * f = format(); + const char * at = applyTo(ec); + const char * f = format(ec); const char * s = strptime(at, f, &tm); if (!s || *s) { Logger()->messagef(warnLev, "%s: check failed (parse) for '%s' against '%s'", diff --git a/project2/cgi/Jamfile.jam b/project2/cgi/Jamfile.jam index cf6e55c..8da2f11 100644 --- a/project2/cgi/Jamfile.jam +++ b/project2/cgi/Jamfile.jam @@ -57,4 +57,3 @@ exe testCgi : <library>p2cgicommon <include>../../libmisc ; - diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp index 75bc004..2a82595 100644 --- a/project2/cgi/cgiAppEngine.cpp +++ b/project2/cgi/cgiAppEngine.cpp @@ -3,45 +3,83 @@ #include "cgiResult.h" #include <cgicc/Cgicc.h> #include <cgicc/HTTPHeader.h> -#include "cgiEnvironment.h" +#include <cgicc/HTTPStatusHeader.h> +#include "cgiRequestContext.h" #include "iterate.h" #include <boost/bind.hpp> #include <boost/foreach.hpp> #include "ostreamWrapper.h" #include "scopeObject.h" +#include "logger.h" #include <boost/date_time/microsec_time_clock.hpp> #include <boost/uuid/uuid_io.hpp> -#include <boost/uuid/uuid_generators.hpp> #include <boost/lexical_cast.hpp> +#include <glibmm/exception.h> +#include <cxxabi.h> -const std::string SESSIONID = "sessionID"; typedef boost::uuids::uuid SIDKey; typedef std::string SValue; SimpleMessageException(UnknownDomain); -CgiApplicationEngine::CgiApplicationEngine(const CgiEnvironment * e, std::ostream & io) : - _env(e), - sessionsContainer(SessionContainerLoader::getFor(e->sessionModule)->create()), - IO(io), - outputCachingActive(false) -{ - try { - cursession = sessionsContainer->GetSession(boost::uuids::string_generator()(e->getCookieValue(SESSIONID))); - } - catch (const NoSuchCookie &) { - cursession = sessionsContainer->GetSession(boost::uuids::uuid()); - } -} +std::string CgiApplicationEngine::dumpdatadoc; +Glib::ustring CgiApplicationEngine::errorContentType; +Glib::ustring CgiApplicationEngine::errorTransformStyle; +std::string CgiApplicationEngine::defaultPresent; +std::string CgiApplicationEngine::transformContentType; +std::string CgiApplicationEngine::transformTargetType; +std::string CgiApplicationEngine::presentRoot; +std::string CgiApplicationEngine::requestRoot; +std::string CgiApplicationEngine::errorPresentRoot; +std::string CgiApplicationEngine::notFoundPresent; +std::string CgiApplicationEngine::onErrorPresent; +std::string CgiApplicationEngine::defaultPresenter; +SessionContainerPtr CgiApplicationEngine::sessionsContainer; +std::string CgiApplicationEngine::sessionCookie; +boost::shared_ptr<RouterLoader> CgiApplicationEngine::router; +boost::intrusive_ptr<HostnamePlatformIdentifier> CgiApplicationEngine::hpi; -CgiApplicationEngine::~CgiApplicationEngine() +DECLARE_OPTIONS(CgiApplicationEngine, "Project2 CGI options") +("cgi.defaultPresenter", Options::value(&defaultPresenter, "xml"), + "The default engine for formatting presentations") +("cgi.transformContentType", Options::value(&transformContentType, "text/xml-xslt"), + "The content type specified to enable standard internal transformations") +("cgi.transformTargetType", Options::value(&transformTargetType, "htmldocument"), + "The transform target type used in standard internal transformations") +("cgi.defaultPresent", Options::value(&defaultPresent, "index"), + "The present script to use when no other is specified") +("cgi.presentRoot", Options::value(&presentRoot, "present"), + "The folder in which to find presentation scripts") +("cgi.requestRoot", Options::value(&requestRoot, "request"), + "The folder in which to find request scripts") +("cgi.errorPresentRoot", Options::value(&errorPresentRoot, "error"), + "The folder in which to find presentation scripts for error handling") +("cgi.errorContentType", Options::value(&errorContentType, "application/xml"), + "The Content-Type to use in HTTP headers in event of an error") +("cgi.errorTransformStyle", Options::value(&errorTransformStyle), + "The xml-stylesheet to specify in the data document in event of an error") +("cgi.notFoundPresent", Options::value(¬FoundPresent), + "The present script to use when the requested script does not exist") +("cgi.onErrorPresent", Options::value(&onErrorPresent), + "The present script to use when the requested script (or child) fails") +("cgi.dumpDataDoc", Options::value(&dumpdatadoc), + "Write a copy of the data document before sending it to the web server") +("cgi.sessionModule", Options::function([](const VariableType & m) { sessionsContainer = SessionContainerLoader::createNew(m); }, "xml"), + "The module with which to implement session management") +("cgi.sessionCookie", Options::value(&sessionCookie, "sessionID"), + "The name of the cookie for storing session IDs") +("cgi.hostRegex", (hpi = new HostnamePlatformIdentifier()), + "Regular expression used to define a hostname -> platform association") +("cgi.router", Options::function([](const VariableType & r) { router = RouterLoader::getFor(r); }, "simple"), + "Implemenation of router model to map request paths to scripts") +END_OPTIONS(CgiApplicationEngine); + +CgiApplicationEngine::CgiApplicationEngine() { } -const CgiEnvironment * -CgiApplicationEngine::env() const +CgiApplicationEngine::~CgiApplicationEngine() { - return _env; } TransformSourcePtr @@ -61,51 +99,51 @@ finalTransformSource(TransformSourcePtr ts) } void -CgiApplicationEngine::process() const +CgiApplicationEngine::processRun(std::ostream & IO, CgiRequestContext * crc) const { - bool sessionEmpty = cursession->Empty(); - startTime = boost::date_time::microsec_clock<boost::posix_time::ptime>::universal_time(); + bool sessionEmpty = crc->getSession()->Empty(); + crc->startTime = boost::date_time::microsec_clock<boost::posix_time::ptime>::universal_time(); bool triedNotFound = false; bool triedOnError = false; NextStage currentStage = NextStage(new InitialStage()); do { try { - currentStage = currentStage.get<0>()->run(); + currentStage = currentStage.get<0>()->run(crc); } catch (const CheckHost::CheckFailure & cf) { - currentStage = NextStage(new PresentStage(ScriptReader::resolveScript(_env->presentRoot, cf.failedCheck->present(), false))); + currentStage = NextStage(new PresentStage(ScriptReader::resolveScript(presentRoot, cf.failedCheck->present(crc), false), crc)); } catch (const ScriptNotFound & nf) { - if (_env->notFoundPresent.empty() || triedNotFound) { + if (notFoundPresent.empty() || triedNotFound) { currentStage = NextStage(new DefaultNotFoundStage(nf)); } else { triedNotFound = true; - currentStage = NextStage(new CustomNotFoundStage(nf, ScriptReader::resolveScript(_env->errorPresentRoot, _env->notFoundPresent, false))); + currentStage = NextStage(new CustomNotFoundStage(nf, ScriptReader::resolveScript(errorPresentRoot, notFoundPresent, false), crc)); } } catch (const std::exception & ex) { - if (_env->onErrorPresent.empty() || triedOnError) { - currentStage = NextStage(new DefaultErrorStage(ex)); + if (onErrorPresent.empty() || triedOnError) { + currentStage = NextStage(new DefaultErrorStage(ex, crc)); } else { triedNotFound = true; - currentStage = NextStage(new CustomErrorStage(ex, ScriptReader::resolveScript(_env->errorPresentRoot, _env->onErrorPresent, false))); + currentStage = NextStage(new CustomErrorStage(ex, ScriptReader::resolveScript(errorPresentRoot, onErrorPresent, false), crc)); } } } while (currentStage.get<0>()); - endTime = boost::date_time::microsec_clock<boost::posix_time::ptime>::universal_time(); + crc->endTime = boost::date_time::microsec_clock<boost::posix_time::ptime>::universal_time(); ResponseStagePtr rs = currentStage.get<1>(); - outputCachingActive = !rs->caches.empty(); + bool outputCachingActive = !rs->caches.empty(); if (const MultiRowSetPresenter * p = currentStage.get<3>().get()) { - addAppData(p, rs->outputOptions); - addEnvData(p, rs->outputOptions); + addAppData(p, rs->outputOptions, crc, outputCachingActive); + addEnvData(p, rs->outputOptions, crc, outputCachingActive); } - HttpHeaderPtr header = rs->getHeader(); - if (!sessionEmpty || !cursession->Empty()) { - sessionsContainer->SaveSession(cursession); - header->setCookie(cgicc::HTTPCookie(SESSIONID, boost::lexical_cast<std::string>(cursession->ID()), "Session ID", - _env->getServerName().substr(_env->getServerName().find(".")), SessionContainer::sessionTimeOut, "/", false)); + HttpHeaderPtr header = rs->getHeader(crc); + if (!sessionEmpty || !crc->getSession()->Empty()) { + sessionsContainer->SaveSession(crc->getSession()); + header->setCookie(cgicc::HTTPCookie(sessionCookie, boost::lexical_cast<std::string>(crc->getSession()->ID()), "Session ID", + crc->getServerName().substr(crc->getServerName().find(".")), SessionContainer::sessionTimeOut, "/", false)); } if (TransformSourcePtr ts = currentStage.get<2>()) { TransformSourcePtr final = finalTransformSource(ts); @@ -113,10 +151,10 @@ CgiApplicationEngine::process() const boost::shared_ptr<std::fstream> ddd; ostreamWrapper * osw = NULL; ScopeObject removeDdd([ts, &osw] { if (osw) { ts->removeTarget(osw); } }); - if (!_env->dumpdatadoc.empty()) { - ddd = boost::shared_ptr<std::fstream>(new std::fstream(_env->dumpdatadoc.c_str(), std::fstream::trunc | std::fstream::out)); + if (!dumpdatadoc.empty()) { + ddd = boost::shared_ptr<std::fstream>(new std::fstream(dumpdatadoc.c_str(), std::fstream::trunc | std::fstream::out)); if (ddd->good()) { - ts->addTarget(osw = new ostreamWrapper(*ddd)); + ts->addTarget(osw = new ostreamWrapper(*ddd), crc, NULL); } else { ddd.reset(); @@ -124,23 +162,23 @@ CgiApplicationEngine::process() const } if (outputCachingActive) { BOOST_FOREACH(const PresenterCachePtr & p, rs->caches) { - final->addTarget(p, NULL); + final->addTarget(p, crc, NULL); } - ts->doTransforms(); + ts->doTransforms(crc); BOOST_FOREACH(const PresenterCachePtr & p, rs->caches) { p->flushCache(); } - if (rs->caches.front()->check(0)) { + if (rs->caches.front()->check(0, crc)) { ScopeObject emptyFinal([rs] { rs->caches.front()->clearTargets(); }); rs->caches.front()->addTarget(new CgiResult(header, IO, - rs && rs->outputOptions ? rs->outputOptions->Encoding().as<std::string>() : OutputOptions::encoding), NULL); - rs->caches.front()->doTransforms(); + rs && rs->outputOptions ? rs->outputOptions->Encoding(crc).as<std::string>() : OutputOptions::encoding), crc, NULL); + rs->caches.front()->doTransforms(crc); return; } } final->addTarget(new CgiResult(header, IO, - rs && rs->outputOptions ? rs->outputOptions->Encoding().as<std::string>() : OutputOptions::encoding), NULL); - ts->doTransforms(); + rs && rs->outputOptions ? rs->outputOptions->Encoding(crc).as<std::string>() : OutputOptions::encoding), crc, NULL); + ts->doTransforms(crc); } else { header->render(IO); @@ -151,44 +189,38 @@ CgiApplicationEngine::Stage::~Stage() { } -const CgiEnvironment * -CgiApplicationEngine::Stage::env() const -{ - return dynamic_cast<const CgiEnvironment *>(Environment::getCurrent()); -} - void -CgiApplicationEngine::addEnvData(const MultiRowSetPresenter * p, OutputOptionsPtr o) const +CgiApplicationEngine::addEnvData(const MultiRowSetPresenter * p, OutputOptionsPtr o, CgiRequestContext * crc, bool outputCachingActive) const { - if (!o || o->Environment()) { + if (!o || o->Environment(crc)) { // Environment set up by web server p->addNewRowSet("environment", Scripts::scriptNamespacePrefix); // Server stuff - addEnvToPresenter(p, "servername", &cgicc::CgiEnvironment::getServerName); - addEnvToPresenter(p, "serversoftware", &cgicc::CgiEnvironment::getServerSoftware); - addEnvToPresenter(p, "serverprotocol", &cgicc::CgiEnvironment::getServerProtocol); - addEnvToPresenter(p, "serverport", &cgicc::CgiEnvironment::getServerPort); - addEnvToPresenter(p, "serverhttps", &cgicc::CgiEnvironment::usingHTTPS); + addEnvToPresenter(p, "servername", &cgicc::CgiEnvironment::getServerName, crc); + addEnvToPresenter(p, "serversoftware", &cgicc::CgiEnvironment::getServerSoftware, crc); + addEnvToPresenter(p, "serverprotocol", &cgicc::CgiEnvironment::getServerProtocol, crc); + addEnvToPresenter(p, "serverport", &cgicc::CgiEnvironment::getServerPort, crc); + addEnvToPresenter(p, "serverhttps", &cgicc::CgiEnvironment::usingHTTPS, crc); // Request stuff if (!outputCachingActive) { - addEnvToPresenter(p, "referrer", &cgicc::CgiEnvironment::getReferrer); - addEnvToPresenter(p, "querystring", &cgicc::CgiEnvironment::getQueryString); + addEnvToPresenter(p, "referrer", &cgicc::CgiEnvironment::getReferrer, crc); + addEnvToPresenter(p, "querystring", &cgicc::CgiEnvironment::getQueryString, crc); } p->finishRowSet(); } - if (!o || o->URL()) { + if (!o || o->URL(crc)) { // URL elements p->addNewRowSet("uriElems", Scripts::scriptNamespacePrefix); - p->addAttribute("full", _env->getRedirectURL()); - _env->router->present(p); + p->addAttribute("full", crc->getRedirectURL()); + crc->router->present(p); p->finishRowSet(); } - if (!o || o->Parameters()) { + if (!o || o->Parameters(crc)) { // Parameters p->addNewRowSet("params", Scripts::scriptNamespacePrefix); - BOOST_FOREACH(cgicc::FormEntry fe, _env->cgi->getElements()) { + BOOST_FOREACH(cgicc::FormEntry fe, crc->cgi.getElements()) { p->addNamedValue(fe.getName(), fe.getValue()); } p->finishRowSet(); @@ -202,34 +234,78 @@ CgiApplicationEngine::addVarToPresenter(const MultiRowSetPresenter * p, const Gl } void -CgiApplicationEngine::addAppData(const MultiRowSetPresenter * p, OutputOptionsPtr o) const +CgiApplicationEngine::addAppData(const MultiRowSetPresenter * p, OutputOptionsPtr o, CgiRequestContext * crc, bool outputCachingActive) const { - if (!o || o->Core()) { - addCoreAppData(p); + if (!o || o->Core(crc)) { + crc->addContextData(p); } - if (!outputCachingActive && (!cursession->Empty()) && (!o || o->Session())) { + if (!outputCachingActive && (!crc->getSession()->Empty()) && (!o || o->Session(crc))) { // Sessions variables p->addNewRowSet("session", Scripts::scriptNamespacePrefix); - p->addAttribute("id", boost::lexical_cast<Glib::ustring>(cursession->ID())); - cursession->ForeachValue(boost::bind(&CgiApplicationEngine::addVarToPresenter, this, p, _1, _2)); + p->addAttribute("id", boost::lexical_cast<Glib::ustring>(crc->getSession()->ID())); + crc->getSession()->ForeachValue(boost::bind(&CgiApplicationEngine::addVarToPresenter, this, p, _1, _2)); p->finishRowSet(); } - if (!outputCachingActive && (!o || o->Timing())) { + if (!outputCachingActive && (!o || o->Timing(crc))) { // Timing info p->addNewRowSet("timing", Scripts::scriptNamespacePrefix); - p->addAttribute("start", startTime); - if (!endTime.is_not_a_date_time()) { - p->addAttribute("end", endTime); - p->addAttribute("duration", (endTime - startTime).total_milliseconds()); + p->addAttribute("start", crc->startTime); + if (!crc->endTime.is_not_a_date_time()) { + p->addAttribute("end", crc->endTime); + p->addAttribute("duration", (crc->endTime - crc->startTime).total_milliseconds()); } p->finishRowSet(); } } -SessionPtr -CgiApplicationEngine::session() const +const char * +what(const Glib::Exception & e) +{ + return e.what().c_str(); +} +const char * +what(const std::exception & e) { - return cursession; + return e.what(); +} +template <typename E> +void +doExceptionReporting(const E & e, std::ostream & IO) +{ + char * buf = __cxxabiv1::__cxa_demangle(typeid(e).name(), NULL, NULL, NULL); + Logger()->messagef(LOG_ERR, "%s: Request errored: %s: %s", __FUNCTION__, buf, what(e)); + cgicc::HTTPStatusHeader header(500, e.what()); + header.render(IO); + IO << "Kaboom!" << std::endl + << std::endl + << buf << std::endl + << "what '" << e.what() << "'" << std::endl; + free(buf); +} + +void +CgiApplicationEngine::process(std::ostream & IO, CgiRequestContext * crc) const +{ + try { + Logger()->messagef(LOG_DEBUG, "%s: Processing request", __FUNCTION__); + processRun(IO, crc); + Logger()->messagef(LOG_DEBUG, "%s: Completed request", __FUNCTION__); + } + catch (const std::exception & e) { + doExceptionReporting(e, IO); + } + catch (const Glib::Exception & e) { + doExceptionReporting(e, IO); + } + catch (...) { + Logger()->messagef(LOG_ERR, "%s: Request errored: Unknown exception", __FUNCTION__); + cgicc::HTTPStatusHeader header(500, "Unknown exception"); + header.render(IO); + IO << "Kaboom!" << std::endl + << std::endl + << "Unknown exception." << std::endl; + throw; + } } diff --git a/project2/cgi/cgiAppEngine.h b/project2/cgi/cgiAppEngine.h index f5f0e08..6d3cd0c 100644 --- a/project2/cgi/cgiAppEngine.h +++ b/project2/cgi/cgiAppEngine.h @@ -1,7 +1,6 @@ #ifndef CGIAPPENGINE_H #define CGIAPPENGINE_H -#include "appEngine.h" #include "task.h" #include "commonObjects.h" #include "taskHost.h" @@ -15,7 +14,7 @@ #include <boost/tuple/tuple.hpp> #include "cgiOutputOptions.h" #include "cgiHttpHeader.h" -#include "cgiEnvironment.h" +#include "cgiRequestContext.h" #include <cgicc/Cgicc.h> class Session; @@ -24,29 +23,26 @@ namespace cgicc { class CgiEnvironment; } -class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink { +class CgiApplicationEngine { public: typedef boost::shared_ptr<Project2HttpHeader> HttpHeaderPtr; - CgiApplicationEngine(const CgiEnvironment *, std::ostream &); + CgiApplicationEngine(); virtual ~CgiApplicationEngine(); - void process() const; - const CgiEnvironment * env() const; - SessionPtr session() const; - void addAppData(const MultiRowSetPresenter * p, OutputOptionsPtr) const; - void addEnvData(const MultiRowSetPresenter * p, OutputOptionsPtr) const; + void process(std::ostream & IO, CgiRequestContext *) const; private: - const CgiEnvironment * _env; - mutable boost::posix_time::ptime startTime; - mutable boost::posix_time::ptime endTime; - SessionContainerPtr sessionsContainer; + void processRun(std::ostream & IO, CgiRequestContext *) const; + void addAppData(const MultiRowSetPresenter * p, OutputOptionsPtr o, CgiRequestContext *, bool) const; + void addEnvData(const MultiRowSetPresenter * p, OutputOptionsPtr o, CgiRequestContext *, bool) const; + // Helpers + // void addVarToPresenter(const MultiRowSetPresenter * p, const Glib::ustring & name, const VariableType &) const; template <class X, class Y> - void addEnvToPresenter(const MultiRowSetPresenter * p, const char * name, X (Y::*getter)() const) const { - addVarToPresenter(p, name, (_env->cgi->getEnvironment().*getter)()); + void addEnvToPresenter(const MultiRowSetPresenter * p, const char * name, X (Y::*getter)() const, CgiRequestContext * crc) const { + addVarToPresenter(p, name, (crc->cgi.getEnvironment().*getter)()); } public: @@ -59,9 +55,7 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink class Stage : public virtual IntrusivePtrBase { public: virtual ~Stage() = 0; - virtual NextStage run() = 0; - protected: - const CgiEnvironment * env() const; + virtual NextStage run(CgiRequestContext *) = 0; }; /// Base class for a stage that can be a response to the client @@ -70,7 +64,7 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink typedef ANONORDEREDSTORAGEOF(PresenterCache) PresenterCaches; ResponseStage(ScriptNodePtr root); - virtual HttpHeaderPtr getHeader() const = 0; + virtual HttpHeaderPtr getHeader(CgiRequestContext *) const = 0; OutputOptionsPtr outputOptions; ScriptNodePtr root; @@ -80,7 +74,7 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink /// Stage implementation used to bootstrap the iteration process based on the CGI environment class InitialStage : public Stage { public: - virtual NextStage run(); + virtual NextStage run(CgiRequestContext *); }; /// Stage to process POST requests @@ -88,8 +82,8 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink public: RequestStage(ScriptReaderPtr); - virtual NextStage run(); - virtual HttpHeaderPtr getHeader() const; + virtual NextStage run(CgiRequestContext *); + virtual HttpHeaderPtr getHeader(CgiRequestContext *) const; protected: Variable present; Variable redirect; @@ -98,11 +92,11 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink /// Stage to process GET requests and follow up RequestStages class PresentStage : public virtual ResponseStage, ViewHost { public: - PresentStage(ScriptReaderPtr); - MultiRowSetPresenterPtr getPresenter() const; + PresentStage(ScriptReaderPtr, CgiRequestContext *); + MultiRowSetPresenterPtr getPresenter(ExecContext *) const; - virtual NextStage run(); - virtual HttpHeaderPtr getHeader() const; + virtual NextStage run(CgiRequestContext *); + virtual HttpHeaderPtr getHeader(CgiRequestContext *) const; protected: HttpHeaderPtr header; LazyPointer<MultiRowSetPresenter> presenter; @@ -113,8 +107,8 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink public: CacheHitStage(ScriptNodePtr, PresenterCachePtr); - virtual NextStage run(); - virtual HttpHeaderPtr getHeader() const; + virtual NextStage run(CgiRequestContext *); + virtual HttpHeaderPtr getHeader(CgiRequestContext *) const; protected: PresenterCachePtr pc; }; @@ -124,8 +118,8 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink public: DefaultNotFoundStage(const ScriptNotFound &); - virtual NextStage run(); - virtual HttpHeaderPtr getHeader() const; + virtual NextStage run(CgiRequestContext *); + virtual HttpHeaderPtr getHeader(CgiRequestContext *) const; private: const ScriptNotFound nf; XmlPresenterPtr pres; @@ -134,19 +128,19 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink /// Custom not found handling stage class CustomNotFoundStage : public DefaultNotFoundStage, public PresentStage { public: - CustomNotFoundStage(const ScriptNotFound &, ScriptReaderPtr); - virtual NextStage run(); - virtual HttpHeaderPtr getHeader() const; + CustomNotFoundStage(const ScriptNotFound &, ScriptReaderPtr, CgiRequestContext *); + virtual NextStage run(CgiRequestContext *); + virtual HttpHeaderPtr getHeader(CgiRequestContext *) const; }; /// The built-in fail-safe unhandled error stage class DefaultErrorStage : public virtual ResponseStage { public: - DefaultErrorStage(const std::exception &); + DefaultErrorStage(const std::exception &, CgiRequestContext *); ~DefaultErrorStage(); - virtual NextStage run(); - virtual HttpHeaderPtr getHeader() const; + virtual NextStage run(CgiRequestContext *); + virtual HttpHeaderPtr getHeader(CgiRequestContext *) const; private: char * buf; std::string what; @@ -156,15 +150,29 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink /// Custom unhandled error handling stage class CustomErrorStage : public DefaultErrorStage, public PresentStage { public: - CustomErrorStage(const std::exception &, ScriptReaderPtr); - virtual NextStage run(); - virtual HttpHeaderPtr getHeader() const; + CustomErrorStage(const std::exception &, ScriptReaderPtr, CgiRequestContext *); + virtual NextStage run(CgiRequestContext *); + virtual HttpHeaderPtr getHeader(CgiRequestContext *) const; }; + INITOPTIONS; + static boost::intrusive_ptr<HostnamePlatformIdentifier> hpi; + static boost::shared_ptr<RouterLoader> router; + static SessionContainerPtr sessionsContainer; + static std::string sessionCookie; private: - SessionPtr cursession; - std::ostream & IO; - mutable bool outputCachingActive; + static std::string dumpdatadoc; + static Glib::ustring errorContentType; + static Glib::ustring errorTransformStyle; + static std::string defaultPresent; + static std::string transformContentType; + static std::string transformTargetType; + static std::string presentRoot; + static std::string requestRoot; + static std::string errorPresentRoot; + static std::string notFoundPresent; + static std::string onErrorPresent; + static std::string defaultPresenter; }; #endif diff --git a/project2/cgi/cgiCommon.cpp b/project2/cgi/cgiCommon.cpp deleted file mode 100644 index a4ed8c4..0000000 --- a/project2/cgi/cgiCommon.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include <pch.hpp> -#include "cgiCommon.h" -#include "optionsSource.h" -#include "logger.h" -#include <glibmm/exception.h> -#include <cgicc/CgiEnvironment.h> -#include <cgicc/HTTPContentHeader.h> -#include <cgicc/HTTPStatusHeader.h> -#include "cgiAppEngine.h" -#include <boost/bind.hpp> -#include <cxxabi.h> - -// These are templates because some people don't inherit their -// exceptions from std::exception like normal people (Glib) -const char * -what(const Glib::Exception & e) -{ - return e.what().c_str(); -} -const char * -what(const std::exception & e) -{ - return e.what(); -} -template <typename E> -void -doExceptionReporting(const E & e, std::ostream & IO) -{ - char * buf = __cxxabiv1::__cxa_demangle(typeid(e).name(), NULL, NULL, NULL); - Logger()->messagef(LOG_ERR, "%s: Request errored: %s: %s", __FUNCTION__, buf, what(e)); - cgicc::HTTPStatusHeader header(500, e.what()); - header.render(IO); - IO << "Kaboom!" << std::endl - << std::endl - << buf << std::endl - << "what '" << e.what() << "'" << std::endl; - free(buf); -} - -void -cgiServe(cgicc::CgiInput * i, CgiEnvironment * env, std::ostream & IO, const CgiEnvInput * e) -{ - try { - cgicc::Cgicc cgi(i); - env->setCGICC(&cgi, e); - OptionsSource::loadSources(); - CgiApplicationEngine app(env, IO); - - Plugable::onAllComponents(boost::bind(&ComponentLoader::onBefore, _1)); - Logger()->messagef(LOG_DEBUG, "%s: Processing request", __FUNCTION__); - app.process(); - Logger()->messagef(LOG_DEBUG, "%s: Completed request", __FUNCTION__); - } - catch (const std::exception & e) { - doExceptionReporting(e, IO); - } - catch (const Glib::Exception & e) { - doExceptionReporting(e, IO); - } - catch (...) { - Logger()->messagef(LOG_ERR, "%s: Request errored: Unknown exception", __FUNCTION__); - cgicc::HTTPStatusHeader header(500, "Unknown exception"); - header.render(IO); - IO << "Kaboom!" << std::endl - << std::endl - << "Unknown exception." << std::endl; - throw; - } -} - diff --git a/project2/cgi/cgiCommon.h b/project2/cgi/cgiCommon.h deleted file mode 100644 index 42a88e6..0000000 --- a/project2/cgi/cgiCommon.h +++ /dev/null @@ -1,6 +0,0 @@ -#include <ostream> -#include <cgicc/Cgicc.h> -#include "cgiEnvironment.h" - -void cgiServe(cgicc::CgiInput * i, CgiEnvironment *, std::ostream & o, const CgiEnvInput * e); - diff --git a/project2/cgi/cgiContentNegotiate.cpp b/project2/cgi/cgiContentNegotiate.cpp index a7f7557..0b6623e 100644 --- a/project2/cgi/cgiContentNegotiate.cpp +++ b/project2/cgi/cgiContentNegotiate.cpp @@ -6,20 +6,20 @@ class ContentNegotiateLoader : public PresenterLoader { public: - MultiRowSetPresenter * create(const ScriptNodePtr & s, const ObjectSource & os) const + MultiRowSetPresenter * create(const ScriptNodePtr & s, const ObjectSource & os, ExecContext * const & ec) const { - auto accept = static_cast<const CgiApplicationEngine *>(CgiApplicationEngine::getCurrent())->env()->getAccept(); + auto accept = static_cast<const CgiRequestContext *>(ec)->getAccept(); typedef boost::tokenizer<boost::char_separator<char>> tokenizer; BOOST_FOREACH(auto mimetypeAndWeight, tokenizer(accept, boost::char_separator<char>(","))) { const auto mimetype = mimetypeAndWeight.substr(0, mimetypeAndWeight.find(';')); if (mimetype == "*/*") break; BOOST_FOREACH(const auto & t, mappedTypes) { if (t->Matches(mimetype)) { - return PresenterLoader::getFor(t->present)->create(s, os); + return PresenterLoader::getFor(t->present)->create(s, os, ec); } } } - return PresenterLoader::getFor((*mappedTypes.begin())->present)->create(s, os); + return PresenterLoader::getFor((*mappedTypes.begin())->present)->create(s, os, ec); } INITOPTIONS; diff --git a/project2/cgi/cgiEnvironment.cpp b/project2/cgi/cgiEnvironment.cpp deleted file mode 100644 index d2ecf77..0000000 --- a/project2/cgi/cgiEnvironment.cpp +++ /dev/null @@ -1,207 +0,0 @@ -#include <pch.hpp> -#include <boost/bind.hpp> -#include <boost/foreach.hpp> -#include <boost/algorithm/string.hpp> -#include "cgiEnvironment.h" -#include "appEngine.h" -#include "exceptions.h" -#include <map> -#include <cgicc/Cgicc.h> -#include <glibmm/regex.h> -#include <curl/curl.h> - -std::string CgiEnvironment::dumpdatadoc; -Glib::ustring CgiEnvironment::errorContentType; -Glib::ustring CgiEnvironment::errorTransformStyle; -std::string CgiEnvironment::defaultPresent; -std::string CgiEnvironment::transformContentType; -std::string CgiEnvironment::transformTargetType; -std::string CgiEnvironment::presentRoot; -std::string CgiEnvironment::requestRoot; -std::string CgiEnvironment::errorPresentRoot; -std::string CgiEnvironment::notFoundPresent; -std::string CgiEnvironment::onErrorPresent; -std::string CgiEnvironment::defaultPresenter; -std::string CgiEnvironment::sessionModule; -std::string CgiEnvironment::routerType; -boost::intrusive_ptr<HostnamePlatformIdentifier> CgiEnvironment::hpi; - -DECLARE_OPTIONS(CgiEnvironment, "Project2 CGI options") -("cgi.defaultPresenter", Options::value(&defaultPresenter, "xml"), - "The default engine for formatting presentations") -("cgi.transformContentType", Options::value(&transformContentType, "text/xml-xslt"), - "The content type specified to enable standard internal transformations") -("cgi.transformTargetType", Options::value(&transformTargetType, "htmldocument"), - "The transform target type used in standard internal transformations") -("cgi.defaultPresent", Options::value(&defaultPresent, "index"), - "The present script to use when no other is specified") -("cgi.presentRoot", Options::value(&presentRoot, "present"), - "The folder in which to find presentation scripts") -("cgi.requestRoot", Options::value(&requestRoot, "request"), - "The folder in which to find request scripts") -("cgi.errorPresentRoot", Options::value(&errorPresentRoot, "error"), - "The folder in which to find presentation scripts for error handling") -("cgi.errorContentType", Options::value(&errorContentType, "application/xml"), - "The Content-Type to use in HTTP headers in event of an error") -("cgi.errorTransformStyle", Options::value(&errorTransformStyle), - "The xml-stylesheet to specify in the data document in event of an error") -("cgi.notFoundPresent", Options::value(¬FoundPresent), - "The present script to use when the requested script does not exist") -("cgi.onErrorPresent", Options::value(&onErrorPresent), - "The present script to use when the requested script (or child) fails") -("cgi.dumpDataDoc", Options::value(&dumpdatadoc), - "Write a copy of the data document before sending it to the web server") -("cgi.sessionModule", Options::value(&sessionModule, "xml"), - "The module with which to implement session management") -("cgi.hostRegex", (hpi = new HostnamePlatformIdentifier()), - "Regular expression used to define a hostname -> platform association") -("cgi.router", Options::value(&routerType, "simple"), - "Implemenation of router model to map request paths to scripts") -END_OPTIONS(CgiEnvironment); - -CgiEnvironment::CgiEnvironment() : - cgi(NULL), - cgienv(NULL) -{ -} - -CgiEnvironment::~CgiEnvironment() -{ -} - -void -CgiEnvironment::setCGICC(const cgicc::Cgicc * c, const CgiEnvInput * e) -{ - cgi = c; - cgienv = e; - router = boost::bind(&GenLoader<Router, const std::string &>::createNew, boost::cref(routerType), getRedirectURL()); -} - -std::string -CgiEnvironment::getCookieValue(const std::string & name) const -{ - BOOST_FOREACH(const cgicc::HTTPCookie & c, cgi->getEnvironment().getCookieList()) { - if (c.getName() == name) { - return c.getValue(); - } - } - throw NoSuchCookie(name); -} - -std::string -CgiEnvironment::getRequestMethod() const -{ - return cgi->getEnvironment().getRequestMethod(); -} - -std::string -CgiEnvironment::getRedirectURL() const -{ - return cgi->getEnvironment().getRedirectURL(); -} - -std::string -CgiEnvironment::getServerName() const -{ - return cgi->getEnvironment().getServerName(); -} - -std::string -CgiEnvironment::getAccept() const -{ - return cgi->getEnvironment().getAccept(); -} - -const Glib::ustring & -CgiEnvironment::platform() const -{ - return hpi->derivedPlatform(); -} - -CgiEnvironment::ETags -CgiEnvironment::getRequestETags() const -{ - const std::string e = cgienv->getenv("HTTP_IF_NONE_MATCH"); - ETags etags; - boost::split(etags, e, boost::is_any_of(" ,"), boost::algorithm::token_compress_on); - return etags; -} - -time_t -CgiEnvironment::getRequestModifiedSince() const -{ - return curl_getdate(cgienv->getenv("HTTP_IF_MODIFIED_SINCE").c_str(), NULL); -} - -Glib::ustring -CgiEnvironment::getParamUri(VariableType p) const -{ - return router->routeParameter(p); -} - -unsigned int -CgiEnvironment::getParamUriCount() const -{ - return router->parameterCount(); -} - -void -CgiEnvironment::applyAllParameters(const boost::function<void (const std::string &, const std::string &)> & func) const -{ - BOOST_FOREACH(const auto & f, cgi->getElements()) { - func(f.getName(), f.getValue()); - } -} - -Glib::ustring -CgiEnvironment::getParamQuery(const std::string & p) const -{ - cgicc::const_form_iterator i = cgi->getElement(p); - if (i == cgi->getElements().end()) { - throw ParamNotFound(p); - } - return (*cgi)(p); -} - -HostnamePlatformIdentifier::HostnamePlatformIdentifier() : - platform(NULL) -{ -} - -HostnamePlatformIdentifier::~HostnamePlatformIdentifier() -{ - reset(); -} - -const Glib::ustring & -HostnamePlatformIdentifier::derivedPlatform() const -{ - if (platform) { - return *platform; - } - throw NoSuchPlatform(Environment::getCurrent()->getServerName()); -} - -void -HostnamePlatformIdentifier::reset() const -{ - if (platform) { - delete platform; - platform = NULL; - } -} - -bool -HostnamePlatformIdentifier::paramRequired() const -{ - return true; -} - -void -HostnamePlatformIdentifier::consume(const Glib::ustring & p, const VariableType & r) const -{ - if (!platform && Glib::Regex::create(r, Glib::REGEX_CASELESS | Glib::REGEX_DOTALL)->match(Environment::getCurrent()->getServerName())) { - platform = new Glib::ustring(p); - } -} - diff --git a/project2/cgi/cgiEnvironment.h b/project2/cgi/cgiEnvironment.h deleted file mode 100644 index e9de59d..0000000 --- a/project2/cgi/cgiEnvironment.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef ENVPROC_H -#define ENVPROC_H - -#include <string> -#include <vector> -#include "environment.h" -#include "cgiEnvInput.h" -#include "cgiRouter.h" -#include <cgicc/CgiEnvironment.h> -#include <lazyPointer.h> - -SimpleMessageException(NoSuchCookie); - -namespace cgicc { - class Cgicc; -} - -class HostnamePlatformIdentifier : public Options::Target { - public: - HostnamePlatformIdentifier(); - virtual ~HostnamePlatformIdentifier(); - void reset() const; - bool paramRequired() const; - void consume(const Glib::ustring &, const VariableType &) const; - const Glib::ustring & derivedPlatform() const; - private: - mutable Glib::ustring * platform; -}; - -class CgiEnvironment : public Environment { - public: - typedef std::string ETag; - typedef std::vector<ETag> ETags; - - CgiEnvironment(); - virtual ~CgiEnvironment(); - - Glib::ustring getParamUri(VariableType idx) const; - unsigned int getParamUriCount() const; - Glib::ustring getParamQuery(const std::string & idx) const; - void applyAllParameters(const boost::function<void (const std::string &, const std::string &)> &) const; - std::string getServerName() const; - std::string getRedirectURL() const; - std::string getRequestMethod() const; - std::string getAccept() const; - ETags getRequestETags() const; - time_t getRequestModifiedSince() const; - std::string getCookieValue(const std::string & name) const; - - void setCGICC(const cgicc::Cgicc *, const CgiEnvInput * cgienv); - const cgicc::Cgicc * cgi; - const CgiEnvInput * cgienv; - - private: - const Glib::ustring & platform() const; - - public: - INITOPTIONS; - static boost::intrusive_ptr<HostnamePlatformIdentifier> hpi; - static std::string dumpdatadoc; - static Glib::ustring errorContentType; - static Glib::ustring errorTransformStyle; - static std::string defaultPresent; - static std::string transformContentType; - static std::string transformTargetType; - static std::string presentRoot; - static std::string requestRoot; - static std::string errorPresentRoot; - static std::string notFoundPresent; - static std::string onErrorPresent; - static std::string defaultPresenter; - static std::string sessionModule; - static std::string routerType; - typedef LazyPointer<const Router> RouterPtr; - RouterPtr router; -}; - -#endif diff --git a/project2/cgi/cgiProgRouter.cpp b/project2/cgi/cgiProgRouter.cpp index e8ae15d..8fce50d 100644 --- a/project2/cgi/cgiProgRouter.cpp +++ b/project2/cgi/cgiProgRouter.cpp @@ -1,7 +1,10 @@ #include <pch.hpp> #include <boost/foreach.hpp> +#include <boost/filesystem/path.hpp> #include <boost/algorithm/string/predicate.hpp> -#include "cgiEnvironment.h" +#include "cgiRequestContext.h" +#include "commonObjects.h" +#include "rowProcessor.h" #include "presenter.h" #include "safeMapFind.h" #include "scriptStorage.h" @@ -82,8 +85,8 @@ class RoutingTable { public: Route(ScriptNodePtr s) : SourceObject(s), - present(s->value("present").as<std::string>()), - path(s->value("path").as<std::string>()) + present(s->value("present", NULL).as<std::string>()), + path(s->value("path", NULL).as<std::string>()) { boost::filesystem::path fspath = path; boost::filesystem::path::iterator p = fspath.begin(); @@ -204,14 +207,14 @@ class Routes : public RowSet { mutable Columns columns; friend class Routes; }; - void execute(const Glib::ustring & filter, const RowProcessor * rp) const + void execute(const Glib::ustring & filter, const RowProcessorCallback & rp, ExecContext *) const { RouteRowState rs; BOOST_FOREACH(const auto & r, ProgRouterLoader::routingTable.routes) { if (boost::algorithm::starts_with(r->path, filter)) { rs.fields[0] = VariableType(r->present); rs.fields[1] = VariableType(r->path); - rs.process(rp); + rp(&rs); } } } diff --git a/project2/cgi/cgiRequestContext.cpp b/project2/cgi/cgiRequestContext.cpp new file mode 100644 index 0000000..5a93243 --- /dev/null +++ b/project2/cgi/cgiRequestContext.cpp @@ -0,0 +1,161 @@ +#include <pch.hpp> +#include <boost/bind.hpp> +#include <boost/foreach.hpp> +#include <boost/algorithm/string.hpp> +#include "cgiRequestContext.h" +#include "cgiAppEngine.h" +#include "exceptions.h" +#include <map> +#include <cgicc/Cgicc.h> +#include <glibmm/regex.h> +#include <curl/curl.h> +#include <boost/uuid/uuid_io.hpp> +#include <boost/uuid/uuid_generators.hpp> + +CgiRequestContext::CgiRequestContext(cgicc::CgiInput * i, const CgiEnvInput & e) : + cgi(i), + router(boost::bind(&RouterLoader::create, boost::cref(CgiApplicationEngine::router), getRedirectURL())), + cgienv(e), + session(boost::bind(&CgiRequestContext::getSessionInternal, this)) +{ +} + +CgiRequestContext::~CgiRequestContext() +{ +} + +SessionPtr +CgiRequestContext::getSession() const +{ + return session; +} + +SessionPtr +CgiRequestContext::getSessionInternal() const +{ + try { + return CgiApplicationEngine::sessionsContainer->GetSession(boost::uuids::string_generator()(getCookieValue(CgiApplicationEngine::sessionCookie))); + } + catch (const NoSuchCookie &) { + return CgiApplicationEngine::sessionsContainer->GetSession(boost::uuids::uuid()); + } +} + +std::string +CgiRequestContext::getCookieValue(const std::string & name) const +{ + BOOST_FOREACH(const cgicc::HTTPCookie & c, cgi.getEnvironment().getCookieList()) { + if (c.getName() == name) { + return c.getValue(); + } + } + throw NoSuchCookie(name); +} + +std::string +CgiRequestContext::getRequestMethod() const +{ + return cgi.getEnvironment().getRequestMethod(); +} + +std::string +CgiRequestContext::getRedirectURL() const +{ + return cgi.getEnvironment().getRedirectURL(); +} + +std::string +CgiRequestContext::getServerName() const +{ + return cgi.getEnvironment().getServerName(); +} + +std::string +CgiRequestContext::getAccept() const +{ + return cgi.getEnvironment().getAccept(); +} + +CgiRequestContext::ETags +CgiRequestContext::getRequestETags() const +{ + const std::string e = cgienv.getenv("HTTP_IF_NONE_MATCH"); + ETags etags; + boost::split(etags, e, boost::is_any_of(" ,"), boost::algorithm::token_compress_on); + return etags; +} + +time_t +CgiRequestContext::getRequestModifiedSince() const +{ + return curl_getdate(cgienv.getenv("HTTP_IF_MODIFIED_SINCE").c_str(), NULL); +} + +Glib::ustring +CgiRequestContext::getParamUri(VariableType p) const +{ + return router->routeParameter(p); +} + +unsigned int +CgiRequestContext::getParamUriCount() const +{ + return router->parameterCount(); +} + +void +CgiRequestContext::applyAllParameters(const boost::function<void (const std::string &, const std::string &)> & func) const +{ + BOOST_FOREACH(const auto & f, cgi.getElements()) { + func(f.getName(), f.getValue()); + } +} + +VariableType +CgiRequestContext::getParameter(const VariableType & p) const +{ + cgicc::const_form_iterator i = cgi.getElement(p); + if (i == cgi.getElements().end()) { + throw ParamNotFound(p); + } + return cgi(p); +} + +HostnamePlatformIdentifier::HostnamePlatformIdentifier() +{ +} + +HostnamePlatformIdentifier::~HostnamePlatformIdentifier() +{ +} + +const Glib::ustring & +HostnamePlatformIdentifier::derivedPlatform(CgiRequestContext * crc) const +{ + auto pi = std::find_if(platHosts.begin(), platHosts.end(), [crc](const PlatformHostname & r) -> bool { + return r.second->match(crc->getServerName()); + }); + if (pi == platHosts.end()) { + throw NoSuchPlatform(crc->getServerName()); + } + return pi->first; +} + +void +HostnamePlatformIdentifier::reset() const +{ + platHosts.clear(); +} + +bool +HostnamePlatformIdentifier::paramRequired() const +{ + return true; +} + +void +HostnamePlatformIdentifier::consume(const Glib::ustring & p, const VariableType & r, const Options::CurrentPlatform &) const +{ + platHosts.push_back(PlatformHostname(p, Glib::Regex::create(r, Glib::REGEX_CASELESS | Glib::REGEX_DOTALL))); +} + diff --git a/project2/cgi/cgiRequestContext.h b/project2/cgi/cgiRequestContext.h new file mode 100644 index 0000000..1dbc613 --- /dev/null +++ b/project2/cgi/cgiRequestContext.h @@ -0,0 +1,68 @@ +#ifndef ENVPROC_H +#define ENVPROC_H + +#include <string> +#include <vector> +#include "cgiEnvInput.h" +#include "cgiRouter.h" +#include "execContext.h" +#include <cgicc/CgiEnvironment.h> +#include <cgicc/Cgicc.h> +#include <lazyPointer.h> +#include <glibmm/refptr.h> + +SimpleMessageException(NoSuchCookie); + +class CgiRequestContext; +namespace Glib { + class Regex; +} + +class HostnamePlatformIdentifier : public Options::Target { + public: + HostnamePlatformIdentifier(); + virtual ~HostnamePlatformIdentifier(); + void reset() const; + bool paramRequired() const; + void consume(const Glib::ustring &, const VariableType &, const Options::CurrentPlatform &) const; + const Glib::ustring & derivedPlatform(CgiRequestContext *) const; + private: + typedef std::pair<Glib::ustring, Glib::RefPtr<Glib::Regex>> PlatformHostname; + typedef std::vector<PlatformHostname> PlatformHostnameList; + mutable PlatformHostnameList platHosts; +}; + +class CgiRequestContext : public ExecContext { + public: + typedef std::string ETag; + typedef std::vector<ETag> ETags; + + CgiRequestContext(cgicc::CgiInput *, const CgiEnvInput & cgienv); + virtual ~CgiRequestContext(); + + const cgicc::Cgicc cgi; + + Glib::ustring getParamUri(VariableType idx) const; + unsigned int getParamUriCount() const; + VariableType getParameter(const VariableType & idx) const; + void applyAllParameters(const boost::function<void (const std::string &, const std::string &)> &) const; + SessionPtr getSession() const; + std::string getServerName() const; + std::string getRedirectURL() const; + std::string getRequestMethod() const; + std::string getAccept() const; + ETags getRequestETags() const; + time_t getRequestModifiedSince() const; + std::string getCookieValue(const std::string & name) const; + LazyPointer<Router> router; + + boost::posix_time::ptime startTime; + boost::posix_time::ptime endTime; + + private: + const CgiEnvInput & cgienv; + LazyPointer<Session> session; + SessionPtr getSessionInternal() const; +}; + +#endif diff --git a/project2/cgi/cgiRequestID.cpp b/project2/cgi/cgiRequestID.cpp index da8ad6a..60baa1e 100644 --- a/project2/cgi/cgiRequestID.cpp +++ b/project2/cgi/cgiRequestID.cpp @@ -1,9 +1,8 @@ #include <pch.hpp> #include <variables.h> -#include "cgiEnvironment.h" +#include "cgiRequestContext.h" #include <scriptLoader.h> #include <scriptStorage.h> -#include <appEngine.h> #include <gcrypt.h> #include <scopeObject.h> #include <iomanip> @@ -16,16 +15,16 @@ class CgiRequestID : public VariableImplDyn { { } - VariableType value() const + VariableType value(ExecContext * ec) const { gcry_md_hd_t state; gcry_md_open(&state, GCRY_MD_SHA1, 0); ScopeObject gcryClose([&state] { gcry_md_close(state); }); - auto _env = static_cast<const CgiEnvironment *>(ApplicationEngine::getCurrent()->env()); - gcryApplyString(state, _env->getRedirectURL()); + auto crc = static_cast<const CgiRequestContext *>(ec); + gcryApplyString(state, crc->getRedirectURL()); - _env->applyAllParameters([&state,this](const std::string & name, const std::string & value) { + crc->applyAllParameters([&state, this](const std::string & name, const std::string & value) { gcryApplyString(state, name); gcryApplyString(state, value); }); diff --git a/project2/cgi/cgiResultStatic.cpp b/project2/cgi/cgiResultStatic.cpp index b5fecd7..ab4ff43 100644 --- a/project2/cgi/cgiResultStatic.cpp +++ b/project2/cgi/cgiResultStatic.cpp @@ -4,7 +4,7 @@ class StaticToCgiResult : public TransformImpl<StaticContent, CgiResult> { public: - void transform(const StaticContent * sc, CgiResult * cr) const { + void transform(const StaticContent * sc, CgiResult * cr, ExecContext *) const { cr->header->addHeader("Content-Type", Glib::ustring::compose("%1; charset=%2", sc->getContentType(), sc->getEncoding())); cr->header->addHeader("Content-Length", Glib::ustring::compose("%1", sc->getSizeInBytes())); char buf[100]; diff --git a/project2/cgi/cgiResultWritable.cpp b/project2/cgi/cgiResultWritable.cpp index ea17d3b..357a57c 100644 --- a/project2/cgi/cgiResultWritable.cpp +++ b/project2/cgi/cgiResultWritable.cpp @@ -3,11 +3,11 @@ class WritableToCgiResult : public TransformImpl<WritableContent, CgiResult> { public: - void transform(const WritableContent * wc, CgiResult * cr) const { + void transform(const WritableContent * wc, CgiResult * cr, ExecContext * ec) const { cr->header->addHeader("Content-Type", Glib::ustring::compose("%1; charset=%2", wc->getContentType(), cr->encoding)); cr->header->addHeader("Cache-control", "no-cache"); cr->header->render(cr->stream); - wc->writeTo(cr->stream, cr->encoding); + wc->writeTo(cr->stream, cr->encoding, ec); } }; DECLARE_TRANSFORM(WritableToCgiResult); diff --git a/project2/cgi/cgiRouter.h b/project2/cgi/cgiRouter.h index dd9c0e6..4a88b19 100644 --- a/project2/cgi/cgiRouter.h +++ b/project2/cgi/cgiRouter.h @@ -14,6 +14,7 @@ class Router : public IntrusivePtrBase { virtual unsigned int parameterCount() const = 0; virtual void present(const MultiRowSetPresenter * p) const = 0; }; +typedef boost::intrusive_ptr<Router> RouterPtr; typedef GenLoader<Router, const std::string &> RouterLoader; #endif diff --git a/project2/cgi/cgiSimpleRouter.cpp b/project2/cgi/cgiSimpleRouter.cpp index cd14c53..b67848e 100644 --- a/project2/cgi/cgiSimpleRouter.cpp +++ b/project2/cgi/cgiSimpleRouter.cpp @@ -1,4 +1,4 @@ -#include "cgiEnvironment.h" +#include "cgiRequestContext.h" #include <boost/filesystem/path.hpp> #include "scriptLoader.h" #include "presenter.h" diff --git a/project2/cgi/cgiStageCacheHit.cpp b/project2/cgi/cgiStageCacheHit.cpp index d398e8f..d74c02f 100644 --- a/project2/cgi/cgiStageCacheHit.cpp +++ b/project2/cgi/cgiStageCacheHit.cpp @@ -1,6 +1,6 @@ #include <pch.hpp> #include "cgiAppEngine.h" -#include "cgiEnvironment.h" +#include "cgiRequestContext.h" #include "cgiHttpHeader.h" #include <boost/foreach.hpp> #include <boost/bind.hpp> @@ -12,13 +12,13 @@ CgiApplicationEngine::CacheHitStage::CacheHitStage(ScriptNodePtr s, PresenterCac } CgiApplicationEngine::NextStage -CgiApplicationEngine::CacheHitStage::run() +CgiApplicationEngine::CacheHitStage::run(CgiRequestContext *) { return NextStage(NULL, this, pc, NULL); } CgiApplicationEngine::HttpHeaderPtr -CgiApplicationEngine::CacheHitStage::getHeader() const +CgiApplicationEngine::CacheHitStage::getHeader(CgiRequestContext *) const { return HttpHeaderPtr(new Project2HttpHeader("200 OK")); } diff --git a/project2/cgi/cgiStageCustomError.cpp b/project2/cgi/cgiStageCustomError.cpp index 56739fd..e38c7ec 100644 --- a/project2/cgi/cgiStageCustomError.cpp +++ b/project2/cgi/cgiStageCustomError.cpp @@ -1,28 +1,28 @@ #include <pch.hpp> #include "cgiAppEngine.h" -#include "cgiEnvironment.h" +#include "cgiRequestContext.h" #include "cgiHttpHeader.h" #include "logger.h" -CgiApplicationEngine::CustomErrorStage::CustomErrorStage(const std::exception & ex, ScriptReaderPtr s) : +CgiApplicationEngine::CustomErrorStage::CustomErrorStage(const std::exception & ex, ScriptReaderPtr s, CgiRequestContext * crc) : CgiApplicationEngine::ResponseStage(s->root()), ::CommonObjects(s->root()), ::CheckHost(s->root()), - CgiApplicationEngine::DefaultErrorStage(ex), - CgiApplicationEngine::PresentStage(s) + CgiApplicationEngine::DefaultErrorStage(ex, crc), + CgiApplicationEngine::PresentStage(s, crc) { } CgiApplicationEngine::HttpHeaderPtr -CgiApplicationEngine::CustomErrorStage::getHeader() const +CgiApplicationEngine::CustomErrorStage::getHeader(CgiRequestContext * ec) const { - return CgiApplicationEngine::DefaultErrorStage::getHeader(); + return CgiApplicationEngine::DefaultErrorStage::getHeader(ec); } CgiApplicationEngine::NextStage -CgiApplicationEngine::CustomErrorStage::run() +CgiApplicationEngine::CustomErrorStage::run(CgiRequestContext * crc) { - CgiApplicationEngine::DefaultErrorStage::run(); - return CgiApplicationEngine::PresentStage::run(); + CgiApplicationEngine::DefaultErrorStage::run(crc); + return CgiApplicationEngine::PresentStage::run(crc); } diff --git a/project2/cgi/cgiStageCustomNotFound.cpp b/project2/cgi/cgiStageCustomNotFound.cpp index 872da77..48fbf64 100644 --- a/project2/cgi/cgiStageCustomNotFound.cpp +++ b/project2/cgi/cgiStageCustomNotFound.cpp @@ -1,28 +1,28 @@ #include <pch.hpp> #include "cgiAppEngine.h" -#include "cgiEnvironment.h" +#include "cgiRequestContext.h" #include "cgiHttpHeader.h" #include "logger.h" -CgiApplicationEngine::CustomNotFoundStage::CustomNotFoundStage(const ScriptNotFound & notfound, ScriptReaderPtr s) : +CgiApplicationEngine::CustomNotFoundStage::CustomNotFoundStage(const ScriptNotFound & notfound, ScriptReaderPtr s, CgiRequestContext * crc) : CgiApplicationEngine::ResponseStage(s->root()), ::CommonObjects(s->root()), ::CheckHost(s->root()), CgiApplicationEngine::DefaultNotFoundStage(notfound), - CgiApplicationEngine::PresentStage(s) + CgiApplicationEngine::PresentStage(s, crc) { } CgiApplicationEngine::HttpHeaderPtr -CgiApplicationEngine::CustomNotFoundStage::getHeader() const +CgiApplicationEngine::CustomNotFoundStage::getHeader(CgiRequestContext * crc) const { - return CgiApplicationEngine::DefaultNotFoundStage::getHeader(); + return CgiApplicationEngine::DefaultNotFoundStage::getHeader(crc); } CgiApplicationEngine::NextStage -CgiApplicationEngine::CustomNotFoundStage::run() +CgiApplicationEngine::CustomNotFoundStage::run(CgiRequestContext * crc) { - CgiApplicationEngine::DefaultNotFoundStage::run(); - return CgiApplicationEngine::PresentStage::run(); + CgiApplicationEngine::DefaultNotFoundStage::run(crc); + return CgiApplicationEngine::PresentStage::run(crc); } diff --git a/project2/cgi/cgiStageDefaultError.cpp b/project2/cgi/cgiStageDefaultError.cpp index 4c3eefe..d230a21 100644 --- a/project2/cgi/cgiStageDefaultError.cpp +++ b/project2/cgi/cgiStageDefaultError.cpp @@ -2,22 +2,22 @@ #include "cgiAppEngine.h" #include "cgiHttpHeader.h" #include "logger.h" -#include "cgiEnvironment.h" +#include "cgiRequestContext.h" #include <cxxabi.h> static const Glib::ustring DefaultErrorStageResp("error"); -CgiApplicationEngine::DefaultErrorStage::DefaultErrorStage(const std::exception & ex) : +CgiApplicationEngine::DefaultErrorStage::DefaultErrorStage(const std::exception & ex, CgiRequestContext * crc) : CgiApplicationEngine::ResponseStage(NULL), buf(__cxxabiv1::__cxa_demangle(typeid(ex).name(), NULL, NULL, NULL)), what(ex.what()), - pres(new XmlPresenter(DefaultErrorStageResp, env()->errorTransformStyle, env()->errorContentType)) + pres(new XmlPresenter(DefaultErrorStageResp, CgiApplicationEngine::errorTransformStyle, CgiApplicationEngine::errorContentType)) { auto xp = dynamic_cast<TransformSource *>(pres.get()); auto cp = dynamic_cast<ContentPresenter *>(pres.get()); - if (xp && cp && cp->contentType == this->env()->transformContentType) { - auto h = TransformTargetLoader::getFor(this->env()->transformTargetType)->create(root, Default); - xp->addTarget(h, root); + if (xp && cp && cp->contentType == CgiApplicationEngine::transformContentType) { + auto h = TransformTargetLoader::getFor(CgiApplicationEngine::transformTargetType)->create(root, Default); + xp->addTarget(h, crc, root); } } @@ -27,15 +27,15 @@ CgiApplicationEngine::DefaultErrorStage::~DefaultErrorStage() } CgiApplicationEngine::HttpHeaderPtr -CgiApplicationEngine::DefaultErrorStage::getHeader() const +CgiApplicationEngine::DefaultErrorStage::getHeader(CgiRequestContext *) const { return HttpHeaderPtr(new Project2HttpHeader("500 Internal Server Error")); } CgiApplicationEngine::NextStage -CgiApplicationEngine::DefaultErrorStage::run() +CgiApplicationEngine::DefaultErrorStage::run(CgiRequestContext * crc) { - pres->init(); + pres->init(crc); pres->addNamedValue("error-type", Scripts::scriptNamespacePrefix, buf); pres->addNamedValue("error-what", Scripts::scriptNamespacePrefix, what.c_str()); return NextStage(NULL, this, pres.get(), pres.get()); diff --git a/project2/cgi/cgiStageDefaultNotFound.cpp b/project2/cgi/cgiStageDefaultNotFound.cpp index e497058..bfb737f 100644 --- a/project2/cgi/cgiStageDefaultNotFound.cpp +++ b/project2/cgi/cgiStageDefaultNotFound.cpp @@ -1,6 +1,6 @@ #include <pch.hpp> #include "cgiAppEngine.h" -#include "cgiEnvironment.h" +#include "cgiRequestContext.h" #include "cgiHttpHeader.h" #include "logger.h" @@ -9,21 +9,21 @@ static const Glib::ustring DefaultNotFoundStageResp("notfound"); CgiApplicationEngine::DefaultNotFoundStage::DefaultNotFoundStage(const ScriptNotFound & notfound) : CgiApplicationEngine::ResponseStage(NULL), nf(notfound), - pres(new XmlPresenter(DefaultNotFoundStageResp, env()->errorTransformStyle, env()->errorContentType)) + pres(new XmlPresenter(DefaultNotFoundStageResp, CgiApplicationEngine::errorTransformStyle, CgiApplicationEngine::errorContentType)) { Logger()->messagef(LOG_ERR, "%s: Resource not found: %s", __FUNCTION__, nf.what()); } CgiApplicationEngine::HttpHeaderPtr -CgiApplicationEngine::DefaultNotFoundStage::getHeader() const +CgiApplicationEngine::DefaultNotFoundStage::getHeader(CgiRequestContext *) const { return HttpHeaderPtr(new Project2HttpHeader("404 Not found")); } CgiApplicationEngine::NextStage -CgiApplicationEngine::DefaultNotFoundStage::run() +CgiApplicationEngine::DefaultNotFoundStage::run(CgiRequestContext * crc) { - pres->init(); + pres->init(crc); pres->addNamedValue("missing-resource", Scripts::scriptNamespacePrefix, nf.what()); return NextStage(NULL, this, pres.get(), pres.get()); } diff --git a/project2/cgi/cgiStageFail.cpp b/project2/cgi/cgiStageFail.cpp index 019ab8e..461c8a7 100644 --- a/project2/cgi/cgiStageFail.cpp +++ b/project2/cgi/cgiStageFail.cpp @@ -1,7 +1,7 @@ #include <pch.hpp> #include <boost/lexical_cast.hpp> #include "cgiAppEngine.h" -#include "cgiEnvironment.h" +#include "cgiRequestContext.h" #include "cgiHttpHeader.h" #include "logger.h" @@ -14,13 +14,13 @@ namespace CgiApplicationExtras { message(m) { } - CgiApplicationEngine::HttpHeaderPtr getHeader() const + CgiApplicationEngine::HttpHeaderPtr getHeader(CgiRequestContext *) const { Project2HttpHeader * header = new Project2HttpHeader(boost::lexical_cast<std::string>(code) + " " + message); return CgiApplicationEngine::HttpHeaderPtr(header); } - CgiApplicationEngine::NextStage run() + CgiApplicationEngine::NextStage run(CgiRequestContext *) { return CgiApplicationEngine::NextStage(NULL, this, NULL, NULL); } @@ -37,9 +37,9 @@ namespace CgiApplicationExtras { code(e, "code", 500), message(e, "message", "Application error") { } - void execute(const MultiRowSetPresenter *) const { + void execute(const MultiRowSetPresenter *, ExecContext * ec) const { throw CgiApplicationEngine::ResponseStagePtr( - new FailStage(code(), message())); + new FailStage(code(ec), message(ec))); } private: Variable code, message; diff --git a/project2/cgi/cgiStageInitial.cpp b/project2/cgi/cgiStageInitial.cpp index d5fe424..1326af8 100644 --- a/project2/cgi/cgiStageInitial.cpp +++ b/project2/cgi/cgiStageInitial.cpp @@ -1,17 +1,18 @@ #include <pch.hpp> #include "cgiAppEngine.h" -#include "cgiEnvironment.h" +#include "cgiRequestContext.h" #include "exceptions.h" CgiApplicationEngine::NextStage -CgiApplicationEngine::InitialStage::run() +CgiApplicationEngine::InitialStage::run(CgiRequestContext * crc) { - const CgiEnvironment * e = env(); - if (e->getRequestMethod() == "POST") { - return NextStage(new RequestStage(ScriptReader::resolveScript(e->requestRoot, e->router->route(), false))); + if (crc->getRequestMethod() == "POST") { + return NextStage(new RequestStage(ScriptReader::resolveScript(CgiApplicationEngine::requestRoot, + crc->router->route(), false))); } else { - return NextStage(new PresentStage(ScriptReader::resolveScript(e->presentRoot, e->router->isDefault() ? e->defaultPresent : e->router->route(), false))); + return NextStage(new PresentStage(ScriptReader::resolveScript(CgiApplicationEngine::presentRoot, + crc->router->isDefault() ? CgiApplicationEngine::defaultPresent : crc->router->route(), false), crc)); } } diff --git a/project2/cgi/cgiStagePresent.cpp b/project2/cgi/cgiStagePresent.cpp index 90299fe..f077111 100644 --- a/project2/cgi/cgiStagePresent.cpp +++ b/project2/cgi/cgiStagePresent.cpp @@ -1,41 +1,41 @@ #include <pch.hpp> #include "cgiAppEngine.h" -#include "cgiEnvironment.h" +#include "cgiRequestContext.h" #include "cgiHttpHeader.h" #include "safeMapFind.h" #include <boost/foreach.hpp> #include <boost/bind.hpp> -CgiApplicationEngine::PresentStage::PresentStage(ScriptReaderPtr s) : +CgiApplicationEngine::PresentStage::PresentStage(ScriptReaderPtr s, CgiRequestContext * crc) : CgiApplicationEngine::ResponseStage(s->root()), CommonObjects(s->root()), CheckHost(s->root()), ViewHost(s->root()), - presenter([this] { - auto p = PresenterLoader::getFor(this->env()->defaultPresenter)->create(root, Default); + presenter([this, crc] { + auto p = PresenterLoader::getFor(CgiApplicationEngine::defaultPresenter)->create(root, Default, crc); auto xp = dynamic_cast<TransformSource *>(p); auto cp = dynamic_cast<ContentPresenter *>(p); - if (xp && cp && cp->contentType == this->env()->transformContentType) { - auto h = TransformTargetLoader::getFor(this->env()->transformTargetType)->create(root, Default); - xp->addTarget(h, root); + if (xp && cp && cp->contentType == CgiApplicationEngine::transformContentType) { + auto h = TransformTargetLoader::getFor(CgiApplicationEngine::transformTargetType)->create(root, Default); + xp->addTarget(h, crc, root); } return p; }) { s->loader.addLoadTarget(s->root(), Storer::into<OutputOptionsLoader>(&outputOptions)); - s->loader.addLoadTarget(s->root(), Storer::into<PresenterLoader>(&presenter, Scripted)); + s->loader.addLoadTarget(s->root(), Storer::into<PresenterLoader>(&presenter, Scripted, crc)); s->loader.addLoadTarget(s->root(), Storer::into<ElementLoader>(&caches)); } CgiApplicationEngine::NextStage -CgiApplicationEngine::PresentStage::run() +CgiApplicationEngine::PresentStage::run(CgiRequestContext * crc) { - runChecks(); + runChecks(crc); PresenterCaches backFill; - time_t reqMS = this->env()->getRequestModifiedSince(); - CgiEnvironment::ETags etags = this->env()->getRequestETags(); + time_t reqMS = crc->getRequestModifiedSince(); + CgiRequestContext::ETags etags = crc->getRequestETags(); BOOST_FOREACH(const PresenterCachePtr & pc, caches) { - if (pc->check(root->script->modifiedTime())) { + if (pc->check(root->script->modifiedTime(), crc)) { if (reqMS >= pc->getModifiedTime() && (etags.empty() || containerContains(etags, pc->getSHA1()))) { header = HttpHeaderPtr(new Project2HttpHeader("304 Not Modified")); return NextStage(NULL, this, NULL, NULL); @@ -49,7 +49,7 @@ CgiApplicationEngine::PresentStage::run() } } try { - executeViews(); + executeViews(crc); header = HttpHeaderPtr(new Project2HttpHeader("200 OK")); return NextStage(NULL, this, boost::dynamic_pointer_cast<TransformSource>(presenter), presenter); } @@ -66,7 +66,7 @@ CgiApplicationEngine::PresentStage::run() } MultiRowSetPresenterPtr -CgiApplicationEngine::PresentStage::getPresenter() const +CgiApplicationEngine::PresentStage::getPresenter(ExecContext *) const { return presenter; } @@ -77,7 +77,7 @@ CgiApplicationEngine::ResponseStage::ResponseStage(ScriptNodePtr r) : } CgiApplicationEngine::HttpHeaderPtr -CgiApplicationEngine::PresentStage::getHeader() const +CgiApplicationEngine::PresentStage::getHeader(CgiRequestContext *) const { return header; } diff --git a/project2/cgi/cgiStageRedirect.cpp b/project2/cgi/cgiStageRedirect.cpp index 4a4cd02..d6fee08 100644 --- a/project2/cgi/cgiStageRedirect.cpp +++ b/project2/cgi/cgiStageRedirect.cpp @@ -1,6 +1,6 @@ #include <pch.hpp> #include "cgiAppEngine.h" -#include "cgiEnvironment.h" +#include "cgiRequestContext.h" #include "cgiHttpHeader.h" #include "logger.h" @@ -12,14 +12,14 @@ namespace CgiApplicationExtras { url(u) { } - CgiApplicationEngine::HttpHeaderPtr getHeader() const + CgiApplicationEngine::HttpHeaderPtr getHeader(CgiRequestContext *) const { Project2HttpHeader * header = new Project2HttpHeader("301 Moved Permanently"); header->addHeader("Location", url); return CgiApplicationEngine::HttpHeaderPtr(header); } - CgiApplicationEngine::NextStage run() + CgiApplicationEngine::NextStage run(CgiRequestContext *) { return CgiApplicationEngine::NextStage(NULL, this, NULL, NULL); } @@ -34,8 +34,8 @@ namespace CgiApplicationExtras { View(e), url(e, "url") { } - void execute(const MultiRowSetPresenter *) const { - throw CgiApplicationEngine::ResponseStagePtr(new RedirectStage(url())); + void execute(const MultiRowSetPresenter *, ExecContext * ec) const { + throw CgiApplicationEngine::ResponseStagePtr(new RedirectStage(url(ec))); } private: Variable url; diff --git a/project2/cgi/cgiStageRequest.cpp b/project2/cgi/cgiStageRequest.cpp index 37faaae..78d933b 100644 --- a/project2/cgi/cgiStageRequest.cpp +++ b/project2/cgi/cgiStageRequest.cpp @@ -1,6 +1,6 @@ #include <pch.hpp> #include "cgiAppEngine.h" -#include "cgiEnvironment.h" +#include "cgiRequestContext.h" #include "cgiHttpHeader.h" #include "scriptLoader.h" #include <boost/foreach.hpp> @@ -17,26 +17,26 @@ CgiApplicationEngine::RequestStage::RequestStage(ScriptReaderPtr s) : } CgiApplicationEngine::NextStage -CgiApplicationEngine::RequestStage::run() +CgiApplicationEngine::RequestStage::run(CgiRequestContext * ec) { - runChecks(); - execute(); - if (!present().isNull()) { - return NextStage(new PresentStage(ScriptReader::resolveScript(env()->presentRoot, present(), false)), this); + runChecks(ec); + execute(ec); + if (!present(ec).isNull()) { + return NextStage(new PresentStage(ScriptReader::resolveScript(CgiApplicationEngine::presentRoot, present(ec), false), ec), this); } return NextStage(NULL, this); } CgiApplicationEngine::HttpHeaderPtr -CgiApplicationEngine::RequestStage::getHeader() const +CgiApplicationEngine::RequestStage::getHeader(CgiRequestContext * ec) const { Project2HttpHeader * header; - if (redirect().isNull()) { + if (redirect(ec).isNull()) { header = new Project2HttpHeader("200 OK"); } else { header = new Project2HttpHeader("301 Moved Permanently"); - header->addHeader("Location", redirect()); + header->addHeader("Location", redirect(ec)); } header->addHeader("Cache-control", "no-cache"); return HttpHeaderPtr(header); diff --git a/project2/cgi/cgiUriParam.cpp b/project2/cgi/cgiUriParam.cpp index c65119e..985048d 100644 --- a/project2/cgi/cgiUriParam.cpp +++ b/project2/cgi/cgiUriParam.cpp @@ -1,9 +1,8 @@ #include <pch.hpp> -#include "cgiEnvironment.h" +#include "cgiRequestContext.h" #include <variables.h> #include <scriptLoader.h> #include <scriptStorage.h> -#include <appEngine.h> /// Variable implementation to access URI path fragments class VariableUri : public VariableImplDyn { @@ -13,16 +12,16 @@ class VariableUri : public VariableImplDyn { index(e, "index") { } - VariableType value() const + VariableType value(ExecContext * ec) const { try { - return static_cast<const CgiEnvironment *>(ApplicationEngine::getCurrent()->env())->getParamUri(index()); + return static_cast<const CgiRequestContext *>(ec)->getParamUri(index(ec)); } catch (...) { if (!defaultValue) { throw; } - return (*defaultValue)(); + return (*defaultValue)(ec); } } private: diff --git a/project2/cgi/p2webCgi.cpp b/project2/cgi/p2webCgi.cpp index 1b2aa99..4f806b2 100644 --- a/project2/cgi/p2webCgi.cpp +++ b/project2/cgi/p2webCgi.cpp @@ -1,5 +1,5 @@ -#include "cgiCommon.h" -#include "scriptLoader.h" +#include "cgiAppEngine.h" +#include "optionsSource.h" #include <boost/bind.hpp> class GetEnv : public CgiEnvInput { @@ -16,9 +16,12 @@ int main(void) { Plugable::onAllComponents(boost::bind(&ComponentLoader::onBegin, _1)); - CgiEnvironment env; + CgiApplicationEngine app; GetEnv ge; - cgiServe(NULL, &env, std::cout, &ge); + CgiRequestContext crc(NULL, ge); + OptionsSource::loadSources(boost::bind(&HostnamePlatformIdentifier::derivedPlatform, boost::cref(CgiApplicationEngine::hpi), &crc)); + Plugable::onAllComponents(boost::bind(&ComponentLoader::onBefore, _1)); + app.process(std::cout, &crc); Plugable::onAllComponents(boost::bind(&ComponentLoader::onIteration, _1)); Plugable::onAllComponents(boost::bind(&ComponentLoader::onPeriodic, _1)); Plugable::onAllComponents(boost::bind(&ComponentLoader::onIdle, _1)); diff --git a/project2/cgi/p2webFCgi.cpp b/project2/cgi/p2webFCgi.cpp index 7eb631f..4320c48 100644 --- a/project2/cgi/p2webFCgi.cpp +++ b/project2/cgi/p2webFCgi.cpp @@ -1,6 +1,6 @@ -#include "cgiCommon.h" #include "FCgiIO.h" -#include "scriptLoader.h" +#include "cgiAppEngine.h" +#include "optionsSource.h" #include <boost/bind.hpp> time_t lastPeriodic = 0; @@ -40,12 +40,15 @@ main(void) fprintf(stderr, "Failed to set signal handler\n"); } alarm(60); - CgiEnvironment env; Plugable::onAllComponents(boost::bind(&ComponentLoader::onBegin, _1)); + CgiApplicationEngine app; while (FCGX_Accept_r(&request) == 0) { alarm(0); cgicc::FCgiIO IO(request); - cgiServe(&IO, &env, IO, &IO); + CgiRequestContext crc(&IO, IO); + OptionsSource::loadSources(boost::bind(&HostnamePlatformIdentifier::derivedPlatform, boost::cref(CgiApplicationEngine::hpi), &crc)); + Plugable::onAllComponents(boost::bind(&ComponentLoader::onBefore, _1)); + app.process(IO, &crc); FCGX_Finish_r(&request); Plugable::onAllComponents(boost::bind(&ComponentLoader::onIteration, _1)); if (time(NULL) > lastPeriodic + periodicDelay) { diff --git a/project2/cgi/pch.hpp b/project2/cgi/pch.hpp index df744a4..5f68b7c 100644 --- a/project2/cgi/pch.hpp +++ b/project2/cgi/pch.hpp @@ -2,14 +2,8 @@ #ifndef CGI_PCH #define CGI_PCH -#include "appEngine.h" -#include "cgiAppEngine.h" -#include "cgiCommon.h" -#include "cgiEnvironment.h" +#include "cgiRequestContext.h" #include "cgiHttpHeader.h" -#include "exceptions.h" -#include "iterate.h" -#include "logger.h" #include "scriptLoader.h" #include <boost/bind.hpp> #include <boost/foreach.hpp> diff --git a/project2/cgi/testCgi.cpp b/project2/cgi/testCgi.cpp index 9ef0079..2025594 100644 --- a/project2/cgi/testCgi.cpp +++ b/project2/cgi/testCgi.cpp @@ -3,8 +3,9 @@ #include <map> #include "options.h" #include "safeMapFind.h" -#include "cgiCommon.h" #include "../files/optionsSource.h" +#include "cgiRequestContext.h" +#include "cgiAppEngine.h" #define TESTOPT(name, def, desc) \ (name, Options::value(optStore().insert(OptStore::value_type(name, StrPtr(new std::string()))).first->second.get(), def), desc) @@ -12,8 +13,8 @@ class TestInput : public cgicc::CgiInput, public CgiEnvInput { public: class TestConfigConsumer : public ConfigConsumer { public: - void operator()(const Glib::ustring & n, const Glib::ustring & p, const Glib::ustring & v) const { - Plugable::onAll<Options>(boost::bind(&Options::consume, _1, n, p, v)); + void operator()(const Glib::ustring & n, const Glib::ustring & p, const Glib::ustring & v, const Options::CurrentPlatform & cp) const { + Plugable::onAll<Options>(boost::bind(&Options::consume, _1, n, p, v, cp)); } const Options::Option * get(const Glib::ustring &) const { return NULL; @@ -22,11 +23,13 @@ class TestInput : public cgicc::CgiInput, public CgiEnvInput { typedef boost::shared_ptr<std::string> StrPtr; typedef std::map<std::string, StrPtr> OptStore; - TestInput(int argc, char ** argv) + TestInput(int argc, char ** argv) : + crc(NULL, *this) { - OptionsSource::loadSources(); + auto cp = boost::bind(&HostnamePlatformIdentifier::derivedPlatform, boost::cref(CgiApplicationEngine::hpi), &crc); + OptionsSource::loadSources(cp); FileOptions fo(".testCgi.settings"); - fo.loadInto(TestConfigConsumer()); + fo.loadInto(TestConfigConsumer(), cp); if (argc > 1) { const char * qm = strchr(argv[1], '?'); if (qm) { @@ -51,9 +54,10 @@ class TestInput : public cgicc::CgiInput, public CgiEnvInput { } void run() { + CgiApplicationEngine app; if (urlListFile.empty()) { for (int run = 0; run < runCount; run += 1) { - cgiServe(this, &env, std::cout, this); + app.process(std::cout, &crc); } } else { @@ -63,7 +67,7 @@ class TestInput : public cgicc::CgiInput, public CgiEnvInput { std::string url; urls >> url; optStore()["REDIRECT_URL"] = StrPtr(new std::string(url)); - cgiServe(this, &env, std::cout, this); + app.process(std::cout, &crc); } } } @@ -71,7 +75,7 @@ class TestInput : public cgicc::CgiInput, public CgiEnvInput { INITOPTIONS; private: - CgiEnvironment env; + CgiRequestContext crc; static int runCount; static std::string urlListFile; static OptStore & optStore() diff --git a/project2/common/aggregate.cpp b/project2/common/aggregate.cpp index 1bb453b..ee7c871 100644 --- a/project2/common/aggregate.cpp +++ b/project2/common/aggregate.cpp @@ -17,8 +17,8 @@ SetAggregate::SetAggregate(ScriptNodePtr s) : } void -Aggregate::pushValue() const +Aggregate::pushValue(ExecContext * ec) const { - pushValue(value()); + pushValue(value(ec), ec); } diff --git a/project2/common/aggregate.h b/project2/common/aggregate.h index 0641c6e..7f33b6b 100644 --- a/project2/common/aggregate.h +++ b/project2/common/aggregate.h @@ -10,9 +10,9 @@ class Aggregate : public SourceObject { Aggregate(ScriptNodePtr); virtual void reset() const = 0; - void pushValue() const; + void pushValue(ExecContext * ec) const; protected: - virtual void pushValue(const VariableType &) const = 0; + virtual void pushValue(const VariableType &, ExecContext *) const = 0; private: Variable value; }; diff --git a/project2/common/appEngine.cpp b/project2/common/appEngine.cpp deleted file mode 100644 index ce71153..0000000 --- a/project2/common/appEngine.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include <pch.hpp> -#include "appEngine.h" -#include "logger.h" -#include "presenter.h" -#include <stdexcept> -#include <boost/foreach.hpp> - -ApplicationEngine * ApplicationEngine::currentEngine = NULL; - -ApplicationEngine::ApplicationEngine() -{ - if (currentEngine) { - throw std::runtime_error("One application at a time, please"); - } - currentEngine = this; -} - -ApplicationEngine::~ApplicationEngine() -{ - currentEngine = NULL; -} - -void -ApplicationEngine::logMessage(bool writeLog, const Glib::ustring & g, const Glib::ustring & m) -{ - if (writeLog) { - Logger()->messagebf(LOG_NOTICE, "%s: %s: %s", __PRETTY_FUNCTION__, g, m); - } - appMessages.push_back(new Message(g, m)); -} - -void -ApplicationEngine::addCoreAppData(const MultiRowSetPresenter * p) const -{ - // Message log - p->addNewRowSet("messages", Scripts::scriptNamespacePrefix); - p->addNewArray("message", true); - BOOST_FOREACH(const Messages::value_type & m, appMessages) { - p->addNewRow("message"); - p->addAttribute("group", m->group); - p->addAttribute("text", m->message); - p->finishRow(); - } - p->finishArray(true); - p->finishRowSet(); -} - -ApplicationEngine::Message::Message(const Glib::ustring & g, const Glib::ustring & m) : - group(g), - message(m) -{ -} - diff --git a/project2/common/appEngine.h b/project2/common/appEngine.h deleted file mode 100644 index 6de21e1..0000000 --- a/project2/common/appEngine.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef APPENGINE_H -#define APPENGINE_H - -#include "environment.h" -#include "session.h" - -class MultiRowSetPresenter; - -class ApplicationEngine { - public: - class Message : public IntrusivePtrBase { - public: - Message(const Glib::ustring & g, const Glib::ustring & m); - - const Glib::ustring group; - const Glib::ustring message; - }; - typedef boost::intrusive_ptr<Message> MessagePtr; - typedef std::list<MessagePtr> Messages; - - ApplicationEngine(); - virtual ~ApplicationEngine() = 0; - - void logMessage(bool writeLog, const Glib::ustring & g, const Glib::ustring & m); - - virtual void process() const = 0; - virtual const Environment * env() const = 0; - virtual SessionPtr session() const = 0; - - static ApplicationEngine * getCurrent() { return currentEngine; } - - protected: - void addCoreAppData(const MultiRowSetPresenter * p) const; - - Messages appMessages; - - private: - static ApplicationEngine * currentEngine; -}; - -#endif - diff --git a/project2/common/cache.cpp b/project2/common/cache.cpp index 9be5845..2a1d410 100644 --- a/project2/common/cache.cpp +++ b/project2/common/cache.cpp @@ -9,17 +9,17 @@ Cache::Cache(ScriptNodePtr p) : IHaveParameters(p), SourceObject(p), - inherit(p->value("inherit", true).as<bool>()) + inherit(p->value("inherit", true, NULL).as<bool>()) { } -bool Cache::checkAndExecute(const Glib::ustring & n, const Glib::ustring & f, const RowProcessor * rp) +bool Cache::checkAndExecute(ExecContext * ec, const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * p, const RowProcessorCallback & rp) { - RowSetCPtr cached = getCachedRowSet(n, f, rp); + RowSetCPtr cached = getCachedRowSet(ec, n, f, p); if (cached) { try { Logger()->messagebf(LOG_DEBUG, "Executing from cache '%s'", name); - cached->execute(f, rp); + cached->execute(f, rp, ec); return true; } catch (const Glib::Exception & e) { @@ -36,14 +36,14 @@ bool Cache::checkAndExecute(const Glib::ustring & n, const Glib::ustring & f, co } void -Cache::applyKeys(const boost::function2<void, const std::string &, const VariableType &> & f, const IHaveParameters * ps) const +Cache::applyKeys(ExecContext * ec, const KeyApplier & f, const IHaveParameters * ps) const { BOOST_FOREACH(const IHaveParameters::Parameters::value_type & p, allParameters()) { - f(p.first, p.second); + f(p.first, p.second(ec)); } if (inherit) { BOOST_FOREACH(const IHaveParameters::Parameters::value_type & p, ps->allParameters()) { - f(p.first, p.second); + f(p.first, p.second(ec)); } } } diff --git a/project2/common/cache.h b/project2/common/cache.h index 2c438b8..0806c6f 100644 --- a/project2/common/cache.h +++ b/project2/common/cache.h @@ -4,8 +4,8 @@ #include "sourceObject.h" #include "presenter.h" #include "iHaveParameters.h" +#include "rowSet.h" -class RowProcessor; class RowSet; class RowState; typedef boost::intrusive_ptr<const RowSet> RowSetCPtr; @@ -14,14 +14,15 @@ class Cache : public IHaveParameters, public SourceObject { public: Cache(ScriptNodePtr p); - bool checkAndExecute(const Glib::ustring &, const Glib::ustring &, const RowProcessor *); - virtual RowSetPresenterPtr openFor(const Glib::ustring &, const Glib::ustring &, const IHaveParameters *) = 0; - virtual void save(const Glib::ustring &, const Glib::ustring &, const IHaveParameters *) = 0; - virtual void discard(const Glib::ustring &, const Glib::ustring &, const IHaveParameters *) = 0; + bool checkAndExecute(ExecContext *, const Glib::ustring &, const Glib::ustring &, const IHaveParameters *, const RowProcessorCallback &); + virtual RowSetPresenterPtr openFor(ExecContext *, const Glib::ustring &, const Glib::ustring &, const IHaveParameters *) = 0; + virtual void save(ExecContext *, const Glib::ustring &, const Glib::ustring &, const IHaveParameters *) = 0; + virtual void discard(ExecContext *, const Glib::ustring &, const Glib::ustring &, const IHaveParameters *) = 0; protected: - virtual RowSetCPtr getCachedRowSet(const Glib::ustring &, const Glib::ustring &, const IHaveParameters *) const = 0; - void applyKeys(const boost::function2<void, const std::string &, const VariableType &> & f, const IHaveParameters *) const; + virtual RowSetCPtr getCachedRowSet(ExecContext *, const Glib::ustring &, const Glib::ustring &, const IHaveParameters *) const = 0; + typedef boost::function<void (const std::string &, const VariableType &)> KeyApplier; + void applyKeys(ExecContext * ec, const KeyApplier & f, const IHaveParameters * ps) const; const bool inherit; }; typedef boost::intrusive_ptr<Cache> CachePtr; diff --git a/project2/common/check.cpp b/project2/common/check.cpp index 21d17cf..d288e2f 100644 --- a/project2/common/check.cpp +++ b/project2/common/check.cpp @@ -20,11 +20,11 @@ Check::~Check() } bool -Check::performCheck() const +Check::performCheck(ExecContext * ec) const { if (!test) { throw NoTestsToPerform(); } - return test->passes(); + return test->passes(ec); } diff --git a/project2/common/check.h b/project2/common/check.h index e9f44b5..dc97f8f 100644 --- a/project2/common/check.h +++ b/project2/common/check.h @@ -5,13 +5,15 @@ #include "variables.h" #include "test.h" +class ExecContext; + /// Base class for Project2 compoments that perform checks class Check : public SourceObject { public: Check(ScriptNodePtr p); virtual ~Check(); - bool performCheck() const; + bool performCheck(ExecContext *) const; const Variable message; const Variable group; diff --git a/project2/common/checkHost.cpp b/project2/common/checkHost.cpp index 49533a9..dedea85 100644 --- a/project2/common/checkHost.cpp +++ b/project2/common/checkHost.cpp @@ -1,6 +1,6 @@ #include <pch.hpp> #include "checkHost.h" -#include "appEngine.h" +#include "execContext.h" #include <boost/foreach.hpp> CheckHost::CheckHost(ScriptNodePtr s) : @@ -14,12 +14,12 @@ CheckHost::~CheckHost() } void -CheckHost::runChecks() const +CheckHost::runChecks(ExecContext * ec) const { loadScriptComponents(); BOOST_FOREACH(const Checks::value_type & pc, checks) { - if (!pc->performCheck()) { - ApplicationEngine::getCurrent()->logMessage(false, pc->group(), pc->message()); + if (!pc->performCheck(ec)) { + ec->logMessage(false, pc->group(ec), pc->message(ec)); throw CheckFailure(pc); } } diff --git a/project2/common/checkHost.h b/project2/common/checkHost.h index edc2cd8..f404d9e 100644 --- a/project2/common/checkHost.h +++ b/project2/common/checkHost.h @@ -18,7 +18,7 @@ class CheckHost : virtual public CommonObjects { CheckHost(ScriptNodePtr script); ~CheckHost(); - void runChecks() const; + void runChecks(ExecContext *) const; typedef ANONORDEREDSTORAGEOF(Check) Checks; Checks checks; diff --git a/project2/common/commonObjects.cpp b/project2/common/commonObjects.cpp index 23f2edb..a25bb9f 100644 --- a/project2/common/commonObjects.cpp +++ b/project2/common/commonObjects.cpp @@ -1,7 +1,6 @@ #include <pch.hpp> #include "commonObjects.h" #include "safeMapFind.h" -#include "appEngine.h" #include "scriptLoader.h" CommonObjects::CommonObjects() : diff --git a/project2/common/environment.cpp b/project2/common/environment.cpp deleted file mode 100644 index 69f853c..0000000 --- a/project2/common/environment.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include <pch.hpp> -#include "environment.h" -#include "optionsSource.h" - -const Environment * Environment::currentEnv(NULL); - -Environment::Environment() -{ - currentEnv = this; -} - -Environment::~Environment() -{ - currentEnv = NULL; -} - -const Environment * -Environment::getCurrent() -{ - return currentEnv; -} - diff --git a/project2/common/environment.h b/project2/common/environment.h deleted file mode 100644 index a97255f..0000000 --- a/project2/common/environment.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef ENVIRONMENT_H -#define ENVIRONMENT_H - -#include <string> -#include <glibmm/ustring.h> -#include "exceptions.h" -#include "scripts.h" - -SimpleMessageException(NoSuchPlatform); - -class Environment { - public: - Environment(); - virtual ~Environment() = 0; - - static const Environment * getCurrent(); - - virtual Glib::ustring getParamQuery(const std::string & idx) const = 0; - - virtual std::string getServerName() const = 0; - virtual const Glib::ustring & platform() const = 0; - - private: - static const Environment * currentEnv; -}; - -#endif - diff --git a/project2/common/exceptions.h b/project2/common/exceptions.h index 38f0efa..9cdf6f0 100644 --- a/project2/common/exceptions.h +++ b/project2/common/exceptions.h @@ -67,6 +67,7 @@ SimpleMessageException(NotSupported); SimpleMessageException(FileNotReadable); SimpleMessageException(FileNotWritable); SimpleMessageException(FilterNotFound); +SimpleMessageException(NoSuchPlatform); #endif diff --git a/project2/common/execContext.cpp b/project2/common/execContext.cpp new file mode 100644 index 0000000..571b5f0 --- /dev/null +++ b/project2/common/execContext.cpp @@ -0,0 +1,36 @@ +#include "execContext.h" +#include "logger.h" +#include "presenter.h" +#include <boost/foreach.hpp> + +void +ExecContext::logMessage(bool writeLog, const Glib::ustring & g, const Glib::ustring & m) +{ + if (writeLog) { + Logger()->messagebf(LOG_NOTICE, "%s: %s: %s", __PRETTY_FUNCTION__, g, m); + } + messages.push_back(new Message(g, m)); +} + +void +ExecContext::addContextData(const MultiRowSetPresenter * p) const +{ + // Message log + p->addNewRowSet("messages", Scripts::scriptNamespacePrefix); + p->addNewArray("message", true); + BOOST_FOREACH(const Messages::value_type & m, messages) { + p->addNewRow("message"); + p->addAttribute("group", m->group); + p->addAttribute("text", m->message); + p->finishRow(); + } + p->finishArray(true); + p->finishRowSet(); +} + +ExecContext::Message::Message(const Glib::ustring & g, const Glib::ustring & m) : + group(g), + message(m) +{ +} + diff --git a/project2/common/execContext.h b/project2/common/execContext.h new file mode 100644 index 0000000..6018058 --- /dev/null +++ b/project2/common/execContext.h @@ -0,0 +1,37 @@ +#ifndef EXECCONTEXT_H +#define EXECCONTEXT_H + +#include <glibmm/ustring.h> +#include <boost/intrusive_ptr.hpp> +#include <list> +#include "variableType.h" +#include "session.h" + +class MultiRowSetPresenter; + +class ExecContext { + public: + class Message : public IntrusivePtrBase { + public: + Message(const Glib::ustring & g, const Glib::ustring & m); + + const Glib::ustring group; + const Glib::ustring message; + }; + typedef boost::intrusive_ptr<Message> MessagePtr; + typedef std::list<MessagePtr> Messages; + + virtual VariableType getParameter(const VariableType & key) const = 0; + virtual SessionPtr getSession() const = 0; + + void logMessage(bool writeLog, const Glib::ustring & g, const Glib::ustring & m); + const Messages & getMessages() const; + + void addContextData(const MultiRowSetPresenter * p) const; + + private: + Messages messages; +}; + +#endif + diff --git a/project2/common/iHaveParameters.cpp b/project2/common/iHaveParameters.cpp index f880944..1bf1362 100644 --- a/project2/common/iHaveParameters.cpp +++ b/project2/common/iHaveParameters.cpp @@ -2,7 +2,6 @@ #include "iHaveParameters.h" #include "exceptions.h" #include "safeMapFind.h" -#include "appEngine.h" #include <boost/foreach.hpp> IHaveParameters::Stack IHaveParameters::scope; @@ -19,9 +18,9 @@ IHaveParameters::~IHaveParameters() } VariableType -IHaveParameters::getParameter(const Glib::ustring & name) const +IHaveParameters::getParameter(const Glib::ustring & name, ExecContext * ec) const { - return safeMapLookup<ParamNotFound>(parameters, name); + return safeMapLookup<ParamNotFound>(parameters, name)(ec); } void @@ -37,12 +36,12 @@ IHaveParameters::pop() } VariableType -IHaveParameters::getScopedParameter(const Glib::ustring & name) +IHaveParameters::getScopedParameter(const Glib::ustring & name, ExecContext * ec) { for(Stack::const_reverse_iterator ihp = scope.rbegin(); ihp != scope.rend(); ++ihp) { Parameters::const_iterator i = (*ihp)->parameters.find(name); if (i != (*ihp)->parameters.end()) { - return i->second; + return i->second(ec); } } throw ParamNotFound(name); diff --git a/project2/common/iHaveParameters.h b/project2/common/iHaveParameters.h index 2b7ed2a..7b15289 100644 --- a/project2/common/iHaveParameters.h +++ b/project2/common/iHaveParameters.h @@ -15,8 +15,8 @@ class IHaveParameters { virtual ~IHaveParameters() = 0; const Parameters & allParameters() const; - VariableType getParameter(const Glib::ustring &) const; - static VariableType getScopedParameter(const Glib::ustring &); + VariableType getParameter(const Glib::ustring &, ExecContext *) const; + static VariableType getScopedParameter(const Glib::ustring &, ExecContext *); protected: Parameters parameters; diff --git a/project2/common/iHaveSubTasks.cpp b/project2/common/iHaveSubTasks.cpp index 78868aa..92248fb 100644 --- a/project2/common/iHaveSubTasks.cpp +++ b/project2/common/iHaveSubTasks.cpp @@ -13,10 +13,10 @@ IHaveSubTasks::~IHaveSubTasks() } void -IHaveSubTasks::run(const Tasks & tlist) const +IHaveSubTasks::run(const Tasks & tlist, ExecContext * ec) const { BOOST_FOREACH(const Tasks::value_type & t, tlist) { - t->execute(); + t->execute(ec); } } diff --git a/project2/common/iHaveSubTasks.h b/project2/common/iHaveSubTasks.h index e52a9be..d13a890 100644 --- a/project2/common/iHaveSubTasks.h +++ b/project2/common/iHaveSubTasks.h @@ -12,11 +12,11 @@ class IHaveSubTasks : public NoOutputExecute { IHaveSubTasks(const std::string & n); virtual ~IHaveSubTasks(); - virtual void execute() const = 0; + virtual void execute(ExecContext * ec) const = 0; Tasks normal; protected: - void run(const Tasks &) const; + void run(const Tasks &, ExecContext * ec) const; }; #endif diff --git a/project2/common/if.cpp b/project2/common/if.cpp index c7f790e..ed2abf6 100644 --- a/project2/common/if.cpp +++ b/project2/common/if.cpp @@ -20,31 +20,31 @@ If::If(ScriptNodePtr e) : } bool -If::passes() const +If::passes(ExecContext * ec) const { if (!test) { throw NoTestsToPerform(); } - return test->passes(); + return test->passes(ec); } void -If::execute(const MultiRowSetPresenter * presenter) const +If::execute(const MultiRowSetPresenter * presenter, ExecContext * ec) const { - if (passes()) { + if (passes(ec)) { Logger()->messagef(LOG_DEBUG, "Test passed; showing %zu views", subViews.size()); BOOST_FOREACH(const SubViews::value_type & sq, subViews) { - sq->execute(presenter); + sq->execute(presenter, ec); } } } void -If::execute() const +If::execute(ExecContext * ec) const { - if (passes()) { + if (passes(ec)) { Logger()->messagef(LOG_DEBUG, "Test passed; executing %zu tasks", normal.size()); - run(normal); + run(normal, ec); } } diff --git a/project2/common/if.h b/project2/common/if.h index 2496dc4..64f885b 100644 --- a/project2/common/if.h +++ b/project2/common/if.h @@ -10,11 +10,11 @@ class If : public IHaveSubTasks, public View { public: If(ScriptNodePtr); - virtual void execute(const MultiRowSetPresenter*) const; - virtual void execute() const; + virtual void execute(const MultiRowSetPresenter *, ExecContext *) const; + virtual void execute(ExecContext *) const; private: - bool passes() const; + bool passes(ExecContext *) const; typedef ANONSTORAGEOF(View) SubViews; SubViews subViews; diff --git a/project2/common/iterate.cpp b/project2/common/iterate.cpp index 037261d..4473885 100644 --- a/project2/common/iterate.cpp +++ b/project2/common/iterate.cpp @@ -27,22 +27,16 @@ Iterate::loadComplete(const CommonObjects * co) } void -Iterate::rowReady(const RowState *) const +Iterate::execute(ExecContext * ec) const { - executeChildren(); + RowProcessor::execute(ec, boost::bind(&Iterate::executeChildren, this, ec)); } void -Iterate::execute() const -{ - RowProcessor::execute(); -} - -void -Iterate::executeChildren() const +Iterate::executeChildren(ExecContext * ec) const { BOOST_FOREACH(const Tasks::value_type & sq, normal) { - sq->execute(); + sq->execute(ec); } } diff --git a/project2/common/iterate.h b/project2/common/iterate.h index 540cec6..2afbe98 100644 --- a/project2/common/iterate.h +++ b/project2/common/iterate.h @@ -15,11 +15,10 @@ class Iterate : public IHaveSubTasks, public RowProcessor { virtual ~Iterate(); void loadComplete(const CommonObjects *); - void rowReady(const RowState *) const; - void execute() const; + void execute(ExecContext *) const; protected: - void executeChildren() const; + void executeChildren(ExecContext *) const; }; #endif diff --git a/project2/common/library.cpp b/project2/common/library.cpp index 4762211..738803f 100644 --- a/project2/common/library.cpp +++ b/project2/common/library.cpp @@ -11,7 +11,7 @@ SimpleMessageException(UnloadLibraryFailed); Library::Library(ScriptNodePtr p) : SourceObject(p), - handle(dlopen(Variable(p, "path")(), RTLD_NOW)) + handle(dlopen(Variable(p, "path")(NULL), RTLD_NOW)) { if (!handle) { throw LoadLibraryFailed(dlerror()); diff --git a/project2/common/memoryCache.cpp b/project2/common/memoryCache.cpp index 0a4f53f..7ab271e 100644 --- a/project2/common/memoryCache.cpp +++ b/project2/common/memoryCache.cpp @@ -43,7 +43,7 @@ class MemoryCache : public Cache { { } - void execute(const Glib::ustring&, const RowProcessor * rp) const { + void execute(const Glib::ustring&, const RowProcessorCallback & rp, ExecContext *) const { BOOST_FOREACH(const DataCache::value_type & mcr, dataCache) { mcr->process(rp, false); } @@ -100,8 +100,8 @@ class MemoryCache : public Cache { { } - RowSetCPtr getCachedRowSet(const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) const { - Key key(makeKey(n, f, ps)); + RowSetCPtr getCachedRowSet(ExecContext * ec, const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) const { + Key key(makeKey(ec, n, f, ps)); CacheStore::index<IndexByKey>::type::const_iterator i = Store.get<IndexByKey>().find(key); if (i == Store.get<IndexByKey>().end()) { return NULL; @@ -113,27 +113,27 @@ class MemoryCache : public Cache { return *i; } - RowSetPresenterPtr openFor(const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) { - return (cur = new CachedRowSet(makeKey(n, f, ps))); + RowSetPresenterPtr openFor(ExecContext * ec, const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) { + return (cur = new CachedRowSet(makeKey(ec, n, f, ps))); } - void save(const Glib::ustring & , const Glib::ustring & , const IHaveParameters * ) { + void save(ExecContext *, const Glib::ustring & , const Glib::ustring & , const IHaveParameters * ) { if (cur) { Store.insert(cur); cur.reset(); } } - void discard(const Glib::ustring & , const Glib::ustring & , const IHaveParameters * ) { + void discard(ExecContext *, const Glib::ustring & , const Glib::ustring & , const IHaveParameters * ) { cur.reset(); } private: - Key makeKey(const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) const { + Key makeKey(ExecContext * ec, const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) const { Key key; key.push_back(n); key.push_back(f); - applyKeys([&key](const std::string &, const VariableType & v) { key.push_back(v); }, ps); + applyKeys(ec, [&key](const std::string &, const VariableType & v) { key.push_back(v); }, ps); return key; } diff --git a/project2/common/noOutputExecute.h b/project2/common/noOutputExecute.h index 67f6b00..61d03b5 100644 --- a/project2/common/noOutputExecute.h +++ b/project2/common/noOutputExecute.h @@ -5,6 +5,7 @@ #include "scriptStorage.h" class NoOutputExecute; +class ExecContext; typedef boost::intrusive_ptr<NoOutputExecute> NoOutputExecutePtr; /// Base class for Project2 compoments that perform actions, but product no output @@ -15,7 +16,7 @@ class NoOutputExecute : public virtual SourceObject { virtual ~NoOutputExecute(); - virtual void execute() const = 0; + virtual void execute(ExecContext *) const = 0; }; #endif diff --git a/project2/common/options.cpp b/project2/common/options.cpp index 5c79163..fd93576 100644 --- a/project2/common/options.cpp +++ b/project2/common/options.cpp @@ -1,6 +1,5 @@ #include <pch.hpp> #include "options.h" -#include "environment.h" #include <boost/foreach.hpp> class NamedOption : public Options::Option { @@ -11,9 +10,9 @@ class NamedOption : public Options::Option { desc(d) { } - void consume(const Glib::ustring & n, const Glib::ustring & p, const VariableType & v) const { + void consume(const Glib::ustring & n, const Glib::ustring & p, const VariableType & v, const Options::CurrentPlatform & cp) const { if (n == id) { - target->consume(p, v); + target->consume(p, v, cp); } } void reset() const { @@ -44,9 +43,9 @@ class OptionAlias : public Options::Option { target(t) { } - void consume(const Glib::ustring & a, const Glib::ustring & p, const VariableType & v) const { + void consume(const Glib::ustring & a, const Glib::ustring & p, const VariableType & v, const Options::CurrentPlatform & cp) const { if (a == alias) { - target->target->consume(p, v); + target->target->consume(p, v, cp); } } void reset() const { @@ -108,10 +107,10 @@ Options::reset() const } void -Options::consume(const Glib::ustring & n, const Glib::ustring & p, const VariableType & v) const +Options::consume(const Glib::ustring & n, const Glib::ustring & p, const VariableType & v, const Options::CurrentPlatform & cp) const { BOOST_FOREACH(const OptionPtr & o, options) { - o->consume(n, p, v); + o->consume(n, p, v, cp); } } @@ -145,13 +144,13 @@ Options::InstanceTarget::paramRequired() const } void -Options::InstanceTarget::consume(const Glib::ustring & p, const VariableType & v) const +Options::InstanceTarget::consume(const Glib::ustring & p, const VariableType & v, const Options::CurrentPlatform & cp) const { if (ts != Platform && p.empty()) { assign(v); ts = Global; } - else if (!p.empty() && p == Environment::getCurrent()->platform()) { + else if (!p.empty() && p == cp) { assign(v); ts = Platform; } diff --git a/project2/common/options.h b/project2/common/options.h index e92e69b..c2416ef 100644 --- a/project2/common/options.h +++ b/project2/common/options.h @@ -15,11 +15,13 @@ class Options { class Target; enum TargetState { Default = 1, Global = 2, Platform = 3 }; + typedef boost::function<const Glib::ustring &()> CurrentPlatform; + class Target : public IntrusivePtrBase { public: virtual void reset() const = 0; virtual bool paramRequired() const = 0; - virtual void consume(const Glib::ustring & platform, const VariableType & value) const = 0; + virtual void consume(const Glib::ustring & platform, const VariableType & value, const CurrentPlatform & currentPlatform) const = 0; }; typedef boost::intrusive_ptr<Target> TargetPtr; typedef boost::function<void(const VariableType &)> Assigner; @@ -29,7 +31,7 @@ class Options { public: InstanceTarget(const Assigner &, const Resetter &); bool paramRequired() const; - void consume(const Glib::ustring & platform, const VariableType & value) const; + void consume(const Glib::ustring & platform, const VariableType & value, const CurrentPlatform & currentPlatform) const; protected: void reset() const; void assign(const VariableType & value) const; @@ -45,7 +47,7 @@ class Options { virtual Glib::ustring name() const = 0; virtual Glib::ustring description() const = 0; virtual bool accepts(const Glib::ustring & name) const = 0; - virtual void consume(const Glib::ustring & name, const Glib::ustring & platform, const VariableType & value) const = 0; + virtual void consume(const Glib::ustring & name, const Glib::ustring & platform, const VariableType & value, const CurrentPlatform & currentPlatform) const = 0; }; typedef boost::intrusive_ptr<Option> OptionPtr; typedef std::list<OptionPtr> OptionList; @@ -86,7 +88,7 @@ class Options { } void reset() const; - void consume(const Glib::ustring & name, const Glib::ustring & platform, const VariableType & value) const; + void consume(const Glib::ustring & name, const Glib::ustring & platform, const VariableType & value, const CurrentPlatform & currentPlatform) const; const Option * find(const Glib::ustring & name) const; const Glib::ustring name; diff --git a/project2/common/optionsSource.cpp b/project2/common/optionsSource.cpp index ed40df9..702b852 100644 --- a/project2/common/optionsSource.cpp +++ b/project2/common/optionsSource.cpp @@ -3,8 +3,8 @@ class DefaultConfigConsumer : public ConfigConsumer { public: - void operator()(const Glib::ustring & n, const Glib::ustring & p, const Glib::ustring & v) const { - Plugable::onAll<Options>(boost::bind(&Options::consume, _1, n, p, v)); + void operator()(const Glib::ustring & n, const Glib::ustring & p, const Glib::ustring & v, const Options::CurrentPlatform & cp) const { + Plugable::onAll<Options>(boost::bind(&Options::consume, _1, n, p, v, cp)); } const Options::Option * get(const Glib::ustring & n) const { const Options::Option * rtn = NULL; @@ -19,7 +19,7 @@ class DefaultConfigConsumer : public ConfigConsumer { }; void -OptionsSource::loadSources() +OptionsSource::loadSources(const Options::CurrentPlatform & platform) { const auto & configs = Plugable::ComponentType<OptionsSource>::components(); if (std::find_if(configs->begin(), configs->end(), boost::bind(&OptionsSource::needReload, _1)) != configs->end()) { @@ -27,7 +27,7 @@ OptionsSource::loadSources() DefaultConfigConsumer dcc; BOOST_FOREACH(const auto & c, *configs) { - c->loadInto(dcc); + c->loadInto(dcc, platform); } Plugable::onAllComponents(boost::bind(&ComponentLoader::onConfigLoad, _1)); diff --git a/project2/common/optionsSource.h b/project2/common/optionsSource.h index 49bb876..d6f41ab 100644 --- a/project2/common/optionsSource.h +++ b/project2/common/optionsSource.h @@ -9,17 +9,17 @@ class ConfigConsumer { public: - virtual void operator()(const Glib::ustring &, const Glib::ustring &, const Glib::ustring &) const = 0; + virtual void operator()(const Glib::ustring &, const Glib::ustring &, const Glib::ustring &, const Options::CurrentPlatform &) const = 0; virtual const Options::Option * get(const Glib::ustring & name) const = 0; }; /// Base class of things that load options class OptionsSource { public: - virtual void loadInto(const ConfigConsumer &) const = 0; + virtual void loadInto(const ConfigConsumer &, const Options::CurrentPlatform & platform) const = 0; virtual bool needReload() const = 0; - static void loadSources(); + static void loadSources(const Options::CurrentPlatform & platform); }; typedef boost::intrusive_ptr<OptionsSource> OptionsSourcePtr; diff --git a/project2/common/presenter.cpp b/project2/common/presenter.cpp index 1e5bbf2..4e12307 100644 --- a/project2/common/presenter.cpp +++ b/project2/common/presenter.cpp @@ -1,7 +1,6 @@ #include <pch.hpp> #include "presenter.h" #include "dataSource.h" -#include "appEngine.h" #include <boost/foreach.hpp> NameValuePairPresenter::NameValuePairPresenter() diff --git a/project2/common/presenter.h b/project2/common/presenter.h index f9069de..3ea56e7 100644 --- a/project2/common/presenter.h +++ b/project2/common/presenter.h @@ -39,7 +39,7 @@ class MultiRowSetPresenter : public RowSetPresenter { virtual void finishRowSet() const = 0; virtual void addNewArray(const Glib::ustring & name, bool objects) const = 0; virtual void finishArray(bool objects) const = 0; - virtual void init() = 0; + virtual void init(ExecContext *) = 0; virtual void finalizeContent() const; }; @@ -77,7 +77,7 @@ typedef boost::intrusive_ptr<RowSetPresenter> RowSetPresenterPtr; typedef boost::intrusive_ptr<MultiRowSetPresenter> MultiRowSetPresenterPtr; typedef boost::intrusive_ptr<NameValuePairPresenter> NameValuePairPresenterPtr; -typedef GenLoader<MultiRowSetPresenter, ScriptNodePtr, ObjectSource> PresenterLoader; +typedef GenLoader<MultiRowSetPresenter, ScriptNodePtr, ObjectSource, ExecContext *> PresenterLoader; #endif diff --git a/project2/common/presenterCache.cpp b/project2/common/presenterCache.cpp index 6ca3661..31fdc8f 100644 --- a/project2/common/presenterCache.cpp +++ b/project2/common/presenterCache.cpp @@ -4,7 +4,7 @@ PresenterCache::PresenterCache(ScriptNodePtr s) : SourceObject(s), IHaveParameters(s), - encoding(s->value("encoding", "utf-8").as<std::string>()) + encoding(s->value("encoding", "utf-8", NULL).as<std::string>()) { } @@ -15,8 +15,8 @@ PresenterCache::flushCache() class WriteToCache : public TransformImpl<WritableContent, PresenterCache> { public: - void transform(const WritableContent * wc, PresenterCache * pc) const { - wc->writeTo(pc->writeCache(wc->getContentType(), pc->encoding), pc->encoding); + void transform(const WritableContent * wc, PresenterCache * pc, ExecContext * ec) const { + wc->writeTo(pc->writeCache(wc->getContentType(), pc->encoding, ec), pc->encoding, ec); } }; DECLARE_TRANSFORM(WriteToCache); diff --git a/project2/common/presenterCache.h b/project2/common/presenterCache.h index 799181b..b0adab8 100644 --- a/project2/common/presenterCache.h +++ b/project2/common/presenterCache.h @@ -8,9 +8,9 @@ class PresenterCache : public SourceObject, public virtual TransformSource, public StaticContent, public SourceOf<StaticContent>, public IHaveParameters { public: PresenterCache(ScriptNodePtr); - virtual bool check(time_t scriptMtime) const = 0; + virtual bool check(time_t scriptMtime, ExecContext *) const = 0; - virtual std::ostream & writeCache(const std::string & ct, const std::string & encoding) = 0; + virtual std::ostream & writeCache(const std::string & ct, const std::string & encoding, ExecContext *) = 0; virtual void flushCache(); const std::string encoding; }; diff --git a/project2/common/rowProcessor.cpp b/project2/common/rowProcessor.cpp index 4e3bf1d..26ca433 100644 --- a/project2/common/rowProcessor.cpp +++ b/project2/common/rowProcessor.cpp @@ -8,10 +8,10 @@ RowProcessor::RowProcessor(ScriptNodePtr p) : IHaveParameters(p), - recordSource(p->value("source").as<std::string>()), - filter(p->value("filter", "").as<Glib::ustring>()), - CROE(p->value("cacheRowsOnError", false)), - IRSE(p->value("ignoreRowSourceError", false)) + recordSource(p->value("source", NULL).as<std::string>()), + filter(p->value("filter", "", NULL).as<Glib::ustring>()), + CROE(p->value("cacheRowsOnError", false, NULL)), + IRSE(p->value("ignoreRowSourceError", false, NULL)) { p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&caches)); p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&tests)); @@ -24,19 +24,19 @@ RowProcessor::loadComplete(const CommonObjects * co) } void -RowProcessor::execute() const +RowProcessor::execute(ExecContext * ec, const RowProcessorCallback & cb) const { IHaveParameters::push(this); ScopeObject _ihp( boost::bind(&IHaveParameters::pop), - boost::bind(&RowProcessor::saveCaches, this), - boost::bind((CROE ? &RowProcessor::saveCaches : &RowProcessor::discardCaches), this), + boost::bind(&RowProcessor::saveCaches, this, ec), + boost::bind((CROE ? &RowProcessor::saveCaches : &RowProcessor::discardCaches), this, ec), boost::bind(&TargetCaches::clear, &tc)); BOOST_FOREACH(const CachePtr & c, caches) { - if (c->checkAndExecute(source->name, filter, this)) { + if (c->checkAndExecute(ec, source->name, filter, this, cb)) { return; } - RowSetPresenterPtr p = c->openFor(source->name, filter, this); + RowSetPresenterPtr p = c->openFor(ec, source->name, filter, this); if (p) { tc.insert(TargetCachePtr(new TargetCache(p, c))); } @@ -47,44 +47,44 @@ RowProcessor::execute() const } if (IRSE) { try { - source->execute(filter, this); + source->execute(filter, cb, ec); } catch (const std::exception & e) { Logger()->messagebf(LOG_WARNING, "Source '%s' failed with '%s'", source->name, e.what()); } } else { - source->execute(filter, this); + source->execute(filter, cb, ec); } } void -RowProcessor::saveCaches() const +RowProcessor::saveCaches(ExecContext * ec) const { BOOST_FOREACH(const TargetCaches::value_type & c, tc) { - c->get<1>()->save(source->name, filter, this); + c->get<1>()->save(ec, source->name, filter, this); } } void -RowProcessor::discardCaches() const +RowProcessor::discardCaches(ExecContext * ec) const { BOOST_FOREACH(const TargetCaches::value_type & c, tc) { - c->get<1>()->discard(source->name, filter, this); + c->get<1>()->discard(ec, source->name, filter, this); } } void -RowProcessor::rowReadyInternal(const RowState * rs) const +RowProcessor::rowReadyInternal(const RowState * rs, const RowProcessorCallback & cb, ExecContext * ec) const { BOOST_FOREACH(const TargetCaches::value_type & c, tc) { c->get<0>()->addNewRow(filter.empty() ? "row" : filter); - rs->foreachColumn(boost::bind(&RowSetPresenter::addNamedValue, c->get<0>(), _2, _3)); + rs->foreachColumn(ec, boost::bind(&RowSetPresenter::addNamedValue, c->get<0>(), _2, _3)); rs->foreachAttr(boost::bind(&RowSetPresenter::addAttribute, c->get<0>(), _1, _2)); c->get<0>()->finishRow(); } - if (boost::algorithm::all(tests, boost::bind(&Test::passes, _1))) { - rowReady(rs); + if (boost::algorithm::all(tests, boost::bind(&Test::passes, _1, ec))) { + cb(rs); } } diff --git a/project2/common/rowProcessor.h b/project2/common/rowProcessor.h index 04a61bf..70f453c 100644 --- a/project2/common/rowProcessor.h +++ b/project2/common/rowProcessor.h @@ -10,6 +10,7 @@ #include "scriptStorage.h" class Presenter; +class ExecContext; /// Base class for Project2 components that work with row sets class RowProcessor : public IHaveParameters { @@ -25,12 +26,11 @@ class RowProcessor : public IHaveParameters { protected: boost::intrusive_ptr<RowSet> source; - void execute() const; + void execute(ExecContext *, const RowProcessorCallback &) const; private: friend class RowState; - void rowReadyInternal(const RowState *) const; - virtual void rowReady(const RowState *) const = 0; + void rowReadyInternal(const RowState *, const RowProcessorCallback &, ExecContext *) const; typedef ANONSTORAGEOF(Test) Tests; Tests tests; typedef ANONORDEREDSTORAGEOF(Cache) Caches; @@ -40,8 +40,8 @@ class RowProcessor : public IHaveParameters { typedef std::set<TargetCachePtr> TargetCaches; mutable TargetCaches tc; - void saveCaches() const; - void discardCaches() const; + void saveCaches(ExecContext *) const; + void discardCaches(ExecContext *) const; }; #endif diff --git a/project2/common/rowSet.cpp b/project2/common/rowSet.cpp index 0378b51..daa81b3 100644 --- a/project2/common/rowSet.cpp +++ b/project2/common/rowSet.cpp @@ -4,7 +4,6 @@ #include "scopeObject.h" #include "logger.h" #include "variables.h" -#include "rowProcessor.h" #include <boost/foreach.hpp> #include <boost/bind.hpp> @@ -29,12 +28,12 @@ RowState::~RowState() } void -RowState::process(const RowProcessor * rp, bool r) +RowState::process(const RowProcessorCallback & rp, bool r) { rowNum += 1; stack.push_back(this); ScopeObject s(boost::bind(&RowState::RowValuesStack::pop_back, &stack)); - rp->rowReadyInternal(this); + rp(this); if (r) { reset(); } @@ -70,13 +69,13 @@ RowState::resolveAttr(const Glib::ustring & attrName) const } VariableType -RowState::getCurrentValue(const Glib::ustring & col) const +RowState::getCurrentValue(ExecContext * ec, const Glib::ustring & col) const { const Columns & columns = getColumns(); Columns::index<byColName>::type::iterator di = columns.get<byColName>().find(col); if (di != columns.get<byColName>().end()) { if (fields[(*di)->idx].isNull()) { - return (*di)->defValue; + return (*di)->defValue(ec); } return fields[(*di)->idx]; } @@ -84,11 +83,11 @@ RowState::getCurrentValue(const Glib::ustring & col) const } void -RowState::foreachColumn(const ColumnAction & action) const +RowState::foreachColumn(ExecContext * ec, const ColumnAction & action) const { const Columns & columns = getColumns(); BOOST_FOREACH(const Columns::value_type & col, columns.get<byColName>()) { - action(col->idx, col->name, (!boost::get<Null>(&fields[col->idx])) ? fields[col->idx] : col->defValue()); + action(col->idx, col->name, (!boost::get<Null>(&fields[col->idx])) ? fields[col->idx] : col->defValue(ec)); } } diff --git a/project2/common/rowSet.h b/project2/common/rowSet.h index 2845983..50dd3fd 100644 --- a/project2/common/rowSet.h +++ b/project2/common/rowSet.h @@ -8,13 +8,13 @@ #include "columns.h" #include <boost/function.hpp> -class RowProcessor; class RowSet; class VariableType; +class RowState; + typedef boost::intrusive_ptr<RowSet> RowSetPtr; typedef boost::intrusive_ptr<const RowSet> ConstRowSetPtr; - -class RowState; +typedef boost::function<void(const RowState *)> RowProcessorCallback; /// Base class for Project2 components that provide a row set representation of data class RowSet : public SourceObject { @@ -26,7 +26,7 @@ class RowSet : public SourceObject { RowSet(ScriptNodePtr); virtual ~RowSet() = 0; - virtual void execute(const Glib::ustring &, const RowProcessor *) const = 0; + virtual void execute(const Glib::ustring &, const RowProcessorCallback &, ExecContext *) const = 0; }; class RowState { @@ -40,12 +40,12 @@ class RowState { SimpleMessageException(AttributeDoesNotExist); VariableType getRowNum() const; - void process(const RowProcessor *, bool reset = true); + void process(const RowProcessorCallback &, bool reset = true); void blankRow(); void reset(); - virtual VariableType getCurrentValue(const Glib::ustring & id) const; + virtual VariableType getCurrentValue(ExecContext *, const Glib::ustring & id) const; virtual RowAttribute resolveAttr(const Glib::ustring & attrName) const; - void foreachColumn(const ColumnAction & action) const; + void foreachColumn(ExecContext * ec, const ColumnAction & action) const; virtual void foreachAttr(const AttrAction & action) const; virtual const Columns & getColumns() const = 0; diff --git a/project2/common/rowView.cpp b/project2/common/rowView.cpp index c0e5cae..b9508bd 100644 --- a/project2/common/rowView.cpp +++ b/project2/common/rowView.cpp @@ -16,9 +16,7 @@ RowView::RowView(ScriptNodePtr p) : rootName(p, "rootname", Null()), recordName(p, "recordname"), required(p, "required", false), - isObject(p, "isobject", true), - presenter(NULL), - rowsFound(false) + isObject(p, "isobject", true) { BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("columns")) { viewColumns.insert(Columns::value_type(node->get_name(), Variable(node))); @@ -39,67 +37,66 @@ RowView::loadComplete(const CommonObjects * co) } void -RowView::rowReady(const RowState * rs) const +RowView::rowReady(const RowState * rs, const MultiRowSetPresenter * presenter, ExecContext * ec, bool & rowsFound) const { rowsFound = true; - if (isObject()) { - presenter->addNewRow(recordName()); + if (isObject(ec)) { + presenter->addNewRow(recordName(ec)); } if (viewColumns.empty()) { - rs->foreachColumn(boost::bind(&RowSetPresenter::addNamedValue, presenter, _2, _3)); + rs->foreachColumn(ec, boost::bind(&RowSetPresenter::addNamedValue, presenter, _2, _3)); } else { BOOST_FOREACH(const Columns::value_type & col, viewColumns) { - presenter->addNamedValue(col.first, col.second); + presenter->addNamedValue(col.first, col.second(ec)); } } - if (isObject()) { - executeChildren(); + if (isObject(ec)) { + executeChildren(presenter, ec); presenter->finishRow(); } BOOST_FOREACH(SetAggregateCPtr s, setAggregates) { - s->pushValue(); + s->pushValue(ec); } BOOST_FOREACH(ValueAggregateCPtr a, valueAggregates) { - a->pushValue(); + a->pushValue(ec); } } void -RowView::execute(const MultiRowSetPresenter * p) const +RowView::execute(const MultiRowSetPresenter * p, ExecContext * ec) const { - rowsFound = false; - presenter = p; - if (!rootName().isNull()) { - presenter->addNewRowSet(rootName()); + if (!rootName(ec).isNull()) { + p->addNewRowSet(rootName(ec)); } - ScopeObject pres(rootName().isNull() ? ScopeObject::Event() : boost::bind(&MultiRowSetPresenter::finishRowSet, p)); + bool rowsFound = false; + ScopeObject pres(rootName(ec).isNull() ? ScopeObject::Event() : boost::bind(&MultiRowSetPresenter::finishRowSet, p)); { - presenter->addNewArray(recordName(), true); + p->addNewArray(recordName(ec), true); ScopeObject pres(boost::bind(&MultiRowSetPresenter::finishArray, p, true)); - RowProcessor::execute(); + RowProcessor::execute(ec, boost::bind(&RowView::rowReady, this, _1, p, ec, boost::ref(rowsFound))); } - if (required() && !rowsFound) { + if (required(ec) && !rowsFound) { throw EmptyRequiredRows(name); } BOOST_FOREACH(SetAggregateCPtr s, setAggregates) { - presenter->addNewArray(s->name, false); + p->addNewArray(s->name, false); ScopeObject pres(boost::bind(&MultiRowSetPresenter::finishArray, p, false)); s->onResultValues(boost::bind(&MultiRowSetPresenter::addNamedValue, p, "value", _1)); s->reset(); } BOOST_FOREACH(ValueAggregateCPtr a, valueAggregates) { - presenter->addNamedValue(a->name, a->resultValue()); + p->addNamedValue(a->name, a->resultValue()); a->reset(); } } void -RowView::executeChildren() const +RowView::executeChildren(const MultiRowSetPresenter * presenter, ExecContext * ec) const { BOOST_FOREACH(const SubViews::value_type & sq, subViews) { - sq->execute(presenter); + sq->execute(presenter, ec); } } diff --git a/project2/common/rowView.h b/project2/common/rowView.h index 534a06f..d2745db 100644 --- a/project2/common/rowView.h +++ b/project2/common/rowView.h @@ -13,8 +13,8 @@ class RowView : public View, public RowProcessor { virtual ~RowView(); void loadComplete(const CommonObjects *); - void execute(const MultiRowSetPresenter *) const; - void rowReady(const RowState *) const; + void execute(const MultiRowSetPresenter *, ExecContext *) const; + void rowReady(const RowState *, const MultiRowSetPresenter *, ExecContext *, bool & found) const; const Variable rootName; const Variable recordName; @@ -25,16 +25,13 @@ class RowView : public View, public RowProcessor { typedef std::map<Glib::ustring, Variable> Columns; Columns viewColumns; - void executeChildren() const; + void executeChildren(const MultiRowSetPresenter * presenter, ExecContext *) const; typedef ANONORDEREDSTORAGEOF(View) SubViews; SubViews subViews; typedef ANONSTORAGEOF(ValueAggregate) ValueAggregates; ValueAggregates valueAggregates; typedef ANONSTORAGEOF(SetAggregate) SetAggregates; SetAggregates setAggregates; - mutable const MultiRowSetPresenter * presenter; - - mutable bool rowsFound; }; #endif diff --git a/project2/common/scriptLoader.cpp b/project2/common/scriptLoader.cpp index ab02f02..fe8799b 100644 --- a/project2/common/scriptLoader.cpp +++ b/project2/common/scriptLoader.cpp @@ -3,7 +3,6 @@ #include "scriptLoader.h" #include "scriptStorage.h" #include "library.h" -#include "appEngine.h" #include <boost/shared_ptr.hpp> #include <boost/foreach.hpp> #include <boost/function.hpp> diff --git a/project2/common/scripts.cpp b/project2/common/scripts.cpp index 767ff0d..f065e4b 100644 --- a/project2/common/scripts.cpp +++ b/project2/common/scripts.cpp @@ -32,20 +32,20 @@ ScriptNode::variable(const Glib::ustring & n, const VariableType & def) const } VariableType -ScriptNode::value(const Glib::ustring & n, const VariableType & def) const +ScriptNode::value(const Glib::ustring & n, const VariableType & def, ExecContext * ec) const { VariableType r; - if (applyValue(n, r)) { + if (applyValue(n, r, ec)) { return r; } return def; } VariableType -ScriptNode::value(const Glib::ustring & n) const +ScriptNode::value(const Glib::ustring & n, ExecContext * ec) const { VariableType r; - if (applyValue(n, r)) { + if (applyValue(n, r, ec)) { return r; } throw ValueNotFound(n); diff --git a/project2/common/scripts.h b/project2/common/scripts.h index 0cb478c..7bf6326 100644 --- a/project2/common/scripts.h +++ b/project2/common/scripts.h @@ -18,6 +18,7 @@ SimpleMessage2Exception(ScriptNotFound); SimpleMessage2Exception(DependencyNotFound); class VariableImpl; +class ExecContext; class Scripts { public: @@ -45,12 +46,12 @@ class ScriptNode : public IntrusivePtrBase { virtual ScriptNodes childrenIn(const Glib::ustring & sub) const = 0; virtual bool valueExists(const Glib::ustring & name) const = 0; - virtual bool applyValue(const Glib::ustring & name, VariableType & target) const = 0; + virtual bool applyValue(const Glib::ustring & name, VariableType & target, ExecContext *) const = 0; virtual VariableImpl * variable(const boost::optional<Glib::ustring> & defaultSource = boost::optional<Glib::ustring>()) const = 0; virtual VariableImpl * variable(const Glib::ustring & name) const = 0; VariableImpl * variable(const Glib::ustring & name, const VariableType & def) const; - VariableType value(const Glib::ustring & name) const; - VariableType value(const Glib::ustring & name, const VariableType & def) const; + VariableType value(const Glib::ustring & name, ExecContext *) const; + VariableType value(const Glib::ustring & name, const VariableType & def, ExecContext *) const; virtual void composeWithCallbacks(const LiteralCallback &, const NodeCallback &) const = 0; const ScriptReaderPtr script; diff --git a/project2/common/sessionClearTask.cpp b/project2/common/sessionClearTask.cpp index b3b1000..265bb1c 100644 --- a/project2/common/sessionClearTask.cpp +++ b/project2/common/sessionClearTask.cpp @@ -2,15 +2,15 @@ #include <boost/foreach.hpp> #include "scriptLoader.h" #include "sessionClearTask.h" -#include "appEngine.h" #include "session.h" +#include "execContext.h" DECLARE_LOADER("sessionclear", SessionClearTask); SessionClearTask::SessionClearTask(ScriptNodePtr p) : SourceObject(p), Task(p), - key(p->value("key").as<Glib::ustring>()) + key(p->value("key", NULL).as<Glib::ustring>()) { } @@ -19,8 +19,8 @@ SessionClearTask::~SessionClearTask() } void -SessionClearTask::execute() const +SessionClearTask::execute(ExecContext * ec) const { - ApplicationEngine::getCurrent()->session()->ClearValue(key); + ec->getSession()->ClearValue(key); } diff --git a/project2/common/sessionClearTask.h b/project2/common/sessionClearTask.h index c7def60..ead88bf 100644 --- a/project2/common/sessionClearTask.h +++ b/project2/common/sessionClearTask.h @@ -15,7 +15,7 @@ class SessionClearTask : public Task { SessionClearTask(ScriptNodePtr p); virtual ~SessionClearTask(); - void execute() const; + void execute(ExecContext *) const; const Glib::ustring key; }; diff --git a/project2/common/sessionContainer.cpp b/project2/common/sessionContainer.cpp index e9c76c9..41c3f98 100644 --- a/project2/common/sessionContainer.cpp +++ b/project2/common/sessionContainer.cpp @@ -1,6 +1,5 @@ #include <pch.hpp> #include "sessionContainer.h" -#include "environment.h" SessionContainer::SessionContainer() { diff --git a/project2/common/sessionSetTask.cpp b/project2/common/sessionSetTask.cpp index aca5b26..f46571b 100644 --- a/project2/common/sessionSetTask.cpp +++ b/project2/common/sessionSetTask.cpp @@ -2,15 +2,15 @@ #include <boost/foreach.hpp> #include "scriptLoader.h" #include "sessionSetTask.h" -#include "appEngine.h" #include "session.h" +#include "execContext.h" DECLARE_LOADER("sessionset", SessionSetTask); SessionSetTask::SessionSetTask(ScriptNodePtr p) : SourceObject(p), Task(p), - key(p->value("key").as<Glib::ustring>()), + key(p->value("key", NULL).as<Glib::ustring>()), value(p, "value") { } @@ -20,8 +20,8 @@ SessionSetTask::~SessionSetTask() } void -SessionSetTask::execute() const +SessionSetTask::execute(ExecContext * ec) const { - ApplicationEngine::getCurrent()->session()->SetValue(key, value); + ec->getSession()->SetValue(key, value(ec)); } diff --git a/project2/common/sessionSetTask.h b/project2/common/sessionSetTask.h index 8e88837..d38c216 100644 --- a/project2/common/sessionSetTask.h +++ b/project2/common/sessionSetTask.h @@ -16,7 +16,7 @@ class SessionSetTask : public Task { SessionSetTask(ScriptNodePtr p); virtual ~SessionSetTask(); - void execute() const; + void execute(ExecContext *) const; const Glib::ustring key; const Variable value; diff --git a/project2/common/singleton.cpp b/project2/common/singleton.cpp index 0aaf5f7..eff3f94 100644 --- a/project2/common/singleton.cpp +++ b/project2/common/singleton.cpp @@ -10,29 +10,28 @@ class Singleton : public View { Singleton(ScriptNodePtr p) : SourceObject(p), View(p), - rootName(p, "rootname"), - presenter(NULL) { + rootName(p, "rootname") + { BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("columns")) { viewColumns.insert(Columns::value_type(node->get_name(), Variable(node))); } p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&subViews)); } - void execute(const MultiRowSetPresenter * p) const + void execute(const MultiRowSetPresenter * p, ExecContext * ec) const { - presenter = p; - presenter->addNewRowSet(rootName()); + p->addNewRowSet(rootName(ec)); ScopeObject pres(boost::bind(&MultiRowSetPresenter::finishRowSet, p)); BOOST_FOREACH(const Columns::value_type & col, viewColumns) { - p->addNamedValue(col.first, col.second); + p->addNamedValue(col.first, col.second(ec)); } } const Variable rootName; private: - void executeChildren() const + void executeChildren(const MultiRowSetPresenter * p, ExecContext * ec) const { BOOST_FOREACH(const SubViews::value_type & sq, subViews) { - sq->execute(presenter); + sq->execute(p, ec); } } @@ -41,7 +40,6 @@ class Singleton : public View { typedef ANONSTORAGEOF(View) SubViews; SubViews subViews; - mutable const MultiRowSetPresenter * presenter; }; DECLARE_LOADER("singleton", Singleton); diff --git a/project2/common/sourceObject.cpp b/project2/common/sourceObject.cpp index 03f06b5..b451919 100644 --- a/project2/common/sourceObject.cpp +++ b/project2/common/sourceObject.cpp @@ -8,7 +8,7 @@ unsigned int SourceObject::loadOrder = 1; SimpleMessageException(ComponentNotFound); SourceObject::SourceObject(ScriptNodePtr p) : - name(p ? p->value("name", "anon").as<std::string>() : "anon"), + name(p ? p->value("name", "anon", NULL).as<std::string>() : "anon"), order(loadOrder++), script(p->script.get()) { diff --git a/project2/common/stream.h b/project2/common/stream.h index eebefab..ad3ee79 100644 --- a/project2/common/stream.h +++ b/project2/common/stream.h @@ -4,12 +4,14 @@ #include "sourceObject.h" #include <boost/function.hpp> +class ExecContext; + class Stream : public SourceObject { public: template<typename... X> Stream(const X &... x) : SourceObject(x...) { } typedef boost::function<size_t(const char *, size_t)> Sink; - virtual void runStream(const Sink &) const = 0; + virtual void runStream(const Sink &, ExecContext *) const = 0; }; typedef boost::intrusive_ptr<Stream> StreamPtr; diff --git a/project2/common/structExceptHandling.cpp b/project2/common/structExceptHandling.cpp index 0881d6d..917f030 100644 --- a/project2/common/structExceptHandling.cpp +++ b/project2/common/structExceptHandling.cpp @@ -23,22 +23,22 @@ StructuredExceptionHandler::loadComplete(const CommonObjects * co) } void -StructuredExceptionHandler::execute() const +StructuredExceptionHandler::execute(ExecContext * ec) const { try { - run(normal); + run(normal, ec); } catch (...) { try { - run(catches); - run(finallies); + run(catches, ec); + run(finallies, ec); return; } catch (...) { } - run(finallies); + run(finallies, ec); throw; } - run(finallies); + run(finallies, ec); } diff --git a/project2/common/structExceptHandling.h b/project2/common/structExceptHandling.h index 067c389..b6702f1 100644 --- a/project2/common/structExceptHandling.h +++ b/project2/common/structExceptHandling.h @@ -8,7 +8,7 @@ class StructuredExceptionHandler : public IHaveSubTasks { StructuredExceptionHandler(ScriptNodePtr); void loadComplete(const CommonObjects*); - void execute() const; + void execute(ExecContext * ec) const; private: Tasks catches, finallies; diff --git a/project2/common/task.h b/project2/common/task.h index 5303f15..15ccfbd 100644 --- a/project2/common/task.h +++ b/project2/common/task.h @@ -9,7 +9,7 @@ class Task : public NoOutputExecute { public: Task(ScriptNodePtr p); virtual ~Task(); - virtual void execute() const = 0; + virtual void execute(ExecContext *) const = 0; }; #endif diff --git a/project2/common/taskHost.cpp b/project2/common/taskHost.cpp index cbfe7c3..07f7601 100644 --- a/project2/common/taskHost.cpp +++ b/project2/common/taskHost.cpp @@ -27,11 +27,11 @@ TaskHost::loadComplete(const CommonObjects * co) } void -TaskHost::execute() const +TaskHost::execute(ExecContext * ec) const { loadScriptComponents(); ScopeObject txHandler(ScopeObject::Event(), boost::bind(&TaskHost::commitAll, this), boost::bind(&TaskHost::rollbackAll, this)); - run(tasks); + run(tasks, ec); } void diff --git a/project2/common/taskHost.h b/project2/common/taskHost.h index edecda6..e4b8b3a 100644 --- a/project2/common/taskHost.h +++ b/project2/common/taskHost.h @@ -15,7 +15,7 @@ class TaskHost : public IHaveSubTasks, virtual public CheckHost, virtual public virtual ~TaskHost(); void loadComplete(const CommonObjects *); - void execute() const; + void execute(ExecContext *) const; Tasks tasks; diff --git a/project2/common/test.h b/project2/common/test.h index 4f87c10..7cf563c 100644 --- a/project2/common/test.h +++ b/project2/common/test.h @@ -4,10 +4,12 @@ #include "sourceObject.h" #include "scripts.h" +class ExecContext; + class Test : public virtual SourceObject { public: Test(ScriptNodePtr); - virtual bool passes() const = 0; + virtual bool passes(ExecContext *) const = 0; virtual void reset() const; }; typedef boost::intrusive_ptr<const Test> TestPtr; diff --git a/project2/common/transform.cpp b/project2/common/transform.cpp index fb92486..efe9bf6 100644 --- a/project2/common/transform.cpp +++ b/project2/common/transform.cpp @@ -19,7 +19,7 @@ class TransformTargetStorer : public Storer { { TransformChainLinkPtr O = boost::dynamic_pointer_cast<TransformChainLink>(o); if (O) { - transformSource->addTarget(O, s); + transformSource->addTarget(O, NULL, s); } return O; } @@ -44,13 +44,13 @@ TransformChainLink::~TransformChainLink() typedef std::map<std::string, boost::shared_ptr<TransformLoader> > TransformLoaderMap; void -TransformSource::addTarget(TransformChainLinkPtr tcl, ScriptNodePtr e) +TransformSource::addTarget(TransformChainLinkPtr tcl, ExecContext * ec, ScriptNodePtr e) { BOOST_FOREACH(const TransformLoaderMap::value_type & tl, *Plugable::objLoaders<TransformLoader>()) { TransformPtr t = tl.second->create(); if (t->canTransform(this, tcl.get())) { if (e) { - t->configure(e); + t->configure(e, ec); } targets[tcl] = t; return; @@ -72,12 +72,12 @@ TransformSource::removeTarget(TransformChainLinkPtr tcl) } void -TransformSource::doTransforms() const +TransformSource::doTransforms(ExecContext * ec) const { BOOST_FOREACH(const Targets::value_type & t, targets) { - t.second->transform(this, t.first.get()); + t.second->transform(this, t.first.get(), ec); if (const TransformSource * tr = dynamic_cast<const TransformSource *>(t.first.get())) { - tr->doTransforms(); + tr->doTransforms(ec); } } } @@ -90,16 +90,16 @@ TransformSource::getTargets() const class TransformWritableContentToStdStream : public TransformImpl<WritableContent, ostreamWrapper> { public: - void transform(const WritableContent * wc, ostreamWrapper * o) const + void transform(const WritableContent * wc, ostreamWrapper * o, ExecContext * ec) const { - wc->writeTo(o->strm, "UTF-8"); + wc->writeTo(o->strm, "UTF-8", ec); } }; DECLARE_TRANSFORM(TransformWritableContentToStdStream); class TransformStaticContentToStdStream : public TransformImpl<StaticContent, ostreamWrapper> { public: - void transform(const StaticContent * wc, ostreamWrapper * o) const + void transform(const StaticContent * wc, ostreamWrapper * o, ExecContext *) const { wc->writeTo(o->strm); } diff --git a/project2/common/transform.h b/project2/common/transform.h index 3ae1063..34e91b7 100644 --- a/project2/common/transform.h +++ b/project2/common/transform.h @@ -6,6 +6,8 @@ #include "scriptLoader.h" #include <map> +class ExecContext; + class TransformChainLink : public virtual IntrusivePtrBase { public: virtual ~TransformChainLink() = 0; @@ -22,8 +24,8 @@ class TransformSource : public TransformChainLink { TransformSource(ScriptNodePtr, ObjectSource); void clearTargets(); void removeTarget(TransformChainLinkPtr); - void addTarget(TransformChainLinkPtr, ScriptNodePtr e = NULL); - void doTransforms() const; + void addTarget(TransformChainLinkPtr, ExecContext *, ScriptNodePtr e); + void doTransforms(ExecContext *) const; const Targets & getTargets() const; private: virtual const TransformChainLink * object() const { return this; } @@ -41,9 +43,9 @@ class SourceOf : public virtual TransformSource { class Transform : public virtual IntrusivePtrBase { public: - virtual void transform(const TransformSource * src, TransformChainLink * dest) const = 0; + virtual void transform(const TransformSource * src, TransformChainLink * dest, ExecContext *) const = 0; virtual bool canTransform(const TransformSource * src, TransformChainLink * dest) const = 0; - virtual void configure(ScriptNodePtr) { }; + virtual void configure(ScriptNodePtr, ExecContext *) { }; }; typedef GenLoader<Transform> TransformLoader; @@ -55,10 +57,10 @@ typedef GenLoader<TransformChainLink, ScriptNodePtr, ObjectSource> TransformTarg template <class Source, class Destination> class TransformImpl : public Transform { public: - virtual void transform(const Source *, Destination *) const = 0; - void transform(const TransformSource * src, TransformChainLink * dest) const + virtual void transform(const Source *, Destination *, ExecContext *) const = 0; + void transform(const TransformSource * src, TransformChainLink * dest, ExecContext * ec) const { - transform(dynamic_cast<const SourceOf<Source> *>(src)->operator const Source *(), dynamic_cast<Destination *>(dest)); + transform(dynamic_cast<const SourceOf<Source> *>(src)->operator const Source *(), dynamic_cast<Destination *>(dest), ec); } bool canTransform(const TransformSource * src, TransformChainLink * dest) const { @@ -75,7 +77,7 @@ class WritableContent { }; virtual Class getContentClass() const = 0; virtual Glib::ustring getContentType() const = 0; - virtual void writeTo(std::ostream &, const std::string & encoding) const = 0; + virtual void writeTo(std::ostream &, const std::string & encoding, ExecContext *) const = 0; }; class StaticContent { diff --git a/project2/common/variables.cpp b/project2/common/variables.cpp index 6f62dc1..a8ca808 100644 --- a/project2/common/variables.cpp +++ b/project2/common/variables.cpp @@ -5,7 +5,6 @@ #include "iHaveParameters.h" #include "scriptLoader.h" #include "exceptions.h" -#include "appEngine.h" #include "session.h" #include "rowSet.h" #include <stdexcept> @@ -31,9 +30,9 @@ class VariableParent : public VariableImplDyn { public: VariableParent(ScriptNodePtr e) : VariableImplDyn(e), - depth(e->value("depth", 1).as<int32_t>()), + depth(e->value("depth", 1, NULL).as<int32_t>()), attr(e->valueExists("attribute")), - name((attr ? e->value("attribute") : e->value("name")).as<Glib::ustring>()) + name((attr ? e->value("attribute", NULL) : e->value("name", NULL)).as<Glib::ustring>()) { } VariableParent(const Glib::ustring & n, bool a, unsigned int d) : @@ -43,14 +42,14 @@ class VariableParent : public VariableImplDyn { name(n) { } - VariableType value() const + VariableType value(ExecContext * ec) const { try { if (!getValue) { if (depth > RowState::Stack().size()) { throw RowSet::ParentOutOfRange(depth); } - bind(RowState::Stack()[RowState::Stack().size() - depth]); + bind(ec, RowState::Stack()[RowState::Stack().size() - depth]); } return getValue(); } @@ -58,23 +57,23 @@ class VariableParent : public VariableImplDyn { if (!defaultValue) { throw; } - return (*defaultValue)(); + return (*defaultValue)(ec); } catch (RowSet::FieldDoesNotExist) { if (!defaultValue) { throw; } - return (*defaultValue)(); + return (*defaultValue)(ec); } } protected: - void bind(const RowState * row) const + void bind(ExecContext * ec, const RowState * row) const { if (attr) { getValue = boost::bind(row->resolveAttr(name)); } else { - getValue = boost::bind(&RowState::getCurrentValue, row, name); + getValue = boost::bind(&RowState::getCurrentValue, row, ec, name); } } const size_t depth; diff --git a/project2/common/variables.h b/project2/common/variables.h index 948f2d2..7713667 100644 --- a/project2/common/variables.h +++ b/project2/common/variables.h @@ -10,12 +10,14 @@ #include "variableType.h" #include <boost/shared_ptr.hpp> +class ExecContext; + SimpleMessageException(UnknownVariableSource); /// Base class for Project2 variable accessors class VariableImpl : public IntrusivePtrBase { public: - virtual VariableType value() const = 0; + virtual VariableType value(ExecContext *) const = 0; protected: virtual ~VariableImpl() = 0; @@ -32,8 +34,7 @@ class Variable { static Variable makeParent(const Glib::ustring & name, bool attr, unsigned int depth); - operator VariableType () const { return var->value(); } - VariableType operator()() const { return var->value(); } + VariableType operator()(ExecContext * ec) const { return var->value(ec); } private: Variable(VariableImpl *); @@ -45,7 +46,7 @@ class Variable { class VariableImplDyn : public VariableImpl { public: VariableImplDyn(ScriptNodePtr e); - virtual VariableType value() const = 0; + virtual VariableType value(ExecContext *) const = 0; protected: boost::optional<Variable> defaultValue; diff --git a/project2/common/variables/config.cpp b/project2/common/variables/config.cpp index 51759d5..9b4cccb 100644 --- a/project2/common/variables/config.cpp +++ b/project2/common/variables/config.cpp @@ -3,7 +3,6 @@ #include "../scriptLoader.h" #include "../scriptStorage.h" #include <boost/algorithm/string/predicate.hpp> -#include "../appEngine.h" typedef std::map<Glib::ustring, VariableType> ConfigOptions; static ConfigOptions cfgOpts; @@ -15,17 +14,17 @@ class VariableConfig : public VariableImplDyn { public: VariableConfig(ScriptNodePtr e) : VariableImplDyn(e), - name(e->value("name").as<Glib::ustring>()) + name(e->value("name", NULL).as<Glib::ustring>()) { } - VariableType value() const + VariableType value(ExecContext * ec) const { const ConfigOptions::const_iterator i = cfgOpts.find(name); if (i != cfgOpts.end()) { return i->second; } if (defaultValue) { - return defaultValue.get()(); + return defaultValue.get()(ec); } throw NoSuchConfigurationValue(name); } @@ -40,17 +39,17 @@ class VariableConfigLoader : public VariableLoader::For<VariableConfig> { void reset() const { cfgOpts.clear(); } - void consume(const Glib::ustring & n, const Glib::ustring & p, const VariableType & v) const { + void consume(const Glib::ustring & n, const Glib::ustring & p, const VariableType & v, const Options::CurrentPlatform & cp) const { if (boost::algorithm::starts_with(n, "application.")) { Glib::ustring k(n.substr(12)); const ConfigOptions::iterator i = cfgOpts.find(k); if (i == cfgOpts.end()) { - if (p.empty() || p == Environment::getCurrent()->platform()) { + if (p.empty() || p == cp) { cfgOpts.insert(ConfigOptions::value_type(k, v)); } } else { - if (p == Environment::getCurrent()->platform()) { + if (p == cp) { i->second = v; } } diff --git a/project2/common/variables/fixed.cpp b/project2/common/variables/fixed.cpp index fdb67ed..4687c6a 100644 --- a/project2/common/variables/fixed.cpp +++ b/project2/common/variables/fixed.cpp @@ -6,7 +6,7 @@ VariableFixed::VariableFixed(VariableType v) : } VariableType -VariableFixed::value() const +VariableFixed::value(ExecContext *) const { return var; } diff --git a/project2/common/variables/fixed.h b/project2/common/variables/fixed.h index ec8be1a..b1380dd 100644 --- a/project2/common/variables/fixed.h +++ b/project2/common/variables/fixed.h @@ -7,7 +7,7 @@ class VariableFixed : public VariableImpl { public: VariableFixed(VariableType v); - VariableType value() const; + VariableType value(ExecContext * ec) const; private: VariableType var; diff --git a/project2/common/variables/literal.cpp b/project2/common/variables/literal.cpp index 11fb78a..3696346 100644 --- a/project2/common/variables/literal.cpp +++ b/project2/common/variables/literal.cpp @@ -19,7 +19,7 @@ append(VariableLiteral::Vals * vals, const Y & y) VariableLiteral::VariableLiteral(ScriptNodePtr s) { try { - val = VariableType::make(s->value("value"), VariableType::getTypeFromName(s->value("type", ""))); + val = VariableType::make(s->value("value", NULL), VariableType::getTypeFromName(s->value("type", "", NULL))); } catch (const ValueNotFound &) { s->composeWithCallbacks( @@ -29,17 +29,17 @@ VariableLiteral::VariableLiteral(ScriptNodePtr s) { } VariableType -VariableLiteral::value() const +VariableLiteral::value(ExecContext * ec) const { if (vals.empty()) { return val; } if (vals.size() == 1) { - return *vals.front(); + return vals.front()->value(ec); } Glib::ustring v; BOOST_FOREACH(PartCPtr p, vals) { - p->appendTo(v); + p->appendTo(ec, v); } return v; } @@ -49,11 +49,12 @@ VariableLiteral::TextPart::TextPart(const Glib::ustring & e) : { } void -VariableLiteral::TextPart::appendTo(Glib::ustring & str) const +VariableLiteral::TextPart::appendTo(ExecContext *, Glib::ustring & str) const { str += txt; } -VariableLiteral::TextPart::operator VariableType() const +VariableType +VariableLiteral::TextPart::value(ExecContext *) const { return txt; } @@ -62,13 +63,14 @@ VariableLiteral::VarPart::VarPart(ScriptNodePtr e) : Variable(e) { } void -VariableLiteral::VarPart::appendTo(Glib::ustring & str) const +VariableLiteral::VarPart::appendTo(ExecContext * ec, Glib::ustring & str) const { - str += (*this)().operator const Glib::ustring &(); + str += (*this)(ec).operator const Glib::ustring &(); } -VariableLiteral::VarPart::operator VariableType() const +VariableType +VariableLiteral::VarPart::value(ExecContext * ec) const { - return (*this)(); + return (*this)(ec); } DECLARE_COMPONENT_LOADER("literal", VariableLiteral, VariableLoader); diff --git a/project2/common/variables/literal.h b/project2/common/variables/literal.h index 4128d1c..8c120b6 100644 --- a/project2/common/variables/literal.h +++ b/project2/common/variables/literal.h @@ -8,28 +8,28 @@ class VariableLiteral : public VariableImpl { public: VariableLiteral(const Glib::ustring & src, const VT_typeID format = DefaultType); VariableLiteral(ScriptNodePtr); - virtual VariableType value() const; + virtual VariableType value(ExecContext * ec) const; class Part; typedef boost::intrusive_ptr<Part> PartCPtr; typedef std::list<PartCPtr> Vals; class Part : public IntrusivePtrBase { public: - virtual void appendTo(Glib::ustring & str) const = 0; - virtual operator VariableType() const = 0; + virtual void appendTo(ExecContext *, Glib::ustring & str) const = 0; + virtual VariableType value(ExecContext *) const = 0; }; class TextPart : public Part { public: TextPart(const Glib::ustring & e); - void appendTo(Glib::ustring & str) const; - operator VariableType() const; + void appendTo(ExecContext *, Glib::ustring & str) const; + VariableType value(ExecContext *) const; const Glib::ustring txt; }; class VarPart : public Part, public Variable { public: VarPart(ScriptNodePtr e); - void appendTo(Glib::ustring & str) const; - operator VariableType() const; + void appendTo(ExecContext *, Glib::ustring & str) const; + VariableType value(ExecContext *) const; }; private: VariableType val; diff --git a/project2/common/variables/localparam.cpp b/project2/common/variables/localparam.cpp index 1b789a7..bb71bde 100644 --- a/project2/common/variables/localparam.cpp +++ b/project2/common/variables/localparam.cpp @@ -9,19 +9,19 @@ class VariableLocalParam : public VariableImplDyn { public: VariableLocalParam(ScriptNodePtr e) : VariableImplDyn(e), - name(e->value("name").as<Glib::ustring>()) + name(e->value("name", NULL).as<Glib::ustring>()) { } - VariableType value() const + VariableType value(ExecContext * ec) const { try { - return IHaveParameters::getScopedParameter(name); + return IHaveParameters::getScopedParameter(name, ec); } catch (ParamNotFound) { if (!defaultValue) { throw; } - return (*defaultValue)(); + return (*defaultValue)(ec); } } private: diff --git a/project2/common/variables/lookup.cpp b/project2/common/variables/lookup.cpp index 2a96338..b3f9002 100644 --- a/project2/common/variables/lookup.cpp +++ b/project2/common/variables/lookup.cpp @@ -33,38 +33,38 @@ class VariableLookup : public VariableImplDyn, public RowProcessor { VariableLookup(ScriptNodePtr e) : VariableImplDyn(e), RowProcessor(e), - name(e->value("name").as<Glib::ustring>()) + name(e->value("name", NULL).as<Glib::ustring>()) { e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&rowSets)); } - VariableType value() const + VariableType value(ExecContext * ec) const { if (map.empty()) { - fillCache(); + fillCache(ec); } Key k; k.reserve(parameters.size()); BOOST_FOREACH(const Parameters::value_type & p, parameters) { - k.push_back(p.second); + k.push_back(p.second(ec)); } return safeMapLookup<NotFound>(map, k); } private: - void fillCache() const + void fillCache(ExecContext * ec) const { BOOST_FOREACH(const RowSets::value_type & rs, rowSets) { - rs->execute(filter, this); + rs->execute(filter, boost::bind(&VariableLookup::rowReady, this, _1, ec), ec); } Logger()->messagef(LOG_DEBUG, "%s: %s has filled cached with %zu items", __PRETTY_FUNCTION__, name.c_str(), map.size()); } - void rowReady(const RowState * rs) const + void rowReady(const RowState * rs, ExecContext * ec) const { Key k; BOOST_FOREACH(const Parameters::value_type & p, parameters) { - k.push_back(rs->getCurrentValue(p.first)); + k.push_back(rs->getCurrentValue(ec, p.first)); } - map[k] = rs->getCurrentValue(name); + map[k] = rs->getCurrentValue(ec, name); } mutable Map map; typedef ANONSTORAGEOF(RowSet) RowSets; diff --git a/project2/common/variables/param.cpp b/project2/common/variables/param.cpp index 7292b0a..a1ef9b7 100644 --- a/project2/common/variables/param.cpp +++ b/project2/common/variables/param.cpp @@ -1,31 +1,31 @@ #include <pch.hpp> +#include "../execContext.h" #include "../variables.h" #include "../scriptLoader.h" #include "../scriptStorage.h" -#include "../appEngine.h" /// Variable implementation to access call parameters class VariableParam : public VariableImplDyn { public: VariableParam(ScriptNodePtr e) : VariableImplDyn(e), - name(e->value("name").as<Glib::ustring>()) + name(e->value("name", NULL)) { } - VariableType value() const + VariableType value(ExecContext * ec) const { try { - return ApplicationEngine::getCurrent()->env()->getParamQuery(name); + return ec->getParameter(name); } catch (ParamNotFound) { if (!defaultValue) { throw; } - return (*defaultValue)(); + return (*defaultValue)(ec); } } private: - const Glib::ustring name; + const VariableType name; }; DECLARE_COMPONENT_LOADER("param", VariableParam, VariableLoader); diff --git a/project2/common/variables/session.cpp b/project2/common/variables/session.cpp index fc33d8e..ed2077d 100644 --- a/project2/common/variables/session.cpp +++ b/project2/common/variables/session.cpp @@ -1,27 +1,27 @@ #include <pch.hpp> #include "../variables.h" +#include "../execContext.h" #include "../scriptLoader.h" #include "../scriptStorage.h" -#include "../appEngine.h" /// Variable implementation to access session contents class VariableSession : public VariableImplDyn { public: VariableSession(ScriptNodePtr e) : VariableImplDyn(e), - name(e->value("name").as<Glib::ustring>()) + name(e->value("name", NULL).as<Glib::ustring>()) { } - VariableType value() const + VariableType value(ExecContext * ec) const { try { - return ApplicationEngine::getCurrent()->session()->GetValue(name); + return ec->getSession()->GetValue(name); } catch (Session::VariableNotFound) { if (!defaultValue) { throw; } - return (*defaultValue)(); + return (*defaultValue)(ec); } } private: diff --git a/project2/common/view.h b/project2/common/view.h index 75a0f3c..52a4130 100644 --- a/project2/common/view.h +++ b/project2/common/view.h @@ -5,6 +5,7 @@ #include "scriptStorage.h" class MultiRowSetPresenter; +class ExecContext; SimpleMessageException(EmptyRequiredRows); /// Base class for Project2 components that output data @@ -13,7 +14,7 @@ class View : public virtual SourceObject { View(ScriptNodePtr); virtual ~View(); - virtual void execute(const MultiRowSetPresenter *) const = 0; + virtual void execute(const MultiRowSetPresenter *, ExecContext *) const = 0; }; #endif diff --git a/project2/common/viewGroup.cpp b/project2/common/viewGroup.cpp index b01f6c8..e6e84d0 100644 --- a/project2/common/viewGroup.cpp +++ b/project2/common/viewGroup.cpp @@ -11,11 +11,11 @@ class ViewGroup : public View { s->script->loader.addLoadTarget(s, Storer::into<ElementLoader>(&subViews)); } - void execute(const MultiRowSetPresenter * presenter) const + void execute(const MultiRowSetPresenter * presenter, ExecContext * ec) const { presenter->addNewRowSet(name); BOOST_FOREACH(const SubViews::value_type & sq, subViews) { - sq->execute(presenter); + sq->execute(presenter, ec); } presenter->finishRowSet(); } diff --git a/project2/common/viewHost.cpp b/project2/common/viewHost.cpp index 04e0d88..320e86d 100644 --- a/project2/common/viewHost.cpp +++ b/project2/common/viewHost.cpp @@ -17,14 +17,14 @@ ViewHost::~ViewHost() } void -ViewHost::executeViews() const +ViewHost::executeViews(ExecContext * ec) const { loadScriptComponents(); - MultiRowSetPresenterPtr presenter = getPresenter(); - presenter->init(); + MultiRowSetPresenterPtr presenter = getPresenter(ec); + presenter->init(ec); BOOST_FOREACH(const Views::value_type & s, views) { - s->execute(presenter.get()); + s->execute(presenter.get(), ec); } // Caches might open transactions BOOST_FOREACH(const CommonObjects::DataSources::value_type & ds, CommonObjects::datasources) { @@ -34,12 +34,12 @@ ViewHost::executeViews() const } void -ViewHost::doTransforms() const +ViewHost::doTransforms(ExecContext * ec) const { - MultiRowSetPresenterPtr presenter = getPresenter(); + MultiRowSetPresenterPtr presenter = getPresenter(ec); TransformSourcePtr ts = boost::dynamic_pointer_cast<TransformSource>(presenter); if (ts) { - ts->doTransforms(); + ts->doTransforms(ec); } } diff --git a/project2/common/viewHost.h b/project2/common/viewHost.h index d09f1af..5ede3e4 100644 --- a/project2/common/viewHost.h +++ b/project2/common/viewHost.h @@ -13,11 +13,11 @@ class ViewHost : virtual public CheckHost, virtual public CommonObjects { ViewHost(ScriptNodePtr script); ~ViewHost(); - void executeViews() const; - void doTransforms() const; + void executeViews(ExecContext *) const; + void doTransforms(ExecContext *) const; protected: - virtual MultiRowSetPresenterPtr getPresenter() const = 0; + virtual MultiRowSetPresenterPtr getPresenter(ExecContext *) const = 0; private: typedef ANONORDEREDSTORAGEOF(View) Views; diff --git a/project2/compression/decompressStream.cpp b/project2/compression/decompressStream.cpp index 92ba035..ad2e01d 100644 --- a/project2/compression/decompressStream.cpp +++ b/project2/compression/decompressStream.cpp @@ -14,13 +14,13 @@ class DecompressStream : public Stream { p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&stream)); } - void runStream(const Sink & sink) const + void runStream(const Sink & sink, ExecContext * ec) const { - DecompressorPtr decomp = DecompressorLoader::getFor(method())->create(); + DecompressorPtr decomp = DecompressorLoader::getFor(method(ec))->create(); stream->runStream([&](const char * data, size_t len) -> size_t { decomp->decompress(data, len, sink); return len; - }); + }, ec); } StreamPtr stream; diff --git a/project2/console/claOptions.cpp b/project2/console/claOptions.cpp index 79be7dc..ee28bf6 100644 --- a/project2/console/claOptions.cpp +++ b/project2/console/claOptions.cpp @@ -4,6 +4,7 @@ #include "../common/optionsSource.h" #include "../common/exceptions.h" #include "claOptions.h" +#include "consoleAppEngine.h" StaticMessageException(InvalidScriptName, "Script name should be group/name"); SimpleMessageException(ArgumentRequired); @@ -17,7 +18,7 @@ CommandLineArguments::CommandLineArguments(int c, const char * const * v) : } void -CommandLineArguments::loadInto(const ConfigConsumer & consume) const { +CommandLineArguments::loadInto(const ConfigConsumer & consume, const Options::CurrentPlatform & platform) const { bool moreopts = true; for (int x = 1; x < argc; x += 1) { @@ -35,10 +36,10 @@ CommandLineArguments::loadInto(const ConfigConsumer & consume) const { if (x >= argc) { throw ArgumentRequired(name); } - consume(name, Environment::getCurrent()->platform(), argv[x]); + consume(name, platform(), argv[x], platform); } else { - consume(name, Environment::getCurrent()->platform(), name); + consume(name, platform(), name, platform); } } else if (moreopts && *(argv[x]) == '-') { @@ -55,22 +56,22 @@ CommandLineArguments::loadInto(const ConfigConsumer & consume) const { if (x >= argc) { throw ArgumentRequired(name); } - consume(name, Environment::getCurrent()->platform(), argv[x]); + consume(name, platform(), argv[x], platform); } else { - consume(name, Environment::getCurrent()->platform(), n); + consume(name, platform(), n, platform); n += 1; } } else { - consume(name, Environment::getCurrent()->platform(), name); + consume(name, platform(), name, platform); } } } else { const char * sl = strchr(argv[x], '/'); if (sl) { - ConsoleEnvironment::todolist.push_back(ConsoleEnvironment::ToDo(std::string(argv[x], sl), sl + 1)); + ConsoleApplicationEngine::todolist.push_back(ConsoleApplicationEngine::ToDo(std::string(argv[x], sl), sl + 1)); sl++; } else { diff --git a/project2/console/claOptions.h b/project2/console/claOptions.h index e1fee8d..ea3fb01 100644 --- a/project2/console/claOptions.h +++ b/project2/console/claOptions.h @@ -6,7 +6,7 @@ class CommandLineArguments : public OptionsSource { public: CommandLineArguments(int c, const char * const * v); - void loadInto(const ConfigConsumer & consume) const; + void loadInto(const ConfigConsumer & consume, const Options::CurrentPlatform & platform) const; bool needReload() const; private: diff --git a/project2/console/consoleAppEngine.cpp b/project2/console/consoleAppEngine.cpp index 044544c..332d7b8 100644 --- a/project2/console/consoleAppEngine.cpp +++ b/project2/console/consoleAppEngine.cpp @@ -2,11 +2,11 @@ #include <glibmm/exception.h> #include <cxxabi.h> #include "consoleAppEngine.h" -#include "consoleEnvironment.h" #include "consolePresenter.h" -#include "logger.h" #include "safeMapFind.h" -#include "iterate.h" +#include "logger.h" +#include "viewHost.h" +#include "taskHost.h" #include "scriptLoader.h" #include <boost/foreach.hpp> #include <boost/bind.hpp> @@ -15,13 +15,45 @@ SimpleMessageException(UnknownPlatformAlias); -ConsoleApplicationEngine::ConsoleApplicationEngine(const ConsoleEnvironment * env, ScriptReaderPtr script) : - SourceObject(script->root()), - CommonObjects(script->root()), - CheckHost(script->root()), - TaskHost(script->root()), - ViewHost(script->root()), - _env(env), +class ShowHelpTrigger : public Options::Target { + public: + void reset() const { } + bool paramRequired() const { + return false; + } + void consume(const Glib::ustring &, const VariableType &, const Options::CurrentPlatform &) const { + fprintf(stdout, "Help\n"); + Plugable::onAll<Options>(boost::bind(&ShowHelpTrigger::outputOptions, this, _1)); + exit(1); + } + private: + void outputOptions(const Options * options) const { + fprintf(stdout, " * %s\n", options->name.c_str()); + BOOST_FOREACH(const auto & option, options->allOptions()) { + fprintf(stdout, " * %s - %s\n", option->name().c_str(), option->description().c_str()); + } + } +}; + +DECLARE_OPTIONS(ConsoleApplicationEngine, "Console options") +("help", new ShowHelpTrigger(), + "Print usage and exit")("h") +("console.platform", Options::value(&reqPlatform), + "Platform")("p") +("console.queryParam", Options::functions( + [](const VariableType & v) { + Glib::ustring vs(v.as<Glib::ustring>()); + parameters.insert(Parameters::value_type(vs.substr(0, vs.find('=')), vs.substr(vs.find('=') + 1))); + }, + boost::bind(&Parameters::clear, ¶meters)), + "Query parameter")("q") +END_OPTIONS(ConsoleApplicationEngine); + +ConsoleApplicationEngine::ToDoList ConsoleApplicationEngine::todolist; +ConsoleApplicationEngine::Parameters ConsoleApplicationEngine::parameters; +Glib::ustring ConsoleApplicationEngine::reqPlatform; + +ConsoleApplicationEngine::ConsoleApplicationEngine() : runtime(new Session(boost::uuids::random_generator()())), presenter(new ConsolePresenter()) { @@ -31,14 +63,39 @@ ConsoleApplicationEngine::~ConsoleApplicationEngine() { } +class ScriptRunner : public TaskHost, public ViewHost { + public: + ScriptRunner(ScriptReaderPtr script, MultiRowSetPresenterPtr p) : + SourceObject(script->root()), + CommonObjects(script->root()), + CheckHost(script->root()), + TaskHost(script->root()), + ViewHost(script->root()), + presenter(p) + { + } + + MultiRowSetPresenterPtr getPresenter(ExecContext *) const + { + return presenter; + } + + void process(ExecContext * ec) + { + runChecks(ec); + execute(ec); + executeViews(ec); + } + private: + MultiRowSetPresenterPtr presenter; +}; + void -ConsoleApplicationEngine::process() const +ConsoleApplicationEngine::process(ScriptReaderPtr s) { try { - runChecks(); - execute(); - executeViews(); - addAppData(presenter.get()); + boost::intrusive_ptr<ScriptRunner> sr = new ScriptRunner(s, presenter); + sr->process(this); } catch (const std::exception & e) { char * buf = __cxxabiv1::__cxa_demangle(typeid(e).name(), NULL, NULL, NULL); @@ -52,31 +109,29 @@ ConsoleApplicationEngine::process() const } } -MultiRowSetPresenterPtr -ConsoleApplicationEngine::getPresenter() const -{ - return presenter; -} - -const Environment * -ConsoleApplicationEngine::env() const -{ - return _env; -} - SessionPtr -ConsoleApplicationEngine::session() const +ConsoleApplicationEngine::getSession() const { return runtime; } -void -ConsoleApplicationEngine::addEnvData(const MultiRowSetPresenter *) const +VariableType +ConsoleApplicationEngine::getParameter(const VariableType & key) const { + return safeMapLookup<ParamNotFound>(parameters, key); } void -ConsoleApplicationEngine::addAppData(const MultiRowSetPresenter *) const +ConsoleApplicationEngine::process() { -} + BOOST_FOREACH(const auto & todo, todolist) { + Plugable::onAllComponents(boost::bind(&ComponentLoader::onBefore, _1)); + Logger()->messagebf(LOG_DEBUG, "%s: Beginning script '%s/%s'", __FUNCTION__, todo.get<0>(), todo.get<1>()); + + Logger()->messagef(LOG_DEBUG, "%s: Processing file", __FUNCTION__); + process(ScriptReader::resolveScript(todo.get<0>(), todo.get<1>(), false)); + Logger()->messagef(LOG_DEBUG, "%s: Complete", __FUNCTION__); + Plugable::onAllComponents(boost::bind(&ComponentLoader::onIteration, _1)); + } +} diff --git a/project2/console/consoleAppEngine.h b/project2/console/consoleAppEngine.h index 3bfd9ed..b75d9b1 100644 --- a/project2/console/consoleAppEngine.h +++ b/project2/console/consoleAppEngine.h @@ -1,39 +1,42 @@ #ifndef CONSOLEAPPENGINE_H #define CONSOLEAPPENGINE_H -#include "appEngine.h" #include "task.h" #include "presenter.h" #include "commonObjects.h" #include "view.h" -#include "taskHost.h" -#include "viewHost.h" -#include <boost/intrusive_ptr.hpp> +#include "execContext.h" +#include <vector> +#include <boost/tuple/tuple.hpp> -class ConsoleEnvironment; - -class ConsoleApplicationEngine : public ApplicationEngine, public TaskHost, public ViewHost { +class ConsoleApplicationEngine : public ExecContext { public: - ConsoleApplicationEngine(const ConsoleEnvironment *, ScriptReaderPtr); + ConsoleApplicationEngine(); virtual ~ConsoleApplicationEngine(); - void process() const; - const Environment * env() const; - SessionPtr session() const; - virtual void addAppData(const MultiRowSetPresenter * p) const; - virtual void addEnvData(const MultiRowSetPresenter * p) const; + void process(); + VariableType getParameter(const VariableType&) const; + SessionPtr getSession() const; - protected: - const ConsoleEnvironment * _env; - MultiRowSetPresenterPtr getPresenter() const; + INITOPTIONS; private: + void process(ScriptReaderPtr); + + typedef boost::tuple<Glib::ustring, Glib::ustring> ToDo; + typedef std::vector<ToDo> ToDoList; typedef std::map<Glib::ustring, const Glib::ustring> ConsolePlatforms; - mutable ConsolePlatforms conplat; + typedef std::map<std::string, std::string> Parameters; - private: + friend class CommandLineArguments; + mutable ConsolePlatforms conplat; SessionPtr runtime; MultiRowSetPresenterPtr presenter; + + static ToDoList todolist; + static Parameters parameters; + public: + static Glib::ustring reqPlatform; }; #endif diff --git a/project2/console/consoleEnvironment.cpp b/project2/console/consoleEnvironment.cpp deleted file mode 100644 index d9abde2..0000000 --- a/project2/console/consoleEnvironment.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include <pch.hpp> -#include "consoleEnvironment.h" -#include <sys/utsname.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include "logger.h" -#include "exceptions.h" -#include "scriptLoader.h" -#include <iostream> -#include <string> -#include <boost/algorithm/string/predicate.hpp> -#include "options.h" -#include <boost/bind.hpp> - -ConsoleEnvironment::ToDoList ConsoleEnvironment::todolist; - -class ShowHelpTrigger : public Options::Target { - public: - void reset() const { } - bool paramRequired() const { - return false; - } - void consume(const Glib::ustring &, const VariableType &) const { - fprintf(stdout, "Help\n"); - Plugable::onAll<Options>(boost::bind(&ShowHelpTrigger::outputOptions, this, _1)); - exit(1); - } - private: - void outputOptions(const Options * options) const { - fprintf(stdout, " * %s\n", options->name.c_str()); - BOOST_FOREACH(const auto & option, options->allOptions()) { - fprintf(stdout, " * %s - %s\n", option->name().c_str(), option->description().c_str()); - } - } -}; - -DECLARE_OPTIONS(ConsoleEnvironment, "Console options") -("help", new ShowHelpTrigger(), - "Print usage and exit")("h") -("console.platform", Options::value(&reqPlatform), - "Platform")("p") -("console.queryParam", Options::functions( - [](const VariableType & v) { - Glib::ustring vs(v.as<Glib::ustring>()); - queryParams.push_back(QueryParams::value_type(vs.substr(0, vs.find('=')), vs.substr(vs.find('=') + 1))); - }, - boost::bind(&QueryParams::clear, &queryParams)), -"Query parameter")("q") -END_OPTIONS(ConsoleEnvironment); - -Glib::ustring ConsoleEnvironment::reqPlatform; -ConsoleEnvironment::QueryParams ConsoleEnvironment::queryParams; - -ConsoleEnvironment::ConsoleEnvironment() -{ -} - -ConsoleEnvironment::~ConsoleEnvironment() -{ -} - -Glib::ustring -ConsoleEnvironment::getParamQuery(const std::string & p) const -{ - QueryParams::const_iterator i = std::find_if(queryParams.begin(), queryParams.end(), - boost::bind(&boost::algorithm::equals<std::string, std::string>, p, - boost::bind(&ConsoleEnvironment::QueryParams::value_type::first, _1))); - if (i != queryParams.end()) { - return i->second; - } - throw ParamNotFound(p); -} - -const Glib::ustring & -ConsoleEnvironment::platform() const -{ - return reqPlatform; -} - -std::string -ConsoleEnvironment::getServerName() const -{ - struct utsname name; - if (uname(&name)) { - Logger()->messagef(LOG_WARNING, "%s: Unable to determine local host name (%d:%s)", - __PRETTY_FUNCTION__, errno, strerror(errno)); - return "unknown"; - } - else { - return name.nodename; - } -} - -const ConsoleEnvironment::ToDoList & -ConsoleEnvironment::todoList() const -{ - return todolist; -} - diff --git a/project2/console/consoleEnvironment.h b/project2/console/consoleEnvironment.h deleted file mode 100644 index 48ab439..0000000 --- a/project2/console/consoleEnvironment.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef ENVPROC_H -#define ENVPROC_H - -#include <string> -#include <vector> -#include <boost/tuple/tuple.hpp> -#include "environment.h" - -class ConsoleEnvironment : public Environment { - public: - typedef boost::tuple<Glib::ustring, Glib::ustring> ToDo; - typedef std::vector<ToDo> ToDoList; - typedef std::vector<std::pair<std::string, std::string> > QueryParams; - - ConsoleEnvironment(); - virtual ~ConsoleEnvironment(); - - - Glib::ustring getParamQuery(const std::string & idx) const; - std::string getServerName() const; - const ToDoList & todoList() const; - - INITOPTIONS; - private: - const Glib::ustring & platform() const; - - friend class CommandLineArguments; - static Glib::ustring reqPlatform; - static QueryParams queryParams; - static ToDoList todolist; -}; - -#endif diff --git a/project2/console/consolePresenter.cpp b/project2/console/consolePresenter.cpp index 52bface..05285a2 100644 --- a/project2/console/consolePresenter.cpp +++ b/project2/console/consolePresenter.cpp @@ -10,7 +10,7 @@ ConsolePresenter::ConsolePresenter() : } void -ConsolePresenter::init() +ConsolePresenter::init(ExecContext *) { } diff --git a/project2/console/consolePresenter.h b/project2/console/consolePresenter.h index f551063..2a0e9e0 100644 --- a/project2/console/consolePresenter.h +++ b/project2/console/consolePresenter.h @@ -15,7 +15,7 @@ class ConsolePresenter : public Presenter { void addNewArray(const Glib::ustring&, bool objects) const; void finishArray(bool objects) const; void write(const boost::function1<std::ostream *, const std::string &> &) const; - void init(); + void init(ExecContext *); private: mutable unsigned int indent; FileStreamVariableWriter out; diff --git a/project2/console/p2consoleMain.cpp b/project2/console/p2consoleMain.cpp index 57008b6..3c0f473 100644 --- a/project2/console/p2consoleMain.cpp +++ b/project2/console/p2consoleMain.cpp @@ -1,31 +1,18 @@ #include <pch.hpp> -#include "consoleEnvironment.h" -#include "consoleAppEngine.h" -#include "scriptLoader.h" -#include "logger.h" -#include <boost/foreach.hpp> #include <boost/bind.hpp> #include "claOptions.h" +#include "consoleAppEngine.h" int main(int argc, char ** argv) { Plugable::newLoader<OptionsSource, OptionsSource>("", new CommandLineArguments(argc, argv)); - ConsoleEnvironment env; Plugable::onAllComponents(boost::bind(&ComponentLoader::onBegin, _1)); - OptionsSource::loadSources(); - BOOST_FOREACH(const ConsoleEnvironment::ToDo & todo, env.todoList()) { - Plugable::onAllComponents(boost::bind(&ComponentLoader::onBefore, _1)); - Logger()->messagebf(LOG_DEBUG, "%s: Beginning script '%s/%s'", __FUNCTION__, todo.get<0>(), todo.get<1>()); - boost::intrusive_ptr<ConsoleApplicationEngine> app(new ConsoleApplicationEngine(&env, - ScriptReader::resolveScript(todo.get<0>(), todo.get<1>(), false))); + OptionsSource::loadSources([] { return ConsoleApplicationEngine::reqPlatform;} ); - Logger()->messagef(LOG_DEBUG, "%s: Processing file", __FUNCTION__); - app->process(); + ConsoleApplicationEngine app; + app.process(); - Logger()->messagef(LOG_DEBUG, "%s: Complete", __FUNCTION__); - Plugable::onAllComponents(boost::bind(&ComponentLoader::onIteration, _1)); - } Plugable::onAllComponents(boost::bind(&ComponentLoader::onPeriodic, _1)); Plugable::onAllComponents(boost::bind(&ComponentLoader::onIdle, _1)); } diff --git a/project2/console/pch.hpp b/project2/console/pch.hpp index 30db218..4bd02fb 100644 --- a/project2/console/pch.hpp +++ b/project2/console/pch.hpp @@ -3,7 +3,6 @@ #define CONSOLE_PCH #include "consoleAppEngine.h" -#include "consoleEnvironment.h" #include "consolePresenter.h" #include "exceptions.h" #include "iterate.h" diff --git a/project2/files/fileStream.cpp b/project2/files/fileStream.cpp index 762e39b..df39406 100644 --- a/project2/files/fileStream.cpp +++ b/project2/files/fileStream.cpp @@ -21,9 +21,9 @@ class FileStream : public Stream { throw NotSupported(__PRETTY_FUNCTION__); } - void runStream(const Sink & sink) const + void runStream(const Sink & sink, ExecContext * ec) const { - FILE * file = fopen(path(), "r"); + FILE * file = fopen(path(ec), "r"); if (!file) { throw syscall_error(errno); } diff --git a/project2/files/fsFilterMaxDepth.cpp b/project2/files/fsFilterMaxDepth.cpp index f0d685e..089737a 100644 --- a/project2/files/fsFilterMaxDepth.cpp +++ b/project2/files/fsFilterMaxDepth.cpp @@ -13,8 +13,8 @@ class FsRowSpecMaxDepth : public FsRows::SpecBase { maxDepth(boost::lexical_cast<unsigned int>(v)) { } - bool recurse(const FsRows::SearchState * fs) const { - return (std::less<int64_t>()(depth(fs), maxDepth())); + bool recurse(const FsRows::SearchState * fs, ExecContext * ec) const { + return (std::less<int64_t>()(depth(fs), maxDepth(ec))); } Variable maxDepth; }; diff --git a/project2/files/fsFilterName.cpp b/project2/files/fsFilterName.cpp index cc1104f..92279c2 100644 --- a/project2/files/fsFilterName.cpp +++ b/project2/files/fsFilterName.cpp @@ -12,10 +12,10 @@ class FsRowSpecName : public FsRows::SpecBase { pattern(v) { } - bool matches(const FsRows::SearchState * fs) const { + bool matches(const FsRows::SearchState * fs, ExecContext * ec) const { // Based on code written by Jack Handy - jakkhandy@hotmail.com // from http://www.codeproject.com/KB/string/wildcmp.aspx - Glib::ustring patt = pattern(); + Glib::ustring patt = pattern(ec); Glib::ustring::const_iterator wild = patt.begin(); Glib::ustring leaf(curPath(fs).leaf().string()); Glib::ustring::const_iterator string = leaf.begin(); diff --git a/project2/files/fsFilterType.cpp b/project2/files/fsFilterType.cpp index 0d0b27b..ba9ad72 100644 --- a/project2/files/fsFilterType.cpp +++ b/project2/files/fsFilterType.cpp @@ -12,8 +12,8 @@ class FsRowSpecType : public FsRows::SpecBase { typelist(v) { } - bool matches(const FsRows::SearchState * fs) const { - const Glib::ustring types = typelist(); + bool matches(const FsRows::SearchState * fs, ExecContext * ec) const { + const Glib::ustring types = typelist(ec); if (S_ISREG(curStat(fs).st_mode)) { return types.find('f') != Glib::ustring::npos; } diff --git a/project2/files/fsRows.cpp b/project2/files/fsRows.cpp index e56f243..71c0dca 100644 --- a/project2/files/fsRows.cpp +++ b/project2/files/fsRows.cpp @@ -36,8 +36,8 @@ Columns defCols() { } const Columns FsRows::SearchState::col(defCols()); -bool FsRows::SpecBase::recurse(const SearchState *) const { return true; } -bool FsRows::SpecBase::matches(const SearchState *) const { return true; } +bool FsRows::SpecBase::recurse(const SearchState *, ExecContext *) const { return true; } +bool FsRows::SpecBase::matches(const SearchState *, ExecContext *) const { return true; } const boost::filesystem::path & FsRows::SpecBase::curPath(const SearchState * fs) const { return fs->curPath; } unsigned int FsRows::SpecBase::depth(const SearchState * fs) const { return fs->depth; } const struct stat & FsRows::SpecBase::curStat(const SearchState * fs) const { return fs->curStat; } @@ -67,11 +67,11 @@ normalisePath(const std::string & p) } void -FsRows::execute(const Glib::ustring &, const RowProcessor * rp) const +FsRows::execute(const Glib::ustring &, const RowProcessorCallback & rp, ExecContext * ec) const { - SearchState ss(normalisePath(root())); + SearchState ss(normalisePath(root(ec))); ss.specs = this->specs; - Glib::ustring sss = spec(); + Glib::ustring sss = spec(ec); if (!sss.empty()) { SpecSpec s; typedef SpecSpec & (*splitter)(SpecSpec &, const Glib::ustring &, bool (*)(gunichar), boost::algorithm::token_compress_mode_type); @@ -87,11 +87,11 @@ FsRows::execute(const Glib::ustring &, const RowProcessor * rp) const } } } - execute(ss, ss.fsRoot, rp); + execute(ss, ss.fsRoot, rp, ec); } void -FsRows::execute(SearchState & ss, const Path & dir, const RowProcessor * rp) const +FsRows::execute(SearchState & ss, const Path & dir, const RowProcessorCallback & rp, ExecContext * ec) const { ss.depth += 1; try { @@ -102,17 +102,17 @@ FsRows::execute(SearchState & ss, const Path & dir, const RowProcessor * rp) con ss.curPath = itr->path(); lstat(ss.curPathStr.c_str(), &ss.curStat); - if (boost::algorithm::all(ss.specs, boost::bind(&SpecBase::matches, _1, &ss))) { + if (boost::algorithm::all(ss.specs, boost::bind(&SpecBase::matches, _1, &ss, ec))) { ss.process(rp); } - if (S_ISDIR(ss.curStat.st_mode) && boost::algorithm::all(ss.specs, boost::bind(&SpecBase::recurse, _1, &ss))) { - execute(ss, *itr, rp); + if (S_ISDIR(ss.curStat.st_mode) && boost::algorithm::all(ss.specs, boost::bind(&SpecBase::recurse, _1, &ss, ec))) { + execute(ss, *itr, rp, ec); } } } catch (const boost::filesystem::filesystem_error & e) { - if (!ignoreErrors()) { + if (!ignoreErrors(ec)) { throw; } Logger()->messagebf(LOG_WARNING, "%s when processing '%s'", e.what(), dir); diff --git a/project2/files/fsRows.h b/project2/files/fsRows.h index 6b689d3..5988865 100644 --- a/project2/files/fsRows.h +++ b/project2/files/fsRows.h @@ -17,8 +17,8 @@ class FsRows : public RowSet { class SearchState; class SpecBase : public virtual IntrusivePtrBase { public: - virtual bool recurse(const SearchState * fs) const; - virtual bool matches(const SearchState * fs) const; + virtual bool recurse(const SearchState * fs, ExecContext *) const; + virtual bool matches(const SearchState * fs, ExecContext *) const; protected: const boost::filesystem::path & curPath(const SearchState * fs) const; unsigned int depth(const SearchState * fs) const; @@ -52,7 +52,7 @@ class FsRows : public RowSet { const Variable spec; const Variable ignoreErrors; - void execute(const Glib::ustring &, const RowProcessor *) const; + void execute(const Glib::ustring &, const RowProcessorCallback &, ExecContext *) const; class SearchState : public RowState { public: SearchState(const boost::filesystem::path & r); @@ -79,7 +79,7 @@ class FsRows : public RowSet { struct stat curStat; }; protected: - void execute(SearchState &, const Path & dir, const RowProcessor *) const; + void execute(SearchState &, const Path & dir, const RowProcessorCallback &, ExecContext *) const; friend class SpecBase; SpecBases specs; }; diff --git a/project2/files/functions/pwd.cpp b/project2/files/functions/pwd.cpp index ce7b068..644c934 100644 --- a/project2/files/functions/pwd.cpp +++ b/project2/files/functions/pwd.cpp @@ -11,7 +11,7 @@ class Pwd : public VariableImplDyn { VariableImplDyn(e) { } - VariableType value() const + VariableType value(ExecContext *) const { return boost::filesystem::current_path().string(); } diff --git a/project2/files/optionsSource.cpp b/project2/files/optionsSource.cpp index 808d481..437eaf4 100644 --- a/project2/files/optionsSource.cpp +++ b/project2/files/optionsSource.cpp @@ -18,7 +18,7 @@ FileOptions::FileOptions(const Glib::ustring & f) : } void -FileOptions::loadInto(const ConfigConsumer & consume) const { +FileOptions::loadInto(const ConfigConsumer & consume, const Options::CurrentPlatform & platform) const { try { Glib::RefPtr<Glib::IOChannel> cfg = Glib::IOChannel::create_from_file(file, "r"); Glib::ustring line; @@ -52,7 +52,7 @@ FileOptions::loadInto(const ConfigConsumer & consume) const { Glib::ustring val = line.substr(eq + 1); boost::algorithm::trim_if(plat, Glib::Unicode::isspace); boost::algorithm::trim_if(val, Glib::Unicode::isspace); - consume(prefix + name, plat, val); + consume(prefix + name, plat, val, platform); break; } } diff --git a/project2/files/optionsSource.h b/project2/files/optionsSource.h index 5cd5250..e1de4b9 100644 --- a/project2/files/optionsSource.h +++ b/project2/files/optionsSource.h @@ -8,7 +8,7 @@ class FileOptions : public OptionsSource { FileOptions(); FileOptions(const Glib::ustring & file); - void loadInto(const ConfigConsumer & consume) const; + void loadInto(const ConfigConsumer & consume, const Options::CurrentPlatform & platform) const; bool needReload() const; private: diff --git a/project2/files/presenterCache.cpp b/project2/files/presenterCache.cpp index f3c3ea9..09ee9ee 100644 --- a/project2/files/presenterCache.cpp +++ b/project2/files/presenterCache.cpp @@ -2,7 +2,6 @@ #include "../common/exceptions.h" #include "../common/options.h" #include <safeMapFind.h> -#include "../common/environment.h" #include <fcntl.h> #include <attr/xattr.h> #include <sys/stat.h> @@ -92,23 +91,23 @@ class FilePresenterCache : public PresenterCache { ~FilePresenterCache() { } - bool check(time_t scriptMtime) const + bool check(time_t scriptMtime, ExecContext * ec) const { - Key key = getCacheKey(); + Key key = getCacheKey(ec); try { CacheFilePtr f = defaultMapFind(openCaches, key); if (!f) { - f = openCacheFile(key); + f = openCacheFile(key, ec); } struct stat st; safesys<StatCacheFile>(-1, fstat(*f, &st)); if (st.st_nlink == 0) { - f = openCacheFile(key); + f = openCacheFile(key, ec); safesys<StatCacheFile>(-1, fstat(*f, &st)); } if (scriptMtime != 0) { if ((st.st_mtime < (time(NULL) - FilePresenterCache::CacheLife)) || (st.st_mtime < scriptMtime)) { - unlink(getCacheFile().string().c_str()); + unlink(getCacheFile(ec).string().c_str()); openCaches.erase(key); return false; } @@ -161,9 +160,9 @@ class FilePresenterCache : public PresenterCache { return this; } - std::ostream & writeCache(const std::string & ct, const std::string & enc) + std::ostream & writeCache(const std::string & ct, const std::string & enc, ExecContext * ec) { - int fd = safesys<OpenCacheFile>(-1, open(getCacheFile().string().c_str(), + int fd = safesys<OpenCacheFile>(-1, open(getCacheFile(ec).string().c_str(), O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)); safesys<LockCacheFile>(-1, ::flock(fd, LOCK_EX)); safesys<TruncateCacheFile>(-1, ::ftruncate(fd, 0)); @@ -186,23 +185,23 @@ class FilePresenterCache : public PresenterCache { INITOPTIONS; private: - Key getCacheKey() const + Key getCacheKey(ExecContext * ec) const { Key key; - key.get<0>().push_back(idProvider->value()); + key.get<0>().push_back(idProvider->value(ec)); return key; } - CacheFilePtr openCacheFile(const Key & key) const + CacheFilePtr openCacheFile(const Key & key, ExecContext * ec) const { - CacheFilePtr c = new CacheFile(safesys<OpenCacheFile>(-1, open(getCacheFile().string().c_str(), O_RDONLY))); + CacheFilePtr c = new CacheFile(safesys<OpenCacheFile>(-1, open(getCacheFile(ec).string().c_str(), O_RDONLY))); openCaches[key] = c; return c; } - boost::filesystem::path getCacheFile() const + boost::filesystem::path getCacheFile(ExecContext * ec) const { boost::filesystem::path cache; cache = Store; - cache /= idProvider->value(); + cache /= idProvider->value(ec); boost::filesystem::create_directories(cache); cache /= FileName; return cache; diff --git a/project2/files/writeStream.cpp b/project2/files/writeStream.cpp index 6e49e10..954ec8b 100644 --- a/project2/files/writeStream.cpp +++ b/project2/files/writeStream.cpp @@ -16,16 +16,16 @@ class WriteStream : public Task { s->script->loader.addLoadTarget(s, Storer::into<ElementLoader>(&stream)); } - void execute() const + void execute(ExecContext * ec) const { - std::fstream ddd(path().as<std::string>(), std::fstream::trunc | std::fstream::out); + std::fstream ddd(path(ec).as<std::string>(), std::fstream::trunc | std::fstream::out); if (!ddd.good()) { - throw OpenTargetFile(path()); + throw OpenTargetFile(path(ec)); } stream->runStream([&ddd](const char * data, size_t len) -> size_t { ddd.write(data, len); return len; - }); + }, ec); } const Variable path; diff --git a/project2/json/presenter-p.cpp b/project2/json/presenter-p.cpp index 3cb5bf8..92ba8c1 100644 --- a/project2/json/presenter-p.cpp +++ b/project2/json/presenter-p.cpp @@ -3,16 +3,16 @@ class Json_P_Presenter : public JsonPresenter { public: - Json_P_Presenter(ScriptNodePtr s, ObjectSource os) : + Json_P_Presenter(ScriptNodePtr s, ObjectSource os, ExecContext *) : JsonPresenter(s, os, "application/json-p"), Callback(s, "callback") { } - void writeTo(std::ostream & o, const std::string & encoding) const + void writeTo(std::ostream & o, const std::string & encoding, ExecContext * ec) const { - o << Callback().as<Glib::ustring>(); + o << Callback(ec).as<Glib::ustring>(); o << "("; - JsonPresenter::writeTo(o, encoding); + JsonPresenter::writeTo(o, encoding, ec); o << ");"; } diff --git a/project2/json/presenter.cpp b/project2/json/presenter.cpp index 111ae5c..2eabeac 100644 --- a/project2/json/presenter.cpp +++ b/project2/json/presenter.cpp @@ -15,7 +15,7 @@ JsonPresenter::JsonPresenter(ScriptNodePtr s, ObjectSource os, const Glib::ustri returnObject(s, "object", Null()) { } -JsonPresenter::JsonPresenter(ScriptNodePtr s, ObjectSource os) : +JsonPresenter::JsonPresenter(ScriptNodePtr s, ObjectSource os, ExecContext *) : TransformSource(s, os), MultiRowSetPresenter(os), ContentPresenter("application/json"), @@ -25,7 +25,7 @@ JsonPresenter::JsonPresenter(ScriptNodePtr s, ObjectSource os) : } void -JsonPresenter::init() +JsonPresenter::init(ExecContext *) { while (!curRowSet.empty()) { curRowSet.pop(); @@ -131,13 +131,13 @@ JsonPresenter::getContentClass() const } void -JsonPresenter::writeTo(std::ostream & o, const std::string & encoding) const +JsonPresenter::writeTo(std::ostream & o, const std::string & encoding, ExecContext * ec) const { - if (returnObject().isNull()) { + if (returnObject(ec).isNull()) { serializeObject(object, o, encoding); } else { - serializeValue(*object[returnObject()], o, encoding); + serializeValue(*object[returnObject(ec)], o, encoding); } } diff --git a/project2/json/presenter.h b/project2/json/presenter.h index 8d5af2a..5ccecb2 100644 --- a/project2/json/presenter.h +++ b/project2/json/presenter.h @@ -9,9 +9,9 @@ class JsonPresenter : public MultiRowSetPresenter, public ContentPresenter, public SourceOf<json::Object>, public WritableContent, public SourceOf<WritableContent> { public: - JsonPresenter(ScriptNodePtr s, ObjectSource); + JsonPresenter(ScriptNodePtr s, ObjectSource, ExecContext *); JsonPresenter(ScriptNodePtr s, ObjectSource, const Glib::ustring &); - void init(); + void init(ExecContext * ec); typedef void (JsonPresenter::*ValueAdder)(const Glib::ustring &, const VariableType &) const; typedef std::stack<ValueAdder> ValueAdderStack; mutable ValueAdderStack vaStack; @@ -29,7 +29,7 @@ class JsonPresenter : public MultiRowSetPresenter, public ContentPresenter, publ operator const WritableContent * () const; Glib::ustring getContentType() const; Class getContentClass() const; - void writeTo(std::ostream & o, const std::string & encoding) const; + void writeTo(std::ostream & o, const std::string & encoding, ExecContext *) const; private: Variable returnObject; diff --git a/project2/mail/sendmailTask.cpp b/project2/mail/sendmailTask.cpp index 10bfbdd..bd4094e 100644 --- a/project2/mail/sendmailTask.cpp +++ b/project2/mail/sendmailTask.cpp @@ -4,7 +4,6 @@ #include <boost/bind.hpp> #include "scriptLoader.h" #include "viewHost.h" -#include "environment.h" #include <stdexcept> #include <libesmtp.h> #include "xmlPresenter.h" @@ -136,17 +135,17 @@ class TransformWritableContentToEmail : public TransformImpl<WritableContent, Se TransformWritableContentToEmail() : encoding(SendMailTask::defaultMailEncoding) { } - void transform(const WritableContent * wc, SendMailTask::Parts * parts) const + void transform(const WritableContent * wc, SendMailTask::Parts * parts, ExecContext * ec) const { parts->parts.insert(new BoundaryBegin(wc->getContentType(), encoding, wc->getContentClass())); std::stringstream str; - wc->writeTo(str, encoding); + wc->writeTo(str, encoding, ec); parts->parts.insert(new MimeContent(str.str(), wc->getContentClass())); SendMailTask::MailPart::mimeIdx += 1; } - void configure(ScriptNodePtr s) + void configure(ScriptNodePtr s, ExecContext * ec) { - s->applyValue("encoding", encoding); + s->applyValue("encoding", encoding, ec); } private: VariableType encoding; @@ -162,16 +161,16 @@ class EmailViewHost : public ViewHost { parts(ps), n(node) { } - MultiRowSetPresenterPtr getPresenter() const { + MultiRowSetPresenterPtr getPresenter(ExecContext * ec) const { if (!presenter) { Logger()->message(LOG_DEBUG, "Building default email transform chain"); - XmlPresenterPtr xpp = new XmlPresenter(n, Default); + XmlPresenterPtr xpp = new XmlPresenter(n, Default, ec); HtmlDocument * hd = new HtmlDocument(n, Default); TextDocument * td = new TextDocument(n, Default); - xpp->addTarget(hd, n); - hd->addTarget(parts); - hd->addTarget(td, n); - td->addTarget(parts); + xpp->addTarget(hd, ec, n); + hd->addTarget(parts, ec, NULL); + hd->addTarget(td, ec, n); + td->addTarget(parts, ec, NULL); presenter = xpp; } return presenter; @@ -183,29 +182,29 @@ class EmailViewHost : public ViewHost { }; void -SendMailTask::execute() const +SendMailTask::execute(ExecContext * ec) const { boost::intrusive_ptr<Parts> parts = new Parts(); MailPart::mimeIdx = 0; - parts->parts.insert(new Header("To", to)); - parts->parts.insert(new Header("From", from)); - parts->parts.insert(new Header("Subject", subject)); + parts->parts.insert(new Header("To", to(ec))); + parts->parts.insert(new Header("From", from(ec))); + parts->parts.insert(new Header("Subject", subject(ec))); parts->parts.insert(new Header("Content-Type", "multipart/alternative; boundary=\"<<divider>>\"")); parts->parts.insert(new Header("MIME-Version", "1.0")); parts->parts.insert(new Header("Content-Transfer-Encoding", "binary")); parts->parts.insert(new BoundaryEnd()); - ViewHostPtr vsp = new EmailViewHost(parts, ScriptReader::resolveScript("emails", present(), false)->root()); - vsp->executeViews(); - vsp->doTransforms(); + ViewHostPtr vsp = new EmailViewHost(parts, ScriptReader::resolveScript("emails", present(ec), false)->root()); + vsp->executeViews(ec); + vsp->doTransforms(ec); parts->part = parts->parts.begin(); // Write email smtp_session_t session = smtp_create_session(); smtp_message_t message = smtp_add_message(session); - smtp_set_server(session, server()); + smtp_set_server(session, server(ec)); smtp_set_header(message, "To", NULL, NULL); - smtp_add_recipient(message, to()); + smtp_add_recipient(message, to(ec)); smtp_set_messagecb(message, writeMail, parts.get()); if (!smtp_start_session(session)) { char buf[BUFSIZ]; diff --git a/project2/mail/sendmailTask.h b/project2/mail/sendmailTask.h index 20435e8..035fe2b 100644 --- a/project2/mail/sendmailTask.h +++ b/project2/mail/sendmailTask.h @@ -34,7 +34,7 @@ class SendMailTask : public Task { SendMailTask(ScriptNodePtr p); virtual ~SendMailTask(); - virtual void execute() const; + virtual void execute(ExecContext * ec) const; INITOPTIONS; protected: diff --git a/project2/processes/processStream.cpp b/project2/processes/processStream.cpp index 1a853e4..f2c678f 100644 --- a/project2/processes/processStream.cpp +++ b/project2/processes/processStream.cpp @@ -21,13 +21,13 @@ class ProcessStream : public Stream, IHaveParameters { { } - void runStream(const Sink & sink) const + void runStream(const Sink & sink, ExecContext * ec) const { const char * callProc[parameters.size() + 2]; - callProc[0] = path(); + callProc[0] = path(ec); int pidx = 1; BOOST_FOREACH(const Parameters::value_type & p, parameters) { - callProc[pidx++] = p.second(); + callProc[pidx++] = p.second(ec); } callProc[pidx] = NULL; int fds[2]; diff --git a/project2/regex/regexRows.cpp b/project2/regex/regexRows.cpp index e1b18f9..514d47a 100644 --- a/project2/regex/regexRows.cpp +++ b/project2/regex/regexRows.cpp @@ -19,11 +19,11 @@ RegexRows::~RegexRows() } void -RegexRows::execute(const Glib::ustring&, const RowProcessor * rp) const +RegexRows::execute(const Glib::ustring&, const RowProcessorCallback & rp, ExecContext * ec) const { - Glib::RefPtr<Glib::Regex> reg = Glib::Regex::create(regex(), Glib::REGEX_CASELESS | Glib::REGEX_DOTALL); + Glib::RefPtr<Glib::Regex> reg = Glib::Regex::create(regex(ec), Glib::REGEX_CASELESS | Glib::REGEX_DOTALL); Glib::MatchInfo matches; - if (reg->match(sourceText(), matches)) { + if (reg->match(sourceText(ec), matches)) { ColumnValues cv(this); do { unsigned int cols = std::min<unsigned int>(matches.get_match_count(), cv.rowSet->columns.size() + 1); diff --git a/project2/regex/regexRows.h b/project2/regex/regexRows.h index 4d94f52..1a4ddb1 100644 --- a/project2/regex/regexRows.h +++ b/project2/regex/regexRows.h @@ -10,7 +10,7 @@ class RegexRows : public DefinedColumns, public RowSet { RegexRows(ScriptNodePtr p); ~RegexRows(); - void execute(const Glib::ustring&, const RowProcessor*) const; + void execute(const Glib::ustring&, const RowProcessorCallback &, ExecContext *) const; private: const Variable sourceText; diff --git a/project2/regex/regexTest.cpp b/project2/regex/regexTest.cpp index 93ee2f7..59dca68 100644 --- a/project2/regex/regexTest.cpp +++ b/project2/regex/regexTest.cpp @@ -18,9 +18,9 @@ RegexTest::~RegexTest() } bool -RegexTest::passes() const +RegexTest::passes(ExecContext * ec) const { - Glib::RefPtr<Glib::Regex> reg = Glib::Regex::create(regex()); - return reg->match(applyTo()); + Glib::RefPtr<Glib::Regex> reg = Glib::Regex::create(regex(ec)); + return reg->match(applyTo(ec)); } diff --git a/project2/regex/regexTest.h b/project2/regex/regexTest.h index f3459bc..00038a1 100644 --- a/project2/regex/regexTest.h +++ b/project2/regex/regexTest.h @@ -10,7 +10,7 @@ class RegexTest : public Test { RegexTest(ScriptNodePtr p); virtual ~RegexTest(); - bool passes() const; + bool passes(ExecContext * ec) const; const Variable applyTo; const Variable regex; diff --git a/project2/sql/rdbmsDataSource.cpp b/project2/sql/rdbmsDataSource.cpp index 691daab..de20844 100644 --- a/project2/sql/rdbmsDataSource.cpp +++ b/project2/sql/rdbmsDataSource.cpp @@ -43,10 +43,10 @@ RdbmsDataSource::DSNSet RdbmsDataSource::changedDSNs; RdbmsDataSource::RdbmsDataSource(ScriptNodePtr p) : DataSource(p), masterDsn(p->child("masterdsn")), - preferLocal(p->value("preferlocal", true)) + preferLocal(p->value("preferlocal", true, NULL)) { BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("readonly")) { - roDSNs.insert(ReadonlyDSNs::value_type(node->value("host").as<std::string>(), node)); + roDSNs.insert(ReadonlyDSNs::value_type(node->value("host", NULL).as<std::string>(), node)); } } @@ -194,8 +194,8 @@ RdbmsDataSource::RdbmsConnection::isExpired() const } RdbmsDataSource::ConnectionInfo::ConnectionInfo(ScriptNodePtr node) : - dsn(node->value("dsn").as<std::string>()), - typeId(Plugable::getLoader<ConnectionLoader, UnknownConnectionProvider>(node->value("provider"))) + dsn(node->value("dsn", NULL).as<std::string>()), + typeId(Plugable::getLoader<ConnectionLoader, UnknownConnectionProvider>(node->value("provider", NULL))) { } diff --git a/project2/sql/sqlBulkLoad.cpp b/project2/sql/sqlBulkLoad.cpp index a8283b9..8787d3e 100644 --- a/project2/sql/sqlBulkLoad.cpp +++ b/project2/sql/sqlBulkLoad.cpp @@ -20,17 +20,17 @@ class SqlBulkLoad : public Task { void loadComplete(const CommonObjects * co) { - db = co->dataSource<RdbmsDataSource>(dataSource()); + db = co->dataSource<RdbmsDataSource>(dataSource(NULL)); } - void execute() const + void execute(ExecContext * ec) const { const DB::Connection & wdb = db->getWritable(); - wdb.beginBulkUpload(targetTable(), extras()); + wdb.beginBulkUpload(targetTable(ec), extras(ec)); ScopeObject tidy([]{}, [&]{ wdb.endBulkUpload(NULL); }, [&]{ wdb.endBulkUpload("Stack unwind in progress"); }); - stream->runStream(boost::bind(&DB::Connection::bulkUploadData, &wdb, _1, _2)); + stream->runStream(boost::bind(&DB::Connection::bulkUploadData, &wdb, _1, _2), ec); } const Variable dataSource; diff --git a/project2/sql/sqlCache.cpp b/project2/sql/sqlCache.cpp index ba8dfb5..66e9288 100644 --- a/project2/sql/sqlCache.cpp +++ b/project2/sql/sqlCache.cpp @@ -85,7 +85,7 @@ class SqlCache : public Cache { friend class SqlCacheRowSet; const SqlCacheRowSet * sc; }; - void execute(const Glib::ustring&, const RowProcessor * rp) const { + void execute(const Glib::ustring&, const RowProcessorCallback & rp, ExecContext *) const { SqlCacheRowState ss(this); HandleAsVariableType h; do { @@ -125,7 +125,7 @@ class SqlCache : public Cache { mutable int64_t cacheId; }; - RowSetCPtr getCachedRowSet(const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) const + RowSetCPtr getCachedRowSet(ExecContext * ec, const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) const { Buffer sql; sql.appendf("SELECT r.* \ @@ -136,12 +136,12 @@ class SqlCache : public Cache { HeaderTable.c_str(), HeaderTable.c_str(), n.c_str(), f.c_str(), HeaderTable.c_str(),n.c_str(), f.c_str()); - applyKeys(boost::bind(appendKeyAnds, &sql, _1), ps); + applyKeys(ec, boost::bind(appendKeyAnds, &sql, _1), ps); sql.appendf(" ORDER BY r.p2_cacheid DESC, r.p2_row"); SelectPtr gh(db->getReadonly().newSelectCommand(sql)); unsigned int offset = 0; gh->bindParamT(offset++, time(NULL) - CacheLife); - applyKeys(boost::bind(bindKeyValues, gh.get(), &offset, _2), ps); + applyKeys(ec, boost::bind(bindKeyValues, gh.get(), &offset, _2), ps); if (gh->fetch()) { return new SqlCacheRowSet(gh); } @@ -202,7 +202,7 @@ class SqlCache : public Cache { mutable Values cols, attrs; }; - RowSetPresenterPtr openFor(const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) + RowSetPresenterPtr openFor(ExecContext * ec, const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) { Buffer sp; sp.appendf("SAVEPOINT sp%p", this); @@ -218,19 +218,19 @@ class SqlCache : public Cache { Buffer sql; sql.appendf("INSERT INTO %s_%s_%s(", HeaderTable.c_str(), n.c_str(), f.c_str()); unsigned int offset = 0; - applyKeys(boost::bind(appendKeyCols, &sql, &offset, _1), ps); + applyKeys(ec, boost::bind(appendKeyCols, &sql, &offset, _1), ps); sql.appendf(") VALUES("); offset = 0; - applyKeys(boost::bind(appendKeyBinds, &sql, &offset), ps); + applyKeys(ec, boost::bind(appendKeyBinds, &sql, &offset), ps); sql.appendf(")"); ModifyPtr m(db->getWritable().newModifyCommand(sql)); offset = 0; - applyKeys(boost::bind(bindKeyValues, m.get(), &offset, _2), ps); + applyKeys(ec, boost::bind(bindKeyValues, m.get(), &offset, _2), ps); m->execute(); return new SqlCachePresenter(n, f, db); } - void save(const Glib::ustring & , const Glib::ustring & , const IHaveParameters * ) + void save(ExecContext *, const Glib::ustring & , const Glib::ustring & , const IHaveParameters * ) { Buffer sp; sp.appendf("RELEASE SAVEPOINT sp%p", this); @@ -238,7 +238,7 @@ class SqlCache : public Cache { s->execute(); } - void discard(const Glib::ustring & , const Glib::ustring & , const IHaveParameters * ) + void discard(ExecContext *, const Glib::ustring & , const Glib::ustring & , const IHaveParameters * ) { Buffer sp; sp.appendf("ROLLBACK TO SAVEPOINT sp%p", this); diff --git a/project2/sql/sqlMergeTask.cpp b/project2/sql/sqlMergeTask.cpp index 0b19c5e..c5eb93c 100644 --- a/project2/sql/sqlMergeTask.cpp +++ b/project2/sql/sqlMergeTask.cpp @@ -27,10 +27,10 @@ class SqlMergeInsert : IHaveParameters, public Task { Task(p), insert(NULL) { } - void execute() const { + void execute(ExecContext * ec) const { unsigned int col = 0; BOOST_FOREACH(const Parameters::value_type & v, parameters) { - boost::apply_visitor<const SqlVariableBinder, const VariableType>(SqlVariableBinder(insert, col++), v.second); + boost::apply_visitor<const SqlVariableBinder, const VariableType>(SqlVariableBinder(insert, col++), v.second(ec)); } insert->execute(); } @@ -59,26 +59,26 @@ SqlMergeTask::SqlMergeTask(ScriptNodePtr p) : insCmd(NULL), destdb(NULL), dataSource(p, "datasource"), - dtable(p->value("targettable").as<std::string>()), + dtable(p->value("targettable", NULL).as<std::string>()), dtablet(stringf("tmp_%s_%d", dtable.c_str(), getpid())) { p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&sources)); - if (!sources.empty() && useView()) { + if (!sources.empty() && useView(NULL)) { throw NotSupported("useview not supported with iterate fillers"); } BOOST_FOREACH(ScriptNodePtr e, p->childrenIn("columns")) { TargetColumnPtr tcp(new TargetColumn(e->get_name())); - tcp->maptable = e->value("maptable", "").as<std::string>(); + tcp->maptable = e->value("maptable", "", NULL).as<std::string>(); if (!tcp->maptable.empty()) { - if (useView()) { + if (useView(NULL)) { throw NotSupported("useview not supported with mapped columns"); } - tcp->mapcolumn = e->value("mapcolumn").as<std::string>(); + tcp->mapcolumn = e->value("mapcolumn", NULL).as<std::string>(); } cols.insert(tcp); - tcp->isKey = e->value("key", false); + tcp->isKey = e->value("key", false, NULL); if (tcp->isKey) { keys.insert(tcp->column); } @@ -97,7 +97,7 @@ SqlMergeTask::~SqlMergeTask() void SqlMergeTask::loadComplete(const CommonObjects * co) { - destdb = &co->dataSource<RdbmsDataSource>(dataSource())->getWritable(); + destdb = &co->dataSource<RdbmsDataSource>(dataSource(NULL))->getWritable(); insCmd = insertCommand(); BOOST_FOREACH(const Sources::value_type & i, sources) { attach(i, insCmd); @@ -116,16 +116,37 @@ SqlMergeTask::TargetColumn::Sort::operator()(const TargetColumnPtr & a, const Ta return a->column < b->column; } +class MergeWhere : public TablePatch::WhereProvider { + public: + MergeWhere(DynamicSql::SqlCommand * u, ExecContext * e) : + ec(e), + updateWhere(u) + { + } + void appendWhere(Buffer * buf) const + { + buf->appendf(" AND %s ", updateWhere->getSqlFor("").c_str()); + } + void bindWhere(DB::Command * cmd) const + { + unsigned int off = 0; + updateWhere->bindParams(ec, cmd, off); + } + private: + ExecContext * ec; + const DynamicSql::SqlCommand * updateWhere; +}; + void -SqlMergeTask::execute() const +SqlMergeTask::execute(ExecContext * ec) const { createTempTable(); - if (earlyKeys()) { + if (earlyKeys(NULL)) { createTempKey(); - copyToTempTable(); + copyToTempTable(ec); } else { - copyToTempTable(); + copyToTempTable(ec); createTempKey(); } std::set<std::string> colNames; @@ -133,20 +154,21 @@ SqlMergeTask::execute() const colNames.insert(c->column); } TablePatch tp(*destdb, dtablet, dtable, colNames); - tp.doDelete = doDelete(); - tp.doUpdate = doUpdate(); - tp.doInsert = doInsert(); + tp.doDelete = doDelete(NULL); + tp.doUpdate = doUpdate(NULL); + tp.doInsert = doInsert(NULL); BOOST_FOREACH(const Keys::value_type & k, keys) { tp.addKey(k); } - tp.patch(updateWhere ? this : NULL, patchOrder()); + MergeWhere mw(updateWhere.get(), ec); + tp.patch(updateWhere ? &mw : NULL, patchOrder(NULL)); dropTempTable(); } void SqlMergeTask::createTempTable() const { - if (useView()) { + if (useView(NULL)) { DB::ModifyCommand * cv = destdb->newModifyCommand(stringf( "CREATE VIEW %s AS %s", dtablet.c_str(), @@ -179,7 +201,7 @@ SqlMergeTask::dropTempTable() const { if (tempTableCreated) { DB::ModifyCommand * d; - if (useView()) { + if (useView(NULL)) { d = destdb->newModifyCommand("DROP VIEW " + dtablet); } else { @@ -192,7 +214,7 @@ SqlMergeTask::dropTempTable() const void SqlMergeTask::createTempKey() const { - if (useView()) return; + if (useView(NULL)) return; /* Primary key */ Buffer idx; idx.appendf("ALTER TABLE %s ADD CONSTRAINT pk_%s PRIMARY KEY(%s)", @@ -244,10 +266,10 @@ class Populate : public NoOutputExecute { cmd(c) { } - void execute() const + void execute(ExecContext * ec) const { unsigned int idx = 0; - RowState::Stack().back()->foreachColumn(boost::bind(&Populate::bind, this, boost::ref(idx), _3)); + RowState::Stack().back()->foreachColumn(ec, boost::bind(&Populate::bind, this, boost::ref(idx), _3)); cmd->execute(); } private: @@ -285,13 +307,13 @@ attach(boost::intrusive_ptr<IHaveSubTasks> i, DB::ModifyCommand * insert) } void -SqlMergeTask::copyToTempTable() const +SqlMergeTask::copyToTempTable(ExecContext * ec) const { - if (useView()) { + if (useView(NULL)) { return; } BOOST_FOREACH(const Sources::value_type & i, sources) { - i->execute(); + i->execute(ec); } if (sqlCommand) { Buffer ins; @@ -312,7 +334,7 @@ SqlMergeTask::copyToTempTable() const ins.appendf(" FROM (%s) tmp_src", sqlCommand->getSqlFor("").c_str()); DB::ModifyCommand * cttt = destdb->newModifyCommand(ins); unsigned int off = 0; - sqlCommand->bindParams(cttt, off); + sqlCommand->bindParams(ec, cttt, off); cttt->execute(); delete cttt; } @@ -334,16 +356,3 @@ SqlMergeTask::copyToTempTable() const } } -void -SqlMergeTask::appendWhere(Buffer * buf) const -{ - buf->appendf(" AND %s ", updateWhere->getSqlFor("").c_str()); -} - -void -SqlMergeTask::bindWhere(DB::Command * cmd) const -{ - unsigned int off = 0; - updateWhere->bindParams(cmd, off); -} - diff --git a/project2/sql/sqlMergeTask.h b/project2/sql/sqlMergeTask.h index b63c277..6b74ccd 100644 --- a/project2/sql/sqlMergeTask.h +++ b/project2/sql/sqlMergeTask.h @@ -16,7 +16,7 @@ #include <list> /// Project2 component merge arbitrary data into an RDBMS table -class SqlMergeTask : public Task, public TablePatch::WhereProvider { +class SqlMergeTask : public Task { public: typedef std::string Table; typedef std::string Column; @@ -44,7 +44,7 @@ class SqlMergeTask : public Task, public TablePatch::WhereProvider { virtual ~SqlMergeTask(); virtual void loadComplete(const CommonObjects *); - void execute() const; + void execute(ExecContext *) const; Columns cols; Keys keys; Keys indexes; @@ -57,12 +57,10 @@ class SqlMergeTask : public Task, public TablePatch::WhereProvider { const Variable doInsert; private: - virtual void copyToTempTable() const; + virtual void copyToTempTable(ExecContext * ec) const; void createTempTable() const; void dropTempTable() const; void createTempKey() const; - void appendWhere(Buffer *) const; - void bindWhere(DB::Command *) const; mutable bool tempTableCreated; typedef ANONSTORAGEOF(Iterate) Sources; diff --git a/project2/sql/sqlRows.cpp b/project2/sql/sqlRows.cpp index 83763dd..f723269 100644 --- a/project2/sql/sqlRows.cpp +++ b/project2/sql/sqlRows.cpp @@ -28,7 +28,7 @@ SqlRows::~SqlRows() void SqlRows::loadComplete(const CommonObjects * co) { - db = co->dataSource<RdbmsDataSource>(dataSource()); + db = co->dataSource<RdbmsDataSource>(dataSource(NULL)); } SqlRows::SqlState::SqlState(SelectPtr s) : @@ -48,11 +48,11 @@ SqlRows::SqlState::getColumns() const } void -SqlRows::execute(const Glib::ustring & filter, const RowProcessor * rp) const +SqlRows::execute(const Glib::ustring & filter, const RowProcessorCallback & rp, ExecContext * ec) const { unsigned int offset = 0; SqlState ss(SelectPtr(db->getReadonly().newSelectCommand(sqlCommand.getSqlFor(filter)))); - sqlCommand.bindParams(ss.query.get(), offset); + sqlCommand.bindParams(ec, ss.query.get(), offset); while (ss.query->fetch()) { HandleAsVariableType h; if (ss.fields.empty()) { diff --git a/project2/sql/sqlRows.h b/project2/sql/sqlRows.h index 7ed5d3f..6f78dcd 100644 --- a/project2/sql/sqlRows.h +++ b/project2/sql/sqlRows.h @@ -16,7 +16,7 @@ class SqlRows : public RowSet { SqlRows(ScriptNodePtr p); ~SqlRows(); - void execute(const Glib::ustring &, const RowProcessor *) const; + void execute(const Glib::ustring &, const RowProcessorCallback &, ExecContext *) const; virtual void loadComplete(const CommonObjects *); const Variable dataSource; diff --git a/project2/sql/sqlTask.cpp b/project2/sql/sqlTask.cpp index 03f67de..80ea08e 100644 --- a/project2/sql/sqlTask.cpp +++ b/project2/sql/sqlTask.cpp @@ -29,24 +29,24 @@ SqlTask::~SqlTask() void SqlTask::loadComplete(const CommonObjects * co) { - db = co->dataSource<RdbmsDataSource>(dataSource()); + db = co->dataSource<RdbmsDataSource>(dataSource(NULL)); } void -SqlTask::execute() const +SqlTask::execute(ExecContext * ec) const { boost::shared_ptr<DB::ModifyCommand> modify = boost::shared_ptr<DB::ModifyCommand>( - db->getWritable().newModifyCommand(sqlCommand.getSqlFor(filter()))); + db->getWritable().newModifyCommand(sqlCommand.getSqlFor(filter(NULL)))); unsigned int offset = 0; - sqlCommand.bindParams(modify.get(), offset); + sqlCommand.bindParams(ec, modify.get(), offset); if (modify->execute() == 0) { BOOST_FOREACH(const SubNOEs::value_type & sq, noChangesNOEs) { - sq->execute(); + sq->execute(ec); } } else { BOOST_FOREACH(const SubNOEs::value_type & sq, changesNOEs) { - sq->execute(); + sq->execute(ec); } } } diff --git a/project2/sql/sqlTask.h b/project2/sql/sqlTask.h index b0d0d27..94901a9 100644 --- a/project2/sql/sqlTask.h +++ b/project2/sql/sqlTask.h @@ -16,7 +16,7 @@ class SqlTask : public Task { SqlTask(ScriptNodePtr p); virtual ~SqlTask(); virtual void loadComplete(const CommonObjects *); - virtual void execute() const; + virtual void execute(ExecContext * ec) const; const Variable dataSource; const Variable filter; diff --git a/project2/sql/sqlTest.cpp b/project2/sql/sqlTest.cpp index f45b2c9..2723d8e 100644 --- a/project2/sql/sqlTest.cpp +++ b/project2/sql/sqlTest.cpp @@ -32,7 +32,7 @@ SqlTest::~SqlTest() void SqlTest::loadComplete(const CommonObjects * co) { - db = co->dataSource<RdbmsDataSource>(dataSource()); + db = co->dataSource<RdbmsDataSource>(dataSource(NULL)); } class HandleDoCompare : public DB::HandleField { @@ -88,13 +88,13 @@ class HandleDoCompare : public DB::HandleField { std::string testOp; }; bool -SqlTest::passes() const +SqlTest::passes(ExecContext * ec) const { boost::shared_ptr<DB::SelectCommand> query = boost::shared_ptr<DB::SelectCommand>( - db->getWritable().newSelectCommand(sqlCommand.getSqlFor(filter()))); + db->getWritable().newSelectCommand(sqlCommand.getSqlFor(filter(NULL)))); unsigned int offset = 0; - sqlCommand.bindParams(query.get(), offset); - HandleDoCompare h(testValue, testOp()); + sqlCommand.bindParams(ec, query.get(), offset); + HandleDoCompare h(testValue(ec), testOp(ec)); while (query->fetch()) { (*query)[0].apply(h); } diff --git a/project2/sql/sqlTest.h b/project2/sql/sqlTest.h index f722424..af843d1 100644 --- a/project2/sql/sqlTest.h +++ b/project2/sql/sqlTest.h @@ -14,7 +14,7 @@ class SqlTest : public Test { virtual ~SqlTest(); virtual void loadComplete(const CommonObjects *); - bool passes() const; + bool passes(ExecContext *) const; const Variable dataSource; const Variable filter; diff --git a/project2/sql/sqlWriter.cpp b/project2/sql/sqlWriter.cpp index 1220211..5278759 100644 --- a/project2/sql/sqlWriter.cpp +++ b/project2/sql/sqlWriter.cpp @@ -64,15 +64,15 @@ DynamicSql::SqlCommand::writeSql(Glib::ustring & sql) const } void -DynamicSql::SqlCommand::bindParams(DB::Command * cmd, unsigned int & offset) const +DynamicSql::SqlCommand::bindParams(ExecContext * ec, DB::Command * cmd, unsigned int & offset) const { BOOST_FOREACH(const SqlWriterPtr & w, writers) { - w->bindParams(cmd, offset); + w->bindParams(ec, cmd, offset); } } DynamicSql::SqlFilter::SqlFilter(ScriptNodePtr p) : - name(p->value("name").as<Glib::ustring>()), + name(p->value("name", NULL).as<Glib::ustring>()), active(false) { p->composeWithCallbacks( @@ -91,11 +91,11 @@ DynamicSql::SqlFilter::writeSql(Glib::ustring & sql) const } void -DynamicSql::SqlFilter::bindParams(DB::Command * cmd, unsigned int & offset) const +DynamicSql::SqlFilter::bindParams(ExecContext * ec, DB::Command * cmd, unsigned int & offset) const { if (active) { BOOST_FOREACH(const SqlWriterPtr & w, writers) { - w->bindParams(cmd, offset); + w->bindParams(ec, cmd, offset); } } } @@ -112,9 +112,9 @@ DynamicSql::SqlParameter::writeSql(Glib::ustring & sql) const } void -DynamicSql::SqlParameter::bindParams(DB::Command * cmd, unsigned int & offset) const +DynamicSql::SqlParameter::bindParams(ExecContext * ec, DB::Command * cmd, unsigned int & offset) const { - boost::apply_visitor<const SqlVariableBinder, const VariableType>(SqlVariableBinder(cmd, offset++), (*this)); + boost::apply_visitor<const SqlVariableBinder, const VariableType>(SqlVariableBinder(cmd, offset++), (*this)(ec)); } DynamicSql::SqlText::SqlText(const Glib::ustring & n) : @@ -129,7 +129,7 @@ DynamicSql::SqlText::writeSql(Glib::ustring & sql) const } void -DynamicSql::SqlText::bindParams(DB::Command *, unsigned int &) const +DynamicSql::SqlText::bindParams(ExecContext *, DB::Command *, unsigned int &) const { } diff --git a/project2/sql/sqlWriter.h b/project2/sql/sqlWriter.h index 4b57fa9..5eef9ac 100644 --- a/project2/sql/sqlWriter.h +++ b/project2/sql/sqlWriter.h @@ -17,13 +17,13 @@ namespace DynamicSql { SqlWriter(); virtual ~SqlWriter(); virtual void writeSql(Glib::ustring & sql) const = 0; - virtual void bindParams(DB::Command *, unsigned int & offset) const = 0; + virtual void bindParams(ExecContext *, DB::Command *, unsigned int & offset) const = 0; }; class SqlText : public SqlWriter { public: SqlText(const Glib::ustring &); virtual void writeSql(Glib::ustring & sql) const; - virtual void bindParams(DB::Command *, unsigned int & offset) const; + virtual void bindParams(ExecContext *, DB::Command *, unsigned int & offset) const; const Glib::ustring text; }; @@ -31,13 +31,13 @@ namespace DynamicSql { public: SqlParameter(ScriptNodePtr); virtual void writeSql(Glib::ustring & sql) const; - virtual void bindParams(DB::Command *, unsigned int & offset) const; + virtual void bindParams(ExecContext *, DB::Command *, unsigned int & offset) const; }; class SqlFilter : public SqlWriter { public: SqlFilter(ScriptNodePtr); virtual void writeSql(Glib::ustring & sql) const; - virtual void bindParams(DB::Command *, unsigned int & offset) const; + virtual void bindParams(ExecContext *, DB::Command *, unsigned int & offset) const; const Glib::ustring name; bool active; @@ -49,7 +49,7 @@ namespace DynamicSql { public: SqlCommand(ScriptNodePtr); virtual void writeSql(Glib::ustring & sql) const; - virtual void bindParams(DB::Command *, unsigned int & offset) const; + virtual void bindParams(ExecContext *, DB::Command *, unsigned int & offset) const; typedef std::multimap<Glib::ustring, SqlFilterPtr> Filters; Glib::ustring getSqlFor(const Glib::ustring & f) const; private: diff --git a/project2/streams/streamNvpRows.cpp b/project2/streams/streamNvpRows.cpp index 2577ffa..3f5927f 100644 --- a/project2/streams/streamNvpRows.cpp +++ b/project2/streams/streamNvpRows.cpp @@ -33,7 +33,7 @@ class StreamNvpRows : public RowSet { mutable size_t firstMatch; }; - ParseState(const StreamNvpRows * rows, const RowProcessor * proc) : + ParseState(const StreamNvpRows * rows, const RowProcessorCallback & proc) : sr(rows), rp(proc), inQuotes(false), @@ -134,7 +134,7 @@ class StreamNvpRows : public RowSet { } const StreamNvpRows * sr; - const RowProcessor * rp; + const RowProcessorCallback & rp; bool inQuotes; bool inValue; bool prevWasQuote; @@ -148,23 +148,23 @@ class StreamNvpRows : public RowSet { StreamNvpRows(ScriptNodePtr p) : RowSet(p), - fieldSep(p->value("fieldSep", ",").as<Glib::ustring>()), - quoteChar(p->value("quoteChar", "\"").as<Glib::ustring>()), - keepBlankRows(p->value("keepBlankRows", false)), - countBlankRows(p->value("countBlankRows", false)), - newline(p->value("newline", "\n").as<Glib::ustring>()), - assign(p->value("assign", "=").as<Glib::ustring>()), - encoding(p->value("encoding", "utf-8").as<std::string>()) + fieldSep(p->value("fieldSep", ",", NULL).as<Glib::ustring>()), + quoteChar(p->value("quoteChar", "\"", NULL).as<Glib::ustring>()), + keepBlankRows(p->value("keepBlankRows", false, NULL)), + countBlankRows(p->value("countBlankRows", false, NULL)), + newline(p->value("newline", "\n", NULL).as<Glib::ustring>()), + assign(p->value("assign", "=", NULL).as<Glib::ustring>()), + encoding(p->value("encoding", "utf-8", NULL).as<std::string>()) { p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&stream)); } - void execute(const Glib::ustring &, const RowProcessor * rp) const + void execute(const Glib::ustring &, const RowProcessorCallback & rp, ExecContext * ec) const { ParseState ps(this, rp); TextReader::CharSink cs = boost::bind(&StreamNvpRows::ParseState::pushChar, &ps, _1); TextReader t(encoding.c_str()); - stream->runStream(boost::bind(&TextReader::read, &t, _1, _2, cs)); + stream->runStream(boost::bind(&TextReader::read, &t, _1, _2, cs), ec); } private: diff --git a/project2/streams/streamRows.cpp b/project2/streams/streamRows.cpp index 78f6963..890e1d7 100644 --- a/project2/streams/streamRows.cpp +++ b/project2/streams/streamRows.cpp @@ -14,7 +14,7 @@ class StreamRows : public DefinedColumns, public RowSet { public: class ParseState : public ColumnValues { public: - ParseState(const StreamRows * rows, const RowProcessor * proc) : + ParseState(const StreamRows * rows, const RowProcessorCallback & proc) : ColumnValues(rows), sr(rows), rp(proc), @@ -33,7 +33,7 @@ class StreamRows : public DefinedColumns, public RowSet { } const StreamRows * sr; - const RowProcessor * rp; + const RowProcessorCallback & rp; size_t skipheader; bool inQuotes; bool prevWasQuote; @@ -46,23 +46,23 @@ class StreamRows : public DefinedColumns, public RowSet { StreamRows(ScriptNodePtr p) : DefinedColumns(p, "columns", boost::bind(&Column::make, _1, _2)), RowSet(p), - fieldSep(p->value("fieldSep", ",").as<Glib::ustring>()[0]), - quoteChar(p->value("quoteChar", "\"").as<Glib::ustring>()[0]), - keepBlankRows(p->value("keepBlankRows", false)), - countBlankRows(p->value("countBlankRows", false)), - newline(p->value("newline", "\n").as<Glib::ustring>()), - encoding(p->value("encoding", "utf-8").as<std::string>()), - skipheader(p->value("skipheader", 0).as<int64_t>()) + fieldSep(p->value("fieldSep", ",", NULL).as<Glib::ustring>()[0]), + quoteChar(p->value("quoteChar", "\"", NULL).as<Glib::ustring>()[0]), + keepBlankRows(p->value("keepBlankRows", false, NULL)), + countBlankRows(p->value("countBlankRows", false, NULL)), + newline(p->value("newline", "\n", NULL).as<Glib::ustring>()), + encoding(p->value("encoding", "utf-8", NULL).as<std::string>()), + skipheader(p->value("skipheader", 0, NULL).as<int64_t>()) { p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&stream)); } - void execute(const Glib::ustring &, const RowProcessor * rp) const + void execute(const Glib::ustring &, const RowProcessorCallback & rp, ExecContext * ec) const { ParseState ps(this, rp); TextReader::CharSink cs = boost::bind(&StreamRows::pushChar, this, _1, boost::ref(ps)); TextReader t(encoding.c_str()); - stream->runStream(boost::bind(&TextReader::read, &t, _1, _2, cs)); + stream->runStream(boost::bind(&TextReader::read, &t, _1, _2, cs), ec); } void pushChar(gunichar c, ParseState & ps) const diff --git a/project2/streams/viewStream.cpp b/project2/streams/viewStream.cpp index 28efc17..29917f6 100644 --- a/project2/streams/viewStream.cpp +++ b/project2/streams/viewStream.cpp @@ -27,23 +27,23 @@ class ViewStream : public Stream, public ViewHost { Stream(p), ViewHost(p) { - p->script->loader.addLoadTarget(p, Storer::into<PresenterLoader>(&presenter, Scripted)); + p->script->loader.addLoadTarget(p, Storer::into<PresenterLoader>(&presenter, Scripted, (ExecContext*)NULL)); } - void runStream(const Stream::Sink & s) const + void runStream(const Stream::Sink & s, ExecContext * ec) const { - TransformSourcePtr t = boost::dynamic_pointer_cast<TransformSource>(getPresenter()); + TransformSourcePtr t = boost::dynamic_pointer_cast<TransformSource>(getPresenter(ec)); if (t) { boost::iostreams::stream<SinkStream> strm(s); ostreamWrapper * o = new ostreamWrapper(strm); - executeViews(); - t->addTarget(o); + executeViews(ec); + t->addTarget(o, ec, NULL); ScopeObject remove([&t] { t->clearTargets(); }); - doTransforms(); + doTransforms(ec); } } private: - MultiRowSetPresenterPtr getPresenter() const { + MultiRowSetPresenterPtr getPresenter(ExecContext *) const { return presenter; } MultiRowSetPresenterPtr presenter; diff --git a/project2/url/curlHelper.cpp b/project2/url/curlHelper.cpp index 7f698cb..2988be9 100644 --- a/project2/url/curlHelper.cpp +++ b/project2/url/curlHelper.cpp @@ -39,26 +39,26 @@ Curl::curlSendHelperHandle(char * ptr, size_t size, size_t nmemb, void *stream) } CurlPtr -CurlHelper::newCurl() const +CurlHelper::newCurl(ExecContext * ec) const { CurlPtr c = new Curl(); c->setopt(CURLOPT_FOLLOWLOCATION, 1); c->setopt(CURLOPT_ENCODING, "deflate, gzip"); - c->setopt(CURLOPT_URL, getUrl().c_str()); + c->setopt(CURLOPT_URL, getUrl(ec).c_str()); c->setopt(CURLOPT_FAILONERROR, 1); return c; } CurlPtr -VariableCurlHelper::newCurl() const +VariableCurlHelper::newCurl(ExecContext * ec) const { - CurlPtr c = CurlHelper::newCurl(); - setopt_s(c, CURLOPT_USERAGENT, userAgent()); - setopt_s(c, CURLOPT_PROXY, proxy()); - setopt_s(c, CURLOPT_REFERER, referer()); - setopt_s(c, CURLOPT_COOKIEFILE, cookieJar()); - setopt_s(c, CURLOPT_COOKIEJAR, cookieJar()); - setopt_l(c, CURLOPT_TIMEOUT_MS, timeout()); + CurlPtr c = CurlHelper::newCurl(ec); + setopt_s(c, CURLOPT_USERAGENT, userAgent(ec)); + setopt_s(c, CURLOPT_PROXY, proxy(ec)); + setopt_s(c, CURLOPT_REFERER, referer(ec)); + setopt_s(c, CURLOPT_COOKIEFILE, cookieJar(ec)); + setopt_s(c, CURLOPT_COOKIEJAR, cookieJar(ec)); + setopt_l(c, CURLOPT_TIMEOUT_MS, timeout(ec)); return c; } @@ -103,8 +103,8 @@ VariableCurlHelper::setopt_l(CurlPtr c, CURLoption o, int64_t v) } std::string -VariableCurlHelper::getUrl() const +VariableCurlHelper::getUrl(ExecContext * ec) const { - return url(); + return url(ec); } diff --git a/project2/url/curlHelper.h b/project2/url/curlHelper.h index e3e4484..9c0bbba 100644 --- a/project2/url/curlHelper.h +++ b/project2/url/curlHelper.h @@ -25,10 +25,10 @@ class CurlHelper { CurlHelper(); ~CurlHelper(); - virtual CurlPtr newCurl() const; + virtual CurlPtr newCurl(ExecContext *) const; protected: - virtual std::string getUrl() const = 0; + virtual std::string getUrl(ExecContext *) const = 0; }; /// Project2 helper component to configure CurlHelper from variables @@ -40,8 +40,8 @@ class VariableCurlHelper : public CurlHelper { const Variable url; protected: - virtual CurlPtr newCurl() const; - virtual std::string getUrl() const; + virtual CurlPtr newCurl(ExecContext *) const; + virtual std::string getUrl(ExecContext *) const; private: static void setopt_s(CurlPtr, CURLoption, const char *); diff --git a/project2/url/downloadToFile.cpp b/project2/url/downloadToFile.cpp index 5546efc..2f6726e 100644 --- a/project2/url/downloadToFile.cpp +++ b/project2/url/downloadToFile.cpp @@ -16,10 +16,10 @@ class Download : public Task, VariableCurlHelper { { } - void execute() const + void execute(ExecContext * ec) const { - CurlPtr c = newCurl(); - FILE * file = fopen(destination(), "w"); + CurlPtr c = newCurl(ec); + FILE * file = fopen(destination(ec), "w"); if (!file) { throw syscall_error(errno); } diff --git a/project2/url/urlStream.cpp b/project2/url/urlStream.cpp index 3e1a439..d9fa336 100644 --- a/project2/url/urlStream.cpp +++ b/project2/url/urlStream.cpp @@ -13,9 +13,9 @@ class UrlStream : public Stream, VariableCurlHelper { { } - void runStream(const Sink & sink) const + void runStream(const Sink & sink, ExecContext * ec) const { - CurlPtr c = newCurl(); + CurlPtr c = newCurl(ec); c->performRead(sink); } }; diff --git a/project2/xml/mutators/copy.cpp b/project2/xml/mutators/copy.cpp index 087cffc..5c16ef6 100644 --- a/project2/xml/mutators/copy.cpp +++ b/project2/xml/mutators/copy.cpp @@ -14,10 +14,10 @@ class Copy : public XmlDocMutator { } void mutateElement(xmlpp::Element * root) const { - BOOST_FOREACH(xmlpp::Node * e, root->find(from())) { - BOOST_FOREACH(xmlpp::Node * t, e->find(to())) { + BOOST_FOREACH(xmlpp::Node * e, root->find(from(NULL))) { + BOOST_FOREACH(xmlpp::Node * t, e->find(to(NULL))) { t->import_node(e); - if (delAfter()) { + if (delAfter(NULL)) { e->get_parent()->remove_child(e); } } diff --git a/project2/xml/mutators/copyToAttr.cpp b/project2/xml/mutators/copyToAttr.cpp index c87facb..9f0db5b 100644 --- a/project2/xml/mutators/copyToAttr.cpp +++ b/project2/xml/mutators/copyToAttr.cpp @@ -14,12 +14,12 @@ class CopyToAttr : public XmlDocMutator { } void mutateElement(xmlpp::Element * root) const { - BOOST_FOREACH(xmlpp::Node * e, root->find(from())) { + BOOST_FOREACH(xmlpp::Node * e, root->find(from(NULL))) { if (xmlpp::Element * ee = dynamic_cast<xmlpp::Element *>(e)) { - BOOST_FOREACH(xmlpp::Node * t, e->find(to())) { + BOOST_FOREACH(xmlpp::Node * t, e->find(to(NULL))) { if (xmlpp::Element * te = dynamic_cast<xmlpp::Element *>(t)) { te->set_attribute(e->get_name(), ee->get_child_text()->get_content()); - if (delAfter()) { + if (delAfter(NULL)) { e->get_parent()->remove_child(e); } } diff --git a/project2/xml/mutators/create.cpp b/project2/xml/mutators/create.cpp index a10f54a..2c271dd 100644 --- a/project2/xml/mutators/create.cpp +++ b/project2/xml/mutators/create.cpp @@ -13,8 +13,8 @@ class Create : public XmlDocMutator { } void mutateElement(xmlpp::Element * root) const { - BOOST_FOREACH(xmlpp::Node * e, root->find(xpath())) { - e->add_child(name()); + BOOST_FOREACH(xmlpp::Node * e, root->find(xpath(NULL))) { + e->add_child(name(NULL)); } } Variable xpath; diff --git a/project2/xml/mutators/delete.cpp b/project2/xml/mutators/delete.cpp index d6eba58..ed4d620 100644 --- a/project2/xml/mutators/delete.cpp +++ b/project2/xml/mutators/delete.cpp @@ -12,7 +12,7 @@ class Delete : public XmlDocMutator { } void mutateElement(xmlpp::Element * root) const { - BOOST_FOREACH(xmlpp::Node * e, root->find(xpath())) { + BOOST_FOREACH(xmlpp::Node * e, root->find(xpath(NULL))) { e->get_parent()->remove_child(e); } } diff --git a/project2/xml/mutators/rename.cpp b/project2/xml/mutators/rename.cpp index 74a4578..544afd9 100644 --- a/project2/xml/mutators/rename.cpp +++ b/project2/xml/mutators/rename.cpp @@ -13,8 +13,8 @@ class Rename : public XmlDocMutator { } void mutateElement(xmlpp::Element * root) const { - BOOST_FOREACH(xmlpp::Node * e, root->find(xpath())) { - e->set_name(newname()); + BOOST_FOREACH(xmlpp::Node * e, root->find(xpath(NULL))) { + e->set_name(newname(NULL)); } } Variable xpath; diff --git a/project2/xml/pch.hpp b/project2/xml/pch.hpp index 3e9c8f1..453f8cc 100644 --- a/project2/xml/pch.hpp +++ b/project2/xml/pch.hpp @@ -2,9 +2,7 @@ #ifndef XML_PCH #define XML_PCH -#include "appEngine.h" #include "cache.h" -#include "environment.h" #include "exceptions.h" #include "iHaveParameters.h" #include "logger.h" diff --git a/project2/xml/rawView.cpp b/project2/xml/rawView.cpp index 5226caf..1cd1676 100644 --- a/project2/xml/rawView.cpp +++ b/project2/xml/rawView.cpp @@ -13,10 +13,10 @@ class RawViewBase : public View { RawViewBase(ScriptNodePtr p) : SourceObject(p), View(p) { } - void execute(const MultiRowSetPresenter * mp) const + void execute(const MultiRowSetPresenter * mp, ExecContext * ec) const { if (const Presenter * p = dynamic_cast<const Presenter *>(mp)) { - BOOST_FOREACH(const auto * node, getCopyRoot()->get_children()) { + BOOST_FOREACH(const auto * node, getCopyRoot(ec)->get_children()) { const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(node); if (e) { copyNode(p, e); @@ -26,7 +26,7 @@ class RawViewBase : public View { } protected: - virtual const xmlpp::Element * getCopyRoot() const = 0; + virtual const xmlpp::Element * getCopyRoot(ExecContext *) const = 0; private: void copyNode(const Presenter * p, const xmlpp::Element * n) const @@ -59,7 +59,7 @@ class RawView : public RawViewBase { { } protected: - const xmlpp::Element * getCopyRoot() const { return copyRoot; } + const xmlpp::Element * getCopyRoot(ExecContext *) const { return copyRoot; } private: const xmlpp::Element * copyRoot; }; @@ -75,13 +75,13 @@ class XmlResourceView : public RawViewBase, XmlDocumentCache, VariableCurlHelper { } protected: - const xmlpp::Element * getCopyRoot() const + const xmlpp::Element * getCopyRoot(ExecContext * ec) const { - return getDocument(url(), encoding())->get_root_node(); + return getDocument(url(ec), encoding(ec), ec)->get_root_node(); } - bool asHtml() const { return false; } - bool withWarnings() const { return true; } - CurlPtr newCurl() const { return VariableCurlHelper::newCurl(); } + bool asHtml(ExecContext *) const { return false; } + bool withWarnings(ExecContext *) const { return true; } + CurlPtr newCurl(ExecContext * ec) const { return VariableCurlHelper::newCurl(ec); } private: Variable encoding; diff --git a/project2/xml/transformHtml.cpp b/project2/xml/transformHtml.cpp index 0659ca8..adf534b 100644 --- a/project2/xml/transformHtml.cpp +++ b/project2/xml/transformHtml.cpp @@ -36,7 +36,7 @@ int xmlstrmwritecallback(void * context, const char * buffer, int len) } void -HtmlDocument::writeTo(std::ostream & o, const std::string & encoding) const +HtmlDocument::writeTo(std::ostream & o, const std::string & encoding, ExecContext *) const { xmlOutputBufferPtr buf = xmlOutputBufferCreateIO(xmlstrmwritecallback, xmlstrmclosecallback, &o, NULL); if (method == "html") { @@ -61,7 +61,7 @@ HtmlDocument::getContentClass() const { class TransformXmlToHtml : public TransformImpl<xmlpp::Document, HtmlDocument> { public: - void transform(const xmlpp::Document * cdata, HtmlDocument * result) const + void transform(const xmlpp::Document * cdata, HtmlDocument * result, ExecContext *) const { xmlpp::Document * data = const_cast<xmlpp::Document *>(cdata); typedef boost::shared_ptr<xsltStylesheet> XsltStyleSheetPtr; diff --git a/project2/xml/transformHtml.h b/project2/xml/transformHtml.h index cdc8906..d572244 100644 --- a/project2/xml/transformHtml.h +++ b/project2/xml/transformHtml.h @@ -13,7 +13,7 @@ class HtmlDocument : public SourceOf<HtmlDocument>, public WritableContent, publ operator const WritableContent * () const; Class getContentClass() const; Glib::ustring getContentType() const; - void writeTo(std::ostream &, const std::string & encoding) const; + void writeTo(std::ostream &, const std::string & encoding, ExecContext *) const; Glib::ustring contentType; Glib::ustring method; }; diff --git a/project2/xml/transformText.cpp b/project2/xml/transformText.cpp index 7a6e98e..179007d 100644 --- a/project2/xml/transformText.cpp +++ b/project2/xml/transformText.cpp @@ -20,7 +20,7 @@ TextDocument::operator const TextDocument * () const { return this; } TextDocument::operator const WritableContent * () const { return this; } void -TextDocument::writeTo(std::ostream & o, const std::string & encoding) const +TextDocument::writeTo(std::ostream & o, const std::string & encoding, ExecContext *) const { o << Glib::convert(doc.raw(), encoding, "utf-8"); } @@ -28,7 +28,7 @@ TextDocument::writeTo(std::ostream & o, const std::string & encoding) const Glib::ustring TextDocument::getContentType() const { - return contentType(); + return contentType(NULL); } WritableContent::Class @@ -42,7 +42,7 @@ class TransformHtmlToText : public TransformImpl<HtmlDocument, TextDocument> { width(defaultWidth), links(defaultLinks) { } - void transform(const HtmlDocument * cdoc, TextDocument * str) const + void transform(const HtmlDocument * cdoc, TextDocument * str, ExecContext *) const { xmlDoc * doc = const_cast<xmlDoc *>(cdoc->doc); str->doc.clear(); @@ -76,10 +76,10 @@ class TransformHtmlToText : public TransformImpl<HtmlDocument, TextDocument> { throw std::runtime_error("Lynx failed"); } } - void configure(ScriptNodePtr s) + void configure(ScriptNodePtr s, ExecContext * ec) { - s->applyValue("width", width); - s->applyValue("links", links); + s->applyValue("width", width, ec); + s->applyValue("links", links, ec); } INITOPTIONS; diff --git a/project2/xml/transformText.h b/project2/xml/transformText.h index 3523473..417ceb1 100644 --- a/project2/xml/transformText.h +++ b/project2/xml/transformText.h @@ -13,7 +13,7 @@ class TextDocument : public SourceOf<TextDocument>, public WritableContent, publ operator const WritableContent * () const; Class getContentClass() const; Glib::ustring getContentType() const; - void writeTo(std::ostream &, const std::string & encoding) const; + void writeTo(std::ostream &, const std::string & encoding, ExecContext *) const; Variable contentType; }; diff --git a/project2/xml/xmlCache.cpp b/project2/xml/xmlCache.cpp index 3481b1e..85ef689 100644 --- a/project2/xml/xmlCache.cpp +++ b/project2/xml/xmlCache.cpp @@ -1,7 +1,6 @@ #include <pch.hpp> #include "cache.h" #include "logger.h" -#include "environment.h" #include "scriptLoader.h" #include "iHaveParameters.h" #include "xmlRawRows.h" @@ -20,9 +19,9 @@ class XmlCache : public Cache { { } - RowSetCPtr getCachedRowSet(const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) const + RowSetCPtr getCachedRowSet(ExecContext * ec, const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) const { - boost::filesystem::path cache = getCacheFile(n, f, ps); + boost::filesystem::path cache = getCacheFile(ec, n, f, ps); struct stat st; if (stat(cache.string().c_str(), &st) == 0) { if (st.st_mtime < time(NULL) - CacheLife) { @@ -34,15 +33,15 @@ class XmlCache : public Cache { return NULL; } - RowSetPresenterPtr openFor(const Glib::ustring & n, const Glib::ustring &, const IHaveParameters *) + RowSetPresenterPtr openFor(ExecContext *, const Glib::ustring & n, const Glib::ustring &, const IHaveParameters *) { writeTo = new XmlPresenter(n, Scripts::scriptNamespace, Scripts::scriptNamespacePrefix); return writeTo; } - void save(const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) + void save(ExecContext * ec, const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) { - boost::filesystem::path target = getCacheFile(n, f, ps); + boost::filesystem::path target = getCacheFile(ec, n, f, ps); try { boost::filesystem::create_directories(target.parent_path()); const xmlpp::Document * d = *writeTo; @@ -54,16 +53,16 @@ class XmlCache : public Cache { } } - void discard(const Glib::ustring &, const Glib::ustring &, const IHaveParameters *) + void discard(ExecContext *, const Glib::ustring &, const Glib::ustring &, const IHaveParameters *) { } INITOPTIONS; private: - boost::filesystem::path getCacheFile(const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) const + boost::filesystem::path getCacheFile(ExecContext * ec, const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) const { boost::filesystem::path cache = Store / n.raw() / f.raw(); - applyKeys(boost::bind(&appendPath, &cache, _1, _2), ps); + applyKeys(ec, boost::bind(&appendPath, &cache, _1, _2), ps); cache /= FileName; return cache; } diff --git a/project2/xml/xmlDocumentCache.cpp b/project2/xml/xmlDocumentCache.cpp index ec8d6a8..3f8a81e 100644 --- a/project2/xml/xmlDocumentCache.cpp +++ b/project2/xml/xmlDocumentCache.cpp @@ -84,11 +84,11 @@ class XmlDocumentCachePopulator : public CurlCompleteCallback { }; XmlDocumentCache::DocumentPtr -XmlDocumentCache::getDocument(const Glib::ustring & url, const char * encoding) const +XmlDocumentCache::getDocument(const Glib::ustring & url, const char * encoding, ExecContext * ec) const { Documents::const_iterator i = documents.find(url); if (i == documents.end()) { - queue(url, encoding); + queue(url, encoding, ec); cbf.perform(); queued.clear(); } @@ -96,10 +96,10 @@ XmlDocumentCache::getDocument(const Glib::ustring & url, const char * encoding) } void -XmlDocumentCache::queue(const Glib::ustring & url, const char * encoding) const +XmlDocumentCache::queue(const Glib::ustring & url, const char * encoding, ExecContext * ec) const { if (queued.find(url) == queued.end()) { - cbf.curls.insert(new XmlDocumentCachePopulator(newCurl(), url, asHtml(), withWarnings(), encoding)); + cbf.curls.insert(new XmlDocumentCachePopulator(newCurl(ec), url, asHtml(ec), withWarnings(ec), encoding)); queued.insert(url); } } diff --git a/project2/xml/xmlDocumentCache.h b/project2/xml/xmlDocumentCache.h index fe1725d..a7b7454 100644 --- a/project2/xml/xmlDocumentCache.h +++ b/project2/xml/xmlDocumentCache.h @@ -19,14 +19,14 @@ class XmlDocumentCache { static Queued queued; static Documents documents; - void queue(const Glib::ustring & url, const char * encoding) const; + void queue(const Glib::ustring & url, const char * encoding, ExecContext *) const; - virtual CurlPtr newCurl() const = 0; - virtual bool asHtml() const = 0; - virtual bool withWarnings() const = 0; + virtual CurlPtr newCurl(ExecContext *) const = 0; + virtual bool asHtml(ExecContext * ec) const = 0; + virtual bool withWarnings(ExecContext * ec) const = 0; protected: - DocumentPtr getDocument(const Glib::ustring & url, const char * encoding) const; + DocumentPtr getDocument(const Glib::ustring & url, const char * encoding, ExecContext * ec) const; private: static CurlBulkFetcher cbf; diff --git a/project2/xml/xmlDocumentPrefetch.cpp b/project2/xml/xmlDocumentPrefetch.cpp index 64b236e..4af0055 100644 --- a/project2/xml/xmlDocumentPrefetch.cpp +++ b/project2/xml/xmlDocumentPrefetch.cpp @@ -20,32 +20,32 @@ XmlDocumentPrefetch::~XmlDocumentPrefetch() } void -XmlDocumentPrefetch::execute(const MultiRowSetPresenter*) const +XmlDocumentPrefetch::execute(const MultiRowSetPresenter*, ExecContext * ec) const { - execute(); + execute(ec); } void -XmlDocumentPrefetch::execute() const +XmlDocumentPrefetch::execute(ExecContext * ec) const { - queue(url(), encoding()); + queue(url(ec), encoding(ec), ec); } CurlPtr -XmlDocumentPrefetch::newCurl() const +XmlDocumentPrefetch::newCurl(ExecContext * ec) const { - return VariableCurlHelper::newCurl(); + return VariableCurlHelper::newCurl(ec); } bool -XmlDocumentPrefetch::asHtml() const +XmlDocumentPrefetch::asHtml(ExecContext * ec) const { - return html(); + return html(ec); } bool -XmlDocumentPrefetch::withWarnings() const +XmlDocumentPrefetch::withWarnings(ExecContext * ec) const { - return warnings(); + return warnings(ec); } diff --git a/project2/xml/xmlDocumentPrefetch.h b/project2/xml/xmlDocumentPrefetch.h index 454492a..fd9285d 100644 --- a/project2/xml/xmlDocumentPrefetch.h +++ b/project2/xml/xmlDocumentPrefetch.h @@ -13,16 +13,16 @@ class XmlDocumentPrefetch : public View, public Task, XmlDocumentCache, Variable XmlDocumentPrefetch(ScriptNodePtr p); ~XmlDocumentPrefetch(); - void execute(const MultiRowSetPresenter*) const; - void execute() const; + void execute(const MultiRowSetPresenter*, ExecContext *) const; + void execute(ExecContext *) const; const Variable html; const Variable warnings; const Variable encoding; - CurlPtr newCurl() const; - bool asHtml() const; - bool withWarnings() const; + CurlPtr newCurl(ExecContext *) const; + bool asHtml(ExecContext * ec) const; + bool withWarnings(ExecContext * ec) const; }; #endif diff --git a/project2/xml/xmlPresenter.cpp b/project2/xml/xmlPresenter.cpp index 08978ce..32960a1 100644 --- a/project2/xml/xmlPresenter.cpp +++ b/project2/xml/xmlPresenter.cpp @@ -4,7 +4,6 @@ #include "scriptLoader.h" #include "scriptStorage.h" #include "variables.h" -#include "appEngine.h" #include <libxml++/document.h> #include <boost/date_time/posix_time/time_formatters.hpp> #include <boost/date_time/gregorian/formatters.hpp> @@ -51,10 +50,10 @@ XmlPresenter::XmlPresenter(const Glib::ustring & responseRootNodeName, const Gli { } -XmlPresenter::XmlPresenter(ScriptNodePtr e, ObjectSource os) : +XmlPresenter::XmlPresenter(ScriptNodePtr e, ObjectSource os, ExecContext *) : TransformSource(e, os), Presenter(os), - ContentPresenter(e->value("contenttype", "application/xml")), + ContentPresenter(e->value("contenttype", "application/xml", NULL)), SourceOf<xmlpp::Document>(e, os), SourceOf<_xmlDoc>(e, os), SourceOf<boost::shared_ptr<xmlpp::Document> >(e, os), @@ -72,16 +71,16 @@ XmlPresenter::~XmlPresenter() } void -XmlPresenter::init() +XmlPresenter::init(ExecContext * ec) { responseDoc = XmlDocumentPtr(new xmlpp::Document("1.0")); nodeStack.clear(); - nodeStack.push_back(responseDoc->create_root_node(root())); + nodeStack.push_back(responseDoc->create_root_node(root(ec))); declareNamespace(Scripts::scriptNamespacePrefix, Scripts::scriptNamespace); // XSLT Style char * buf; - if (!style().isNull() && asprintf(&buf, "type=\"text/xsl\" href=\"%s\"", - style().as<const char *>()) > 0) { + if (!style(ec).isNull() && asprintf(&buf, "type=\"text/xsl\" href=\"%s\"", + style(ec).as<const char *>()) > 0) { xmlAddPrevSibling(nodeStack.back()->cobj(), xmlNewDocPI(responseDoc->cobj(), BAD_CAST "xml-stylesheet", BAD_CAST buf)); free(buf); @@ -247,7 +246,7 @@ XmlPresenter::getContentClass() const { } void -XmlPresenter::writeTo(std::ostream & o, const std::string & enc) const { +XmlPresenter::writeTo(std::ostream & o, const std::string & enc, ExecContext *) const { responseDoc->write_to_stream_formatted(o, enc); } diff --git a/project2/xml/xmlPresenter.h b/project2/xml/xmlPresenter.h index 0180342..de3f65b 100644 --- a/project2/xml/xmlPresenter.h +++ b/project2/xml/xmlPresenter.h @@ -24,7 +24,7 @@ class XmlPresenter : public Presenter, public ContentPresenter, public SourceOf< public: typedef boost::shared_ptr<xmlpp::Document> XmlDocumentPtr; XmlPresenter(const Glib::ustring & responseRootNodeName, const Glib::ustring & responseStyle, const Glib::ustring & contentType); - XmlPresenter(ScriptNodePtr e, ObjectSource); + XmlPresenter(ScriptNodePtr e, ObjectSource, ExecContext *); ~XmlPresenter(); void declareNamespace(const Glib::ustring & prefix, const Glib::ustring & ns) const; @@ -44,9 +44,9 @@ class XmlPresenter : public Presenter, public ContentPresenter, public SourceOf< operator const WritableContent * () const; Class getContentClass() const; Glib::ustring getContentType() const; - void writeTo(std::ostream &, const std::string & enc) const; + void writeTo(std::ostream &, const std::string & enc, ExecContext *) const; void finalizeContent() const; - void init(); + void init(ExecContext *); INITOPTIONS; private: diff --git a/project2/xml/xmlRawRows.cpp b/project2/xml/xmlRawRows.cpp index 3511981..e686375 100644 --- a/project2/xml/xmlRawRows.cpp +++ b/project2/xml/xmlRawRows.cpp @@ -1,6 +1,5 @@ #include <pch.hpp> #include "xmlRawRows.h" -#include "environment.h" #include <boost/foreach.hpp> #include <libxml++/parsers/domparser.h> #include <libxml++/nodes/textnode.h> @@ -53,7 +52,7 @@ XmlRawRowsBase::XmlRawRowsBase() : { } -void XmlRawRowsBase::execute(const xmlpp::Document * doc, const RowProcessor * rp) const +void XmlRawRowsBase::execute(const xmlpp::Document * doc, const RowProcessorCallback & rp, ExecContext *) const { XmlRowState rs; BOOST_FOREACH(const xmlpp::Node * n, doc->get_root_node()->get_children()) { @@ -94,10 +93,10 @@ XmlRawRows::XmlRawRows(const Glib::ustring & p) : { } -void XmlRawRows::execute(const Glib::ustring&, const RowProcessor * rp) const +void XmlRawRows::execute(const Glib::ustring&, const RowProcessorCallback & rp, ExecContext * ec) const { - xmlpp::DomParser x(path()); - XmlRawRowsBase::execute(x.get_document(), rp); + xmlpp::DomParser x(path(ec)); + XmlRawRowsBase::execute(x.get_document(), rp, ec); } XmlMemRawRows::XmlMemRawRows(boost::shared_ptr<const xmlpp::Document> d) : @@ -105,8 +104,8 @@ XmlMemRawRows::XmlMemRawRows(boost::shared_ptr<const xmlpp::Document> d) : { } -void XmlMemRawRows::execute(const Glib::ustring&, const RowProcessor * rp) const +void XmlMemRawRows::execute(const Glib::ustring&, const RowProcessorCallback & rp, ExecContext * ec) const { - XmlRawRowsBase::execute(doc.get(), rp); + XmlRawRowsBase::execute(doc.get(), rp, ec); } diff --git a/project2/xml/xmlRawRows.h b/project2/xml/xmlRawRows.h index 15dad48..ac5a30f 100644 --- a/project2/xml/xmlRawRows.h +++ b/project2/xml/xmlRawRows.h @@ -10,7 +10,7 @@ class XmlRawRowsBase : public RowSet { XmlRawRowsBase(); protected: - void execute(const xmlpp::Document *, const RowProcessor * rp) const; + void execute(const xmlpp::Document *, const RowProcessorCallback &, ExecContext *) const; }; class XmlRawRows : public XmlRawRowsBase { @@ -18,7 +18,7 @@ class XmlRawRows : public XmlRawRowsBase { XmlRawRows(ScriptNodePtr p); XmlRawRows(const Glib::ustring & p); - void execute(const Glib::ustring&, const RowProcessor * rp) const; + void execute(const Glib::ustring&, const RowProcessorCallback &, ExecContext *) const; private: const Variable path; @@ -28,7 +28,7 @@ class XmlMemRawRows : public XmlRawRowsBase { public: XmlMemRawRows(boost::shared_ptr<const xmlpp::Document> d); - void execute(const Glib::ustring&, const RowProcessor * rp) const; + void execute(const Glib::ustring&, const RowProcessorCallback &, ExecContext *) const; private: boost::shared_ptr<const xmlpp::Document> doc; diff --git a/project2/xml/xmlRows.cpp b/project2/xml/xmlRows.cpp index 01e626f..7916a37 100644 --- a/project2/xml/xmlRows.cpp +++ b/project2/xml/xmlRows.cpp @@ -23,15 +23,15 @@ XmlRows::XmlRows(ScriptNodePtr p) : { typedef boost::split_iterator<Glib::ustring::iterator> ssi; - Glib::ustring rR = recordRoot(); + Glib::ustring rR = recordRoot(NULL); boost::split(root, rR, boost::is_any_of("/")); - Glib::ustring rT = recordTrigger(); + Glib::ustring rT = recordTrigger(NULL); boost::split(trigger, rT, boost::is_any_of("/")); unsigned int col = 0; BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("fields")) { Path p(root); - Glib::ustring path = node->value("path"); + Glib::ustring path = node->value("path", NULL); for(ssi It = make_split_iterator(path, first_finder("/", boost::is_equal())); It!=ssi(); ++It) { if (It->front() == '@') { @@ -60,9 +60,9 @@ store(const XmlRows::Path & position, RowState::FieldValues & values, const XmlR } void -XmlRows::execute(const Glib::ustring &, const RowProcessor * rp) const +XmlRows::execute(const Glib::ustring &, const RowProcessorCallback & rp, ExecContext * ec) const { - xmlTextReaderPtr reader = xmlReaderForFile(filename(), NULL, 0); + xmlTextReaderPtr reader = xmlReaderForFile(filename(ec), NULL, 0); if (reader == NULL) { throw std::runtime_error("Failed to open file"); } diff --git a/project2/xml/xmlRows.h b/project2/xml/xmlRows.h index 975e290..bfc6514 100644 --- a/project2/xml/xmlRows.h +++ b/project2/xml/xmlRows.h @@ -15,7 +15,7 @@ class XmlRows : public RowSet { XmlRows(ScriptNodePtr p); ~XmlRows(); - void execute(const Glib::ustring &, const RowProcessor *) const; + void execute(const Glib::ustring &, const RowProcessorCallback &, ExecContext *) const; const Variable recordRoot; const Variable recordTrigger; diff --git a/project2/xml/xmlScriptParser.cpp b/project2/xml/xmlScriptParser.cpp index 1040667..5d0d37c 100644 --- a/project2/xml/xmlScriptParser.cpp +++ b/project2/xml/xmlScriptParser.cpp @@ -1,6 +1,5 @@ #include <pch.hpp> #include "xmlScriptParser.h" -#include "environment.h" #include "scripts.h" #include "commonObjects.h" #include "variables/literal.h" @@ -214,7 +213,7 @@ XmlScriptNode::variable(const boost::optional<Glib::ustring> & defaultSource) co } bool -XmlScriptNode::applyValue(const Glib::ustring & n, VariableType & val) const +XmlScriptNode::applyValue(const Glib::ustring & n, VariableType & val, ExecContext * ec) const { if (const xmlpp::Attribute * a = element->get_attribute(n)) { val = a->get_value(); @@ -230,7 +229,7 @@ XmlScriptNode::applyValue(const Glib::ustring & n, VariableType & val) const else { v = new VariableLiteral(new XmlScriptNode(c, script)); } - val = v->value(); + val = v->value(ec); return false; } } diff --git a/project2/xml/xmlScriptParser.h b/project2/xml/xmlScriptParser.h index 0f391a1..f596c8d 100644 --- a/project2/xml/xmlScriptParser.h +++ b/project2/xml/xmlScriptParser.h @@ -24,7 +24,7 @@ class XmlScriptNode : public ScriptNode { bool valueExists(const Glib::ustring&) const; VariableImpl * variable(const boost::optional<Glib::ustring> & defaultSource) const; VariableImpl * variable(const Glib::ustring&) const; - bool applyValue(const Glib::ustring & name, VariableType & target) const; + bool applyValue(const Glib::ustring & name, VariableType & target, ExecContext *) const; void composeWithCallbacks(const ScriptNode::LiteralCallback&, const ScriptNode::NodeCallback&) const; private: diff --git a/project2/xml/xpathRows.cpp b/project2/xml/xpathRows.cpp index eedfa8e..8537b35 100644 --- a/project2/xml/xpathRows.cpp +++ b/project2/xml/xpathRows.cpp @@ -29,7 +29,7 @@ XPathRows::XPathRows(ScriptNodePtr p) : fvs[fv->name] = fv; } BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("namespaces")) { - namespaces[node->value("prefix")] = node->value("url").as<Glib::ustring>(); + namespaces[node->value("prefix", NULL)] = node->value("url", NULL).as<Glib::ustring>(); } } @@ -38,31 +38,31 @@ XPathRows::~XPathRows() } bool -XPathRows::asHtml() const +XPathRows::asHtml(ExecContext * ec) const { - return html(); + return html(ec); } bool -XPathRows::withWarnings() const +XPathRows::withWarnings(ExecContext * ec) const { - return warnings(); + return warnings(ec); } CurlPtr -XPathRows::newCurl() const +XPathRows::newCurl(ExecContext * ec) const { - return VariableCurlHelper::newCurl(); + return VariableCurlHelper::newCurl(ec); } void -XPathRows::execute(const Glib::ustring & filter, const RowProcessor * rp) const +XPathRows::execute(const Glib::ustring & filter, const RowProcessorCallback & rp, ExecContext * ec) const { FilterViewPtr fv = safeMapLookup<FilterNotFound>(fvs, filter); typedef boost::shared_ptr<xmlXPathObject> xmlXPathObjectSPtr; typedef boost::shared_ptr<xmlXPathContext> xmlXPathContextSPtr; - xmlDocPtr doc = getDocument(url(), encoding())->cobj(); + xmlDocPtr doc = getDocument(url(ec), encoding(ec), ec)->cobj(); xmlXPathContextSPtr xpathCtx = xmlXPathContextSPtr(xmlXPathNewContext(doc), xmlXPathFreeContext); if (!xpathCtx) { throw XpathInitError(xmlGetLastError()->message); @@ -70,18 +70,18 @@ XPathRows::execute(const Glib::ustring & filter, const RowProcessor * rp) const BOOST_FOREACH(const Namespaces::value_type & ns, namespaces) { xmlXPathRegisterNs(xpathCtx.get(), BAD_CAST ns.first.c_str(), BAD_CAST ns.second.c_str()); } - xmlXPathObjectSPtr xpathObj = xmlXPathObjectSPtr(xmlXPathEvalExpression(fv->root(), xpathCtx.get()), xmlXPathFreeObject); + xmlXPathObjectSPtr xpathObj = xmlXPathObjectSPtr(xmlXPathEvalExpression(fv->root(ec), xpathCtx.get()), xmlXPathFreeObject); if (!xpathObj || !xpathObj->nodesetval) { throw XpathEvalError(xmlGetLastError()->message); } - Logger()->messagef(LOG_INFO, "%d nodes matched %s", xpathObj->nodesetval->nodeNr, (const char *)(fv->root())); + Logger()->messagef(LOG_INFO, "%d nodes matched %s", xpathObj->nodesetval->nodeNr, (const char *)(fv->root(ec))); XPathState xs(fv); for (int row = 0; row < xpathObj->nodesetval->nodeNr; row += 1) { xmlNodePtr rowRoot = xpathObj->nodesetval->nodeTab[row]; xpathCtx->node = rowRoot; BOOST_FOREACH(const Columns::value_type & _xp, fv->columns.get<byColIdx>()) { const FilterViewColumn * xp = static_cast<const FilterViewColumn *>(_xp.get()); - const VariableType & path(xp->path); + const VariableType & path(xp->path(ec)); if (path.isNull()) { continue; } diff --git a/project2/xml/xpathRows.h b/project2/xml/xpathRows.h index 47d34eb..03929ab 100644 --- a/project2/xml/xpathRows.h +++ b/project2/xml/xpathRows.h @@ -17,7 +17,7 @@ class XPathRows : public RowSet, XmlDocumentCache, VariableCurlHelper { XPathRows(ScriptNodePtr p); ~XPathRows(); - void execute(const Glib::ustring &, const RowProcessor *) const; + void execute(const Glib::ustring &, const RowProcessorCallback &, ExecContext *) const; private: class FilterViewColumn : public Column { @@ -40,9 +40,9 @@ class XPathRows : public RowSet, XmlDocumentCache, VariableCurlHelper { typedef std::map<const Glib::ustring, FilterViewPtr> FilterViews; FilterViews fvs; - virtual CurlPtr newCurl() const; - virtual bool asHtml() const; - virtual bool withWarnings() const; + virtual CurlPtr newCurl(ExecContext *) const; + virtual bool asHtml(ExecContext *) const; + virtual bool withWarnings(ExecContext *) const; typedef std::map<const Glib::ustring, Glib::ustring> Namespaces; Namespaces namespaces; |