diff options
author | randomdan <randomdan@localhost> | 2013-07-05 00:01:26 +0000 |
---|---|---|
committer | randomdan <randomdan@localhost> | 2013-07-05 00:01:26 +0000 |
commit | 530d921225b019130585667d91bad25194179310 (patch) | |
tree | 6f3a750f79ad26047ff5322522219798d19aa64c | |
parent | Move remaining options out of environment (diff) | |
download | project2-530d921225b019130585667d91bad25194179310.tar.bz2 project2-530d921225b019130585667d91bad25194179310.tar.xz project2-530d921225b019130585667d91bad25194179310.zip |
Massive refactor to remove the appEngine and environment complication and instead have an execution context that's passed around from the original call site
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; |