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