diff options
159 files changed, 1219 insertions, 928 deletions
| diff --git a/project2/cgi/Jamfile.jam b/project2/cgi/Jamfile.jam index 48225cb..017dd11 100644 --- a/project2/cgi/Jamfile.jam +++ b/project2/cgi/Jamfile.jam @@ -1,6 +1,7 @@ -alias libxmlpp : : : : -	<cflags>"`pkg-config --cflags libxml++-2.6`" -	<linkflags>"`pkg-config --libs libxml++-2.6`" ; +alias glibmm : : : : +	<cflags>"`pkg-config --cflags glibmm-2.4`" +	<linkflags>"`pkg-config --libs glibmm-2.4`" +	;  lib boost_filesystem : : <name>boost_filesystem ;  lib cgicc : : <name>cgicc ;  lib fcgi : : <name>fcgi ; @@ -9,7 +10,7 @@ lib fcgi++ : : <name>fcgi++ ;  cpp-pch pch : pch.hpp :  	<include>../../libmisc  	<library>cgicc -	<library>libxmlpp +	<library>glibmm  	<library>../common//p2common  	<library>boost_filesystem  	<library>../xml//p2xml @@ -20,7 +21,7 @@ lib p2web :  	:  	<include>../libmisc  	<library>cgicc -	<library>libxmlpp +	<library>glibmm  	<library>../common//p2common  	<library>boost_filesystem  	<library>../xml//p2xml diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp index 7fd7c33..4d91069 100644 --- a/project2/cgi/cgiAppEngine.cpp +++ b/project2/cgi/cgiAppEngine.cpp @@ -56,15 +56,15 @@ CgiApplicationEngine::process() const   			currentStage = currentStage.get<0>()->run();  		}  		catch (const CheckHost::CheckFailure & cf) { -			currentStage = NextStage(new PresentStage(_env, _env->resolveScript(_env->presentRoot, cf.failedCheck->present()))); +			currentStage = NextStage(new PresentStage(_env, _env->resolveScript(_env->presentRoot, cf.failedCheck->present(), false)));  		} -		catch (const XmlScriptParser::NotFound & nf) { +		catch (const ScriptNotFound & nf) {  			if (_env->notFoundPresent.empty() || triedNotFound) {  				currentStage = NextStage(new DefaultNotFoundStage(_env, nf));  			}  			else {  				triedNotFound = true; -				currentStage = NextStage(new CustomNotFoundStage(_env, nf)); +				currentStage = NextStage(new CustomNotFoundStage(_env, nf, _env->resolveScript(_env->errorPresentRoot, _env->notFoundPresent, false)));  			}  		}  		catch (const std::exception & ex) { @@ -73,7 +73,7 @@ CgiApplicationEngine::process() const  			}  			else {  				triedNotFound = true; -				currentStage = NextStage(new CustomErrorStage(_env, ex)); +				currentStage = NextStage(new CustomErrorStage(_env, ex, _env->resolveScript(_env->errorPresentRoot, _env->onErrorPresent, false)));  			}  		}  	} while (currentStage.get<0>()); diff --git a/project2/cgi/cgiAppEngine.h b/project2/cgi/cgiAppEngine.h index 25d3b93..f4b3896 100644 --- a/project2/cgi/cgiAppEngine.h +++ b/project2/cgi/cgiAppEngine.h @@ -88,7 +88,7 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink  		/// Stage to process POST requests  		class RequestStage : public ResponseStage, TaskHost {  			public: -				RequestStage(const CgiEnvironment *, const boost::filesystem::path & path); +				RequestStage(const CgiEnvironment *, ScriptReaderPtr);  				virtual NextStage run();  				virtual HttpHeaderPtr getHeader() const; @@ -99,7 +99,7 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink  		/// Stage to process GET requests and follow up RequestStages  		class PresentStage : public virtual ResponseStage, ViewHost {  			public: -				PresentStage(const CgiEnvironment * e, const boost::filesystem::path & path); +				PresentStage(const CgiEnvironment * e, ScriptReaderPtr);  				virtual NextStage run();  				virtual HttpHeaderPtr getHeader() const; @@ -108,19 +108,19 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink  		/// The built-in fail-safe not found stage  		class DefaultNotFoundStage : public virtual ResponseStage {  			public: -				DefaultNotFoundStage(const CgiEnvironment *, const XmlScriptParser::NotFound &); +				DefaultNotFoundStage(const CgiEnvironment *, const ScriptNotFound &);  				virtual NextStage run();  				virtual HttpHeaderPtr getHeader() const;  			private: -				const XmlScriptParser::NotFound nf; +				const ScriptNotFound nf;  				XmlPresenterPtr pres;  		};  		/// Custom not found handling stage  		class CustomNotFoundStage : public DefaultNotFoundStage, public PresentStage {  			public: -				CustomNotFoundStage(const CgiEnvironment *, const ::XmlScriptParser::NotFound &); +				CustomNotFoundStage(const CgiEnvironment *, const ScriptNotFound &, ScriptReaderPtr);  				virtual NextStage run();  				virtual HttpHeaderPtr getHeader() const;  		}; @@ -142,7 +142,7 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink  		/// Custom unhandled error handling stage  		class CustomErrorStage : public DefaultErrorStage, public PresentStage {  			public: -				CustomErrorStage(const CgiEnvironment *, const std::exception &); +				CustomErrorStage(const CgiEnvironment *, const std::exception &, ScriptReaderPtr);  				virtual NextStage run();  				virtual HttpHeaderPtr getHeader() const;  		}; diff --git a/project2/cgi/cgiOutputOptions.cpp b/project2/cgi/cgiOutputOptions.cpp index add1671..f9a6d86 100644 --- a/project2/cgi/cgiOutputOptions.cpp +++ b/project2/cgi/cgiOutputOptions.cpp @@ -1,4 +1,5 @@  #include "cgiOutputOptions.h" +#include "scripts.h"  bool OutputOptions::core;  bool OutputOptions::session; @@ -7,13 +8,13 @@ bool OutputOptions::environment;  bool OutputOptions::url;  bool OutputOptions::parameters; -OutputOptions::OutputOptions(const xmlpp::Element * p) : -	Core(p, "core", false, core), -	Session(p, "session", false, session), -	Timing(p, "timing", false, timing), -	Environment(p, "environment", false, environment), -	URL(p, "url", false, url), -	Parameters(p, "parameters", false, parameters) +OutputOptions::OutputOptions(ScriptNodePtr p) : +	Core(p, "core", core), +	Session(p, "session", session), +	Timing(p, "timing", timing), +	Environment(p, "environment", environment), +	URL(p, "url", url), +	Parameters(p, "parameters", parameters)  {  } @@ -31,7 +32,7 @@ OutputOptionsLoader::OutputOptionsLoader() :  }  OutputOptionsPtr -OutputOptionsLoader::createFrom(const xmlpp::Element * e) const { +OutputOptionsLoader::createFrom(ScriptNodePtr e) const {  	return new OutputOptions(e);  } diff --git a/project2/cgi/cgiOutputOptions.h b/project2/cgi/cgiOutputOptions.h index a1ff62d..07b7598 100644 --- a/project2/cgi/cgiOutputOptions.h +++ b/project2/cgi/cgiOutputOptions.h @@ -11,7 +11,7 @@ namespace xmlpp {  class OutputOptions : public IntrusivePtrBase {  	public: -		OutputOptions(const xmlpp::Element *); +		OutputOptions(ScriptNodePtr);  		const Variable Core;  		const Variable Session; @@ -35,7 +35,7 @@ typedef boost::intrusive_ptr<OutputOptions> OutputOptionsPtr;  class OutputOptionsLoader : public ComponentLoader {  	public:  		OutputOptionsLoader(); -		OutputOptionsPtr createFrom(const xmlpp::Element * e) const; +		OutputOptionsPtr createFrom(ScriptNodePtr e) const;  		const Options * options() const;  	private: diff --git a/project2/cgi/cgiStageCustomError.cpp b/project2/cgi/cgiStageCustomError.cpp index 8b4b347..82fc6a1 100644 --- a/project2/cgi/cgiStageCustomError.cpp +++ b/project2/cgi/cgiStageCustomError.cpp @@ -4,12 +4,12 @@  #include "cgiHttpHeader.h"  #include "logger.h" -CgiApplicationEngine::CustomErrorStage::CustomErrorStage(const CgiEnvironment * env, const std::exception & ex) : +CgiApplicationEngine::CustomErrorStage::CustomErrorStage(const CgiEnvironment * env, const std::exception & ex, ScriptReaderPtr s) :  	CgiApplicationEngine::ResponseStage(env), -	::XmlScriptParser(e->resolveScript(env->errorPresentRoot, env->onErrorPresent), false), -	::CheckHost(e->resolveScript(env->errorPresentRoot, env->onErrorPresent)), +	::CommonObjects(s), +	::CheckHost(s),  	CgiApplicationEngine::DefaultErrorStage(env, ex), -	CgiApplicationEngine::PresentStage(env, e->resolveScript(env->errorPresentRoot, env->onErrorPresent)) +	CgiApplicationEngine::PresentStage(env, s)  {  } diff --git a/project2/cgi/cgiStageCustomNotFound.cpp b/project2/cgi/cgiStageCustomNotFound.cpp index fc49804..8a224fa 100644 --- a/project2/cgi/cgiStageCustomNotFound.cpp +++ b/project2/cgi/cgiStageCustomNotFound.cpp @@ -4,12 +4,12 @@  #include "cgiHttpHeader.h"  #include "logger.h" -CgiApplicationEngine::CustomNotFoundStage::CustomNotFoundStage(const CgiEnvironment * env, const ::XmlScriptParser::NotFound & notfound) : +CgiApplicationEngine::CustomNotFoundStage::CustomNotFoundStage(const CgiEnvironment * env, const ScriptNotFound & notfound, ScriptReaderPtr s) :  	CgiApplicationEngine::ResponseStage(env), -	::XmlScriptParser(e->resolveScript(env->errorPresentRoot, env->notFoundPresent), false), -	::CheckHost(e->resolveScript(env->errorPresentRoot, env->notFoundPresent)), +	::CommonObjects(s), +	::CheckHost(s),  	CgiApplicationEngine::DefaultNotFoundStage(env, notfound), -	CgiApplicationEngine::PresentStage(env, e->resolveScript(env->errorPresentRoot, env->notFoundPresent)) +	CgiApplicationEngine::PresentStage(env, s)  {  } diff --git a/project2/cgi/cgiStageDefaultNotFound.cpp b/project2/cgi/cgiStageDefaultNotFound.cpp index 38cc395..d05c92b 100644 --- a/project2/cgi/cgiStageDefaultNotFound.cpp +++ b/project2/cgi/cgiStageDefaultNotFound.cpp @@ -6,7 +6,7 @@  static const Glib::ustring DefaultNotFoundStageResp("notfound"); -CgiApplicationEngine::DefaultNotFoundStage::DefaultNotFoundStage(const CgiEnvironment * env, const XmlScriptParser::NotFound & notfound) : +CgiApplicationEngine::DefaultNotFoundStage::DefaultNotFoundStage(const CgiEnvironment * env, const ScriptNotFound & notfound) :  	CgiApplicationEngine::ResponseStage(env),  	nf(notfound),  	pres(new XmlPresenter(DefaultNotFoundStageResp, e->errorTransformStyle, e->errorContentType)) diff --git a/project2/cgi/cgiStageFail.cpp b/project2/cgi/cgiStageFail.cpp index 87aba66..62de295 100644 --- a/project2/cgi/cgiStageFail.cpp +++ b/project2/cgi/cgiStageFail.cpp @@ -31,11 +31,11 @@ namespace CgiApplicationExtras {  	class CgiFail : public View {  		public: -			CgiFail(const xmlpp::Element * e) : +			CgiFail(ScriptNodePtr e) :  				SourceObject(e),  				View(e), -				code(e, "code", false, 500), -				message(e, "message", false, "Application error") { +				code(e, "code", 500), +				message(e, "message", "Application error") {  			}  			void execute(const MultiRowSetPresenter *) const {  				throw CgiApplicationEngine::ResponseStagePtr( diff --git a/project2/cgi/cgiStageInitial.cpp b/project2/cgi/cgiStageInitial.cpp index b263110..0fe81d4 100644 --- a/project2/cgi/cgiStageInitial.cpp +++ b/project2/cgi/cgiStageInitial.cpp @@ -17,12 +17,10 @@ CgiApplicationEngine::InitialStage::run()  		if (e->elems.empty()) {  			throw EmptyRequestURL();  		} -		return NextStage(new RequestStage(e, e->resolveScript(e->requestRoot, -						e->getRedirectURL()))); +		return NextStage(new RequestStage(e, e->resolveScript(e->requestRoot, e->getRedirectURL(), false)));  	}  	else { -		return NextStage(new PresentStage(e, e->resolveScript(e->presentRoot, -						e->elems.empty() ? e->defaultPresent : e->getRedirectURL()))); +		return NextStage(new PresentStage(e, e->resolveScript(e->presentRoot, e->elems.empty() ? e->defaultPresent : e->getRedirectURL(), false)));  	}  } diff --git a/project2/cgi/cgiStagePresent.cpp b/project2/cgi/cgiStagePresent.cpp index 54b0e02..8eb0487 100644 --- a/project2/cgi/cgiStagePresent.cpp +++ b/project2/cgi/cgiStagePresent.cpp @@ -5,13 +5,13 @@  #include <boost/foreach.hpp>  #include <boost/bind.hpp> -CgiApplicationEngine::PresentStage::PresentStage(const CgiEnvironment * e, const boost::filesystem::path & path) : +CgiApplicationEngine::PresentStage::PresentStage(const CgiEnvironment * e, ScriptReaderPtr s) :  	CgiApplicationEngine::ResponseStage(e), -	XmlScriptParser(path, false), -	CheckHost(path), -	ViewHost(path) +	CommonObjects(s), +	CheckHost(s), +	ViewHost(s)  { -	loader.supportedStorers.insert(Storer::into<OutputOptionsLoader>(&outputOptions)); +	s->loader.addLoadTarget(s->root(), Storer::into<OutputOptionsLoader>(&outputOptions));  }  CgiApplicationEngine::NextStage diff --git a/project2/cgi/cgiStageRedirect.cpp b/project2/cgi/cgiStageRedirect.cpp index f72e986..8c918f1 100644 --- a/project2/cgi/cgiStageRedirect.cpp +++ b/project2/cgi/cgiStageRedirect.cpp @@ -29,10 +29,10 @@ namespace CgiApplicationExtras {  	class CgiRedirect : public View {  		public: -			CgiRedirect(const xmlpp::Element * e) : +			CgiRedirect(ScriptNodePtr e) :  				SourceObject(e),  				View(e), -				url(e, "url", true) { +				url(e, "url") {  			}  			void execute(const MultiRowSetPresenter *) const {  				throw CgiApplicationEngine::ResponseStagePtr( diff --git a/project2/cgi/cgiStageRequest.cpp b/project2/cgi/cgiStageRequest.cpp index 4831a71..99ca956 100644 --- a/project2/cgi/cgiStageRequest.cpp +++ b/project2/cgi/cgiStageRequest.cpp @@ -5,13 +5,13 @@  #include "xmlObjectLoader.h"  #include <boost/foreach.hpp> -CgiApplicationEngine::RequestStage::RequestStage(const CgiEnvironment * e, const boost::filesystem::path & path) : -	XmlScriptParser(path, false), -	SourceObject(get_document()->get_root_node()), -	::CheckHost(path), +CgiApplicationEngine::RequestStage::RequestStage(const CgiEnvironment * e, ScriptReaderPtr s) : +	SourceObject(s->root()), +	CommonObjects(s), +	::CheckHost(s),  	CgiApplicationEngine::ResponseStage(e), -	::TaskHost(path), -	present(get_document()->get_root_node()->get_attribute_value("present")) +	::TaskHost(s), +	present(s->root()->value("present","").as<std::string>())  {  } @@ -20,7 +20,7 @@ CgiApplicationEngine::RequestStage::run()  {  	runChecks();  	execute(); -	return NextStage(present.empty() ? NULL : new PresentStage(e, e->resolveScript(e->presentRoot, present)), this); +	return NextStage(present.empty() ? NULL : new PresentStage(e, e->resolveScript(e->presentRoot, present, false)), this);  }  const std::string contentType = "text/plain"; diff --git a/project2/common/Jamfile.jam b/project2/common/Jamfile.jam index 4964ea1..5c6cfc7 100644 --- a/project2/common/Jamfile.jam +++ b/project2/common/Jamfile.jam @@ -1,6 +1,7 @@ -alias libxmlpp : : : : -	<cflags>"`pkg-config --cflags libxml++-2.6`" -	<linkflags>"`pkg-config --libs libxml++-2.6`" ; +alias glibmm : : : : +	<cflags>"`pkg-config --cflags glibmm-2.4`" +	<linkflags>"`pkg-config --libs glibmm-2.4`" +	;  lib dl : : <name>dl ;  lib boost_system : : <name>boost_system ;  lib boost_filesystem : : <name>boost_filesystem ; @@ -8,7 +9,7 @@ lib boost_date_time : : <name>boost_date_time ;  cpp-pch pch : pch.hpp :  	<include>../../libmisc -	<library>libxmlpp +	<library>glibmm   	;  lib p2common :  	pch @@ -18,7 +19,7 @@ lib p2common :  	../../libmisc/misc.cpp  	:  	<include>../../libmisc -	<library>libxmlpp +	<library>glibmm   	<library>dl  	<library>boost_system  	<library>boost_filesystem diff --git a/project2/common/cache.cpp b/project2/common/cache.cpp index 7ad4053..f5edc43 100644 --- a/project2/common/cache.cpp +++ b/project2/common/cache.cpp @@ -5,10 +5,10 @@  #include "logger.h"  #include <boost/foreach.hpp> -Cache::Cache(const xmlpp::Element * p) : +Cache::Cache(ScriptNodePtr p) :  	IHaveParameters(p),  	SourceObject(p), -	inherit(p->get_attribute_value("inherit") != "false") +	inherit(p->value("inherit", true).as<bool>())  {  } diff --git a/project2/common/cache.h b/project2/common/cache.h index eff24b0..2c438b8 100644 --- a/project2/common/cache.h +++ b/project2/common/cache.h @@ -12,7 +12,7 @@ typedef boost::intrusive_ptr<const RowSet> RowSetCPtr;  class Cache : public IHaveParameters, public SourceObject {  	public: -		Cache(const xmlpp::Element * p); +		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; diff --git a/project2/common/checkHost.cpp b/project2/common/checkHost.cpp index 343b255..4f2ab44 100644 --- a/project2/common/checkHost.cpp +++ b/project2/common/checkHost.cpp @@ -3,10 +3,10 @@  #include "appEngine.h"  #include <boost/foreach.hpp> -CheckHost::CheckHost(const boost::filesystem::path & file) : -	XmlScriptParser(file, false) +CheckHost::CheckHost(ScriptReaderPtr s) : +	CommonObjects(s)  { -	loader.supportedStorers.insert(Storer::into<ElementLoader>(¶meterChecks)); +	s->loader.addLoadTarget(s->root(), Storer::into<ElementLoader>(¶meterChecks));  }  CheckHost::~CheckHost() @@ -16,7 +16,7 @@ CheckHost::~CheckHost()  void  CheckHost::runChecks() const  { -	parseDocument(); +	loadScriptComponents();  	BOOST_FOREACH(const ParamCheckers::value_type & pc, parameterChecks) {  		if (!pc->performCheck()) {  			ApplicationEngine::getCurrent()->logMessage(false, pc->group(), pc->message()); diff --git a/project2/common/checkHost.h b/project2/common/checkHost.h index 54fc96d..9a87aea 100644 --- a/project2/common/checkHost.h +++ b/project2/common/checkHost.h @@ -1,13 +1,13 @@  #ifndef CHECKHOST_H  #define CHECKHOST_H -#include "xmlScriptParser.h"  #include "paramChecker.h"  #include "xmlStorage.h"  #include <set>  #include <boost/function.hpp> +#include "commonObjects.h" -class CheckHost : public virtual XmlScriptParser { +class CheckHost : virtual public CommonObjects {  	public:  		class CheckFailure : std::exception {  			public: @@ -15,7 +15,7 @@ class CheckHost : public virtual XmlScriptParser {  				~CheckFailure() throw();  				const ParamCheckerCPtr failedCheck;  		}; -		CheckHost(const boost::filesystem::path & file);  +		CheckHost(ScriptReaderPtr script);   		~CheckHost();  		void runChecks() const; diff --git a/project2/common/columns.cpp b/project2/common/columns.cpp index e64a9f8..268a59d 100644 --- a/project2/common/columns.cpp +++ b/project2/common/columns.cpp @@ -1,11 +1,10 @@  #include <pch.hpp>  #include "columns.h" -#include <libxml++/nodes/textnode.h> -Column::Column(unsigned int i, const xmlpp::Element * p) : +Column::Column(unsigned int i, ScriptNodePtr p) :  	idx(i), -	name(p->get_attribute("name") ? p->get_attribute_value("name") : p->get_child_text()->get_content()), -	defValue(p, "default", false) +	name(p->get_name()), +	defValue(p, "default", Null())  {  } @@ -17,7 +16,7 @@ Column::Column(unsigned int i, const Glib::ustring & n, const Variable & v) :  }  Column * -Column::make(unsigned int idx, const xmlpp::Element * p) +Column::make(unsigned int idx, ScriptNodePtr p)  {  	return new Column(idx, p);  } diff --git a/project2/common/columns.h b/project2/common/columns.h index 8b9b9b3..d0b62d9 100644 --- a/project2/common/columns.h +++ b/project2/common/columns.h @@ -1,7 +1,6 @@  #ifndef COLUMNS_H  #define COLUMNS_H -#include <libxml++/nodes/element.h>  #include "variables.h"  #include <boost/multi_index_container.hpp>  #include <boost/multi_index/member.hpp> @@ -9,10 +8,10 @@  class Column : public IntrusivePtrBase {  	public: -		Column(unsigned int idx, const xmlpp::Element * p); +		Column(unsigned int idx, ScriptNodePtr p);  		Column(unsigned int i, const Glib::ustring & n, const Variable & v = Variable(Null())); -		static Column * make(unsigned int idx, const xmlpp::Element * p); +		static Column * make(unsigned int idx, ScriptNodePtr p);  		const unsigned int idx;  		const Glib::ustring name; diff --git a/project2/common/commonObjects.cpp b/project2/common/commonObjects.cpp index 4ce8c82..5bfe6bc 100644 --- a/project2/common/commonObjects.cpp +++ b/project2/common/commonObjects.cpp @@ -3,7 +3,16 @@  #include "safeMapFind.h"  #include "appEngine.h"  #include "xmlObjectLoader.h" -#include "xmlScriptParser.h" + +CommonObjects::CommonObjects() +{ +} + +CommonObjects::CommonObjects(ScriptReaderPtr s) : +	script(s) +{ +	s->loader.addLoadTarget(s->root(), Storer::into<ElementLoader>(&rowSets)); +}  CommonObjects::~CommonObjects()  { @@ -18,13 +27,18 @@ CommonObjects::getSource(const std::string & name) const  CommonObjects::DataSources::const_iterator  CommonObjects::loadDataSource(const std::string & name) const  { -	XmlScriptParser xml(Environment::getCurrent()->resolveScript( -				Environment::getCurrent()->datasourceRoot, name), true); - -	LoaderBase loader(true); -	loader.supportedStorers.insert(Storer::into<ElementLoader>(&datasources)); -	loader.collectAll(xml.get_document()->get_root_node(), false); - +	ScriptReaderPtr dbs = Environment::getCurrent()->resolveScript(Environment::getCurrent()->datasourceRoot, name, true); +	dbs->loader.addLoadTarget(dbs->root(), Storer::into<ElementLoader>(&datasources)); +	dbs->loader.collectAll(NULL, false, dbs->root());  	return safeMapFind<DataSourceNotFound>(datasources, name);  } +void +CommonObjects::loadScriptComponents() const +{ +	if (script) { +		script->loader.collectAll(this, true, script->root()); +		script.reset(); +	} +} + diff --git a/project2/common/commonObjects.h b/project2/common/commonObjects.h index fe6bd5c..2e00442 100644 --- a/project2/common/commonObjects.h +++ b/project2/common/commonObjects.h @@ -13,7 +13,9 @@ class CommonObjects : public virtual IntrusivePtrBase {  		SimpleMessageException(DataSourceNotFound);  		SimpleMessageException(DataSourceNotCompatible); -		virtual ~CommonObjects(); +		CommonObjects(); +		CommonObjects(ScriptReaderPtr script); +		~CommonObjects();  		RowSetPtr getSource(const std::string &) const;  		template <class DataSourceType> @@ -29,9 +31,13 @@ class CommonObjects : public virtual IntrusivePtrBase {  			}  			return s;  		} +		void loadScriptComponents() const; +  	protected:  		RowSets rowSets;  		mutable DataSources datasources; +		mutable ScriptReaderPtr script; +  	private:  		DataSources::const_iterator loadDataSource(const std::string & name) const;  }; diff --git a/project2/common/dataSource.cpp b/project2/common/dataSource.cpp index 3fedbd8..cd03300 100644 --- a/project2/common/dataSource.cpp +++ b/project2/common/dataSource.cpp @@ -1,7 +1,7 @@  #include <pch.hpp>  #include "dataSource.h" -DataSource::DataSource(const xmlpp::Element * p) : +DataSource::DataSource(ScriptNodePtr p) :  	SourceObject(p)  {  } diff --git a/project2/common/dataSource.h b/project2/common/dataSource.h index d8a5a9a..1f557dd 100644 --- a/project2/common/dataSource.h +++ b/project2/common/dataSource.h @@ -10,7 +10,7 @@ typedef boost::intrusive_ptr<DataSource> DataSourcePtr;  /// Base class for data sources providing transaction support  class DataSource : public SourceObject {  	public: -		DataSource(const xmlpp::Element * p); +		DataSource(ScriptNodePtr p);  		virtual ~DataSource();  		virtual void commit() { }; diff --git a/project2/common/definedColumns.cpp b/project2/common/definedColumns.cpp index 2db8f24..cc88939 100644 --- a/project2/common/definedColumns.cpp +++ b/project2/common/definedColumns.cpp @@ -1,16 +1,12 @@  #include <pch.hpp>  #include "definedColumns.h"  #include <boost/function.hpp> -#include <libxml++/nodes/textnode.h> -DefinedColumns::DefinedColumns(const xmlpp::Element * p, const Glib::ustring & colPath, const ColCreator & func) +DefinedColumns::DefinedColumns(ScriptNodePtr p, const Glib::ustring & colPath, const ColCreator & func)  {  	unsigned int colNo = 0; -	BOOST_FOREACH(const xmlpp::Node * node, p->find(colPath)) { -		const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node); -		if (elem) { -			columns.insert(func(colNo++, elem)); -		} +	BOOST_FOREACH(ScriptNodePtr node, p->childrenIn(colPath)) { +		columns.insert(func(colNo++, node));  	}  } diff --git a/project2/common/definedColumns.h b/project2/common/definedColumns.h index 2fc6bbd..89d42be 100644 --- a/project2/common/definedColumns.h +++ b/project2/common/definedColumns.h @@ -1,7 +1,6 @@  #ifndef DEFINEDCOLUMNS_H  #define DEFINEDCOLUMNS_H -#include <libxml++/nodes/element.h>  #include <boost/foreach.hpp>  #include "variables.h"  #include "rowSet.h" @@ -9,8 +8,8 @@  class DefinedColumns {  	public: -		typedef boost::function2<Column *, unsigned int, const xmlpp::Element *> ColCreator; -		DefinedColumns(const xmlpp::Element * p, const Glib::ustring & colPath, const ColCreator & func); +		typedef boost::function2<Column *, unsigned int, ScriptNodePtr> ColCreator; +		DefinedColumns(ScriptNodePtr p, const Glib::ustring & colPath, const ColCreator & func);  		Columns columns;  }; diff --git a/project2/common/environment.cpp b/project2/common/environment.cpp index 18d60a0..e99be54 100644 --- a/project2/common/environment.cpp +++ b/project2/common/environment.cpp @@ -90,20 +90,21 @@ Environment::getCurrent()  	return currentEnv;  } -boost::filesystem::path -Environment::resolveScript(const std::string & group, const std::string & name) const +ScriptReaderPtr +Environment::resolveScript(const std::string & group, const std::string & name, bool ii) const  { -	boost::filesystem::path script(boost::filesystem::current_path() / group); -	BOOST_FOREACH(const boost::filesystem::path & e, boost::filesystem::path(name)) { -		if (boost::filesystem::is_directory(script / e)) { -			script /= e; -		} -		else { -			if (boost::filesystem::is_regular_file((script / e).replace_extension(".xml"))) { -				return ((script / e).replace_extension(".xml")); -			} +	typedef std::map<std::string, boost::shared_ptr<ScriptReaderLoader> > ReaderLoaders; +	BOOST_FOREACH(const ReaderLoaders::value_type & rl, *LoaderBase::objLoaders<ScriptReaderLoader>()) { +		ScriptReaderPtr rs = rl.second->resolveScript(group, name); +		if (rs) { +			return rs;  		}  	} -	return script; +	if (ii) { +		throw DependencyNotFound(group, name); +	} +	else { +		throw ScriptNotFound(group, name); +	}  } diff --git a/project2/common/environment.h b/project2/common/environment.h index 6185178..c2b9474 100644 --- a/project2/common/environment.h +++ b/project2/common/environment.h @@ -7,6 +7,7 @@  #include <boost/filesystem/path.hpp>  #include "options.h"  #include "exceptions.h" +#include "scripts.h"  SimpleMessageException(NoSuchPlatform); @@ -26,7 +27,7 @@ class Environment {  		virtual std::string getScriptName() const = 0;  		virtual const Glib::ustring & platform() const = 0; -		boost::filesystem::path resolveScript(const std::string & group, const std::string & name) const; +		ScriptReaderPtr resolveScript(const std::string & group, const std::string & name, bool ii) const;  	private:  		Options commonOptions; diff --git a/project2/common/exceptions.cpp b/project2/common/exceptions.cpp index d347f5f..2fa5509 100644 --- a/project2/common/exceptions.cpp +++ b/project2/common/exceptions.cpp @@ -25,3 +25,26 @@ numeric_error::what() const throw()  	return buf;  } +two_part_error::two_part_error(const std::string & w1, const std::string & w2) : +	what1(w1), +	what2(w2), +	buf(NULL) +{ +} + +two_part_error::~two_part_error() throw() +{ +	free(buf); +} + +const char * +two_part_error::what() const throw() +{ +	if (!buf) { +		if (asprintf(&buf, "%s, %s", what1.c_str(), what2.c_str()) < 1) { +			throw std::bad_alloc(); +		} +	} +	return buf; +} + diff --git a/project2/common/exceptions.h b/project2/common/exceptions.h index a9d4952..a45e53d 100644 --- a/project2/common/exceptions.h +++ b/project2/common/exceptions.h @@ -12,6 +12,16 @@ class numeric_error : public std::exception {  		int err;  		mutable char * buf;  }; +class two_part_error : public std::exception { +	public: +		two_part_error(const std::string & what1, const std::string & what2); +		~two_part_error() throw(); +		const char * what() const throw(); +	private: +		const std::string what1; +		const std::string what2; +		mutable char * buf; +};  #define StaticMessageException(Name, Text) \  class Name : public std::runtime_error { \  	public: \ @@ -22,6 +32,11 @@ class Name : public std::runtime_error { \  	public: \  		Name(const std::string & what) : std::runtime_error(what) { } \  } +#define SimpleMessage2Exception(Name) \ +class Name : public two_part_error { \ +	public: \ +		Name(const std::string & what1, const std::string & what2) : two_part_error(what1, what2) { } \ +}  #define SimpleMessageExceptionBase(Name, Base) \  class Name : public Base { \  	public: \ diff --git a/project2/common/functions/dates.cpp b/project2/common/functions/dates.cpp index da169cf..8028789 100644 --- a/project2/common/functions/dates.cpp +++ b/project2/common/functions/dates.cpp @@ -11,7 +11,7 @@ class ParseError { };  /// Variable implementation to access platform configuration values  class ParseDate : public VariableImplDyn {  	public: -		ParseDate(const xmlpp::Element * e) : +		ParseDate(ScriptNodePtr e) :  			VariableImplDyn(e),  			string(e, "string"),  			format(e, "format") @@ -41,7 +41,7 @@ DECLARE_COMPONENT_LOADER("parsedate", ParseDate, VariableLoader);  class FormatDate : public VariableImplDyn {  	public: -		FormatDate(const xmlpp::Element * e) : +		FormatDate(ScriptNodePtr e) :  			VariableImplDyn(e),  			date(e, "date"),  			format(e, "format") @@ -64,7 +64,7 @@ DECLARE_COMPONENT_LOADER("formatdate", FormatDate, VariableLoader);  class AdjustDate : public VariableImplDyn {  	public: -		AdjustDate(const xmlpp::Element * e) : +		AdjustDate(ScriptNodePtr e) :  			VariableImplDyn(e),  			date(e, "date"),  			offset(e, "offset") @@ -82,7 +82,7 @@ DECLARE_COMPONENT_LOADER("adjustdate", AdjustDate, VariableLoader);  class CurrentDate : public VariableImplDyn {  	public: -		CurrentDate(const xmlpp::Element * e) : +		CurrentDate(ScriptNodePtr e) :  			VariableImplDyn(e)  		{  		} diff --git a/project2/common/functions/strings.cpp b/project2/common/functions/strings.cpp index 1272c6c..d2967d2 100644 --- a/project2/common/functions/strings.cpp +++ b/project2/common/functions/strings.cpp @@ -6,7 +6,7 @@  /// Variable implementation to access platform configuration values  class Trim : public VariableImplDyn {  	public: -		Trim(const xmlpp::Element * e) : +		Trim(ScriptNodePtr e) :  			VariableImplDyn(e),  			string(e, "string")  		{ diff --git a/project2/common/iHaveParameters.cpp b/project2/common/iHaveParameters.cpp index cded7e1..5272e5f 100644 --- a/project2/common/iHaveParameters.cpp +++ b/project2/common/iHaveParameters.cpp @@ -7,12 +7,10 @@  IHaveParameters::Stack IHaveParameters::scope; -IHaveParameters::IHaveParameters(const xmlpp::Element * p) +IHaveParameters::IHaveParameters(ScriptNodePtr p)  { -	BOOST_FOREACH(xmlpp::Node * node, p->find("parameters/*")) { -		if (const xmlpp::Element * pelem = dynamic_cast<const xmlpp::Element *>(node)) { -			parameters.insert(Parameters::value_type(pelem->get_name(), Variable(pelem, boost::optional<Glib::ustring>()))); -		} +	BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("parameters")) { +		parameters.insert(Parameters::value_type(node->get_name(), Variable(node)));  	}  } diff --git a/project2/common/iHaveParameters.h b/project2/common/iHaveParameters.h index 08c8d00..2b7ed2a 100644 --- a/project2/common/iHaveParameters.h +++ b/project2/common/iHaveParameters.h @@ -1,7 +1,6 @@  #ifndef IHAVEPARAMETERS  #define IHAVEPARAMETERS -#include <libxml++/nodes/element.h>  #include <boost/intrusive_ptr.hpp>  #include <vector>  #include "variables.h" @@ -12,7 +11,7 @@ class IHaveParameters {  	public:  		typedef std::map<Glib::ustring, Variable> Parameters; -		IHaveParameters(const xmlpp::Element * p); +		IHaveParameters(ScriptNodePtr p);  		virtual ~IHaveParameters() = 0;  		const Parameters & allParameters() const; diff --git a/project2/common/iHaveSubTasks.cpp b/project2/common/iHaveSubTasks.cpp index 586dff8..78868aa 100644 --- a/project2/common/iHaveSubTasks.cpp +++ b/project2/common/iHaveSubTasks.cpp @@ -2,7 +2,7 @@  #include "iHaveSubTasks.h"  #include <boost/foreach.hpp> -IHaveSubTasks::IHaveSubTasks(const xmlpp::Element * e) : +IHaveSubTasks::IHaveSubTasks(ScriptNodePtr e) :  	SourceObject(e),  	NoOutputExecute(e)  { diff --git a/project2/common/iHaveSubTasks.h b/project2/common/iHaveSubTasks.h index c2d2022..e52a9be 100644 --- a/project2/common/iHaveSubTasks.h +++ b/project2/common/iHaveSubTasks.h @@ -8,7 +8,7 @@ class IHaveSubTasks : public NoOutputExecute {  	public:  		typedef ANONORDEREDSTORAGEOF(NoOutputExecute) Tasks; -		IHaveSubTasks(const xmlpp::Element * p); +		IHaveSubTasks(ScriptNodePtr p);  		IHaveSubTasks(const std::string & n);  		virtual ~IHaveSubTasks(); diff --git a/project2/common/if.cpp b/project2/common/if.cpp index a810146..0f982ec 100644 --- a/project2/common/if.cpp +++ b/project2/common/if.cpp @@ -10,12 +10,10 @@ DECLARE_LOADER("if", If);  SimpleMessageException(IfModeIsNonsense); -IfSet::IfSet(const xmlpp::Element * e) : -	mode(e->get_attribute_value("mode") == "or" ? Or : And) +IfSet::IfSet(ScriptNodePtr e) : +	mode(e->value("mode", "and").as<Glib::ustring>() == "or" ? Or : And)  { -	LoaderBase loader(true); -	loader.supportedStorers.insert(Storer::into<ElementLoader>(&checks)); -	loader.collectAll(e, true, IgnoreUnsupported); +	e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&checks));  }  template <class Range, class Pred> @@ -41,23 +39,21 @@ IfSet::passes() const  	throw IfModeIsNonsense(getName());  } -If::If(const xmlpp::Element * e) : +If::If(ScriptNodePtr e) :  	SourceObject(e),  	IHaveSubTasks(e),  	View(e),  	IfSet(e)  { -	LoaderBase loader(true); -	loader.supportedStorers.insert(Storer::into<ElementLoader>(&normal)); -	loader.supportedStorers.insert(Storer::into<ElementLoader>(&subViews)); -	loader.collectAll(e, true, IgnoreUnsupported); +	e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&normal)); +	e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&subViews));  }  void  If::execute(const MultiRowSetPresenter * presenter) const  {  	if (passes()) { -		Logger()->messagef(LOG_DEBUG, "IfSet passed, showing %zu views", subViews.size()); +		Logger()->messagef(LOG_DEBUG, "IfSet passed %zu checks, showing %zu views", checks.size(), subViews.size());  		BOOST_FOREACH(const SubViews::value_type & sq, subViews) {  			sq->execute(presenter);  		} diff --git a/project2/common/if.h b/project2/common/if.h index 28299ba..e27003d 100644 --- a/project2/common/if.h +++ b/project2/common/if.h @@ -7,7 +7,7 @@  class IfSet : public virtual IntrusivePtrBase {  	public: -		IfSet(const xmlpp::Element *); +		IfSet(ScriptNodePtr);  		bool passes() const;  	private: @@ -15,13 +15,14 @@ class IfSet : public virtual IntrusivePtrBase {  		enum Mode { And, Or };  		Mode mode;  		typedef ANONORDEREDSTORAGEOF(ParamChecker) ParamCheckers; +	protected:  		ParamCheckers checks;  };  /// Project2 component to conditionally execute its children  class If : public IHaveSubTasks, public View, public IfSet {  	public: -		If(const xmlpp::Element *); +		If(ScriptNodePtr);  		virtual void execute(const MultiRowSetPresenter*) const;  		virtual void execute() const; diff --git a/project2/common/iterate.cpp b/project2/common/iterate.cpp index ba8a4b9..9c7592e 100644 --- a/project2/common/iterate.cpp +++ b/project2/common/iterate.cpp @@ -8,14 +8,12 @@  DECLARE_LOADER("iterate", Iterate); -Iterate::Iterate(const xmlpp::Element * p) : +Iterate::Iterate(ScriptNodePtr p) :  	SourceObject(p),  	IHaveSubTasks(p),  	RowProcessor(p)  { -	LoaderBase loader(true); -	loader.supportedStorers.insert(Storer::into<ElementLoader>(&normal)); -	loader.collectAll(p, true, IgnoreUnsupported); +	p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&normal));  }  Iterate::~Iterate() diff --git a/project2/common/iterate.h b/project2/common/iterate.h index 50fd879..aa0b0e8 100644 --- a/project2/common/iterate.h +++ b/project2/common/iterate.h @@ -1,7 +1,6 @@  #ifndef ITERATE_H  #define ITERATE_H -#include <libxml++/nodes/element.h>  #include "rowProcessor.h"  #include "iHaveSubTasks.h"  #include "xmlStorage.h" @@ -12,7 +11,7 @@ typedef boost::intrusive_ptr<Iterate> IteratePtr;  /// Project2 component to iterate over a row set, executing its children for each record  class Iterate : public IHaveSubTasks, public RowProcessor {  	public: -		Iterate(const xmlpp::Element * p); +		Iterate(ScriptNodePtr p);  		virtual ~Iterate();  		void loadComplete(const CommonObjects *); diff --git a/project2/common/library.cpp b/project2/common/library.cpp index 711e14f..0c4fa7b 100644 --- a/project2/common/library.cpp +++ b/project2/common/library.cpp @@ -2,12 +2,13 @@  #include <dlfcn.h>  #include "xmlStorage.h"  #include "exceptions.h" +#include "scripts.h"  #include "library.h"  SimpleMessageException(LoadLibraryFailed);  SimpleMessageException(UnloadLibraryFailed); -Library::Library(const xmlpp::Element * p) : +Library::Library(ScriptNodePtr p) :  	SourceObject(p),  	handle(dlopen(Variable(p, "path")(), RTLD_NOW))  { diff --git a/project2/common/library.h b/project2/common/library.h index 523dcf4..892c075 100644 --- a/project2/common/library.h +++ b/project2/common/library.h @@ -5,7 +5,7 @@  class Library : public SourceObject {  	public: -		Library(const xmlpp::Element * p); +		Library(ScriptNodePtr p);  		~Library();  	private: diff --git a/project2/common/memoryCache.cpp b/project2/common/memoryCache.cpp index 5942cb8..ea7fb84 100644 --- a/project2/common/memoryCache.cpp +++ b/project2/common/memoryCache.cpp @@ -94,7 +94,7 @@ class MemoryCache : public Cache {  				boost::multi_index::tag<IndexByTime>, BOOST_MULTI_INDEX_MEMBER(CachedRowSet, const time_t, createdAt)>  				> > CacheStore; -		MemoryCache(const xmlpp::Element * p) : +		MemoryCache(ScriptNodePtr p) :  			Cache(p)  		{  		} diff --git a/project2/common/noOutputExecute.cpp b/project2/common/noOutputExecute.cpp index 5b1cb36..02c8f71 100644 --- a/project2/common/noOutputExecute.cpp +++ b/project2/common/noOutputExecute.cpp @@ -2,7 +2,7 @@  #include "noOutputExecute.h"  #include <boost/foreach.hpp> -NoOutputExecute::NoOutputExecute(const xmlpp::Element * p) : +NoOutputExecute::NoOutputExecute(ScriptNodePtr p) :  	SourceObject(p)  {  } diff --git a/project2/common/noOutputExecute.h b/project2/common/noOutputExecute.h index 1047f38..fffea9c 100644 --- a/project2/common/noOutputExecute.h +++ b/project2/common/noOutputExecute.h @@ -10,7 +10,7 @@ typedef boost::intrusive_ptr<NoOutputExecute> NoOutputExecutePtr;  /// Base class for Project2 compoments that perform actions, but product no output  class NoOutputExecute : public virtual SourceObject {  	public: -		NoOutputExecute(const xmlpp::Element * p); +		NoOutputExecute(ScriptNodePtr p);  		NoOutputExecute(const std::string & n);  		virtual ~NoOutputExecute(); diff --git a/project2/common/paramChecker.cpp b/project2/common/paramChecker.cpp index ad61b3a..fe49fa3 100644 --- a/project2/common/paramChecker.cpp +++ b/project2/common/paramChecker.cpp @@ -2,11 +2,11 @@  #include "paramChecker.h"  #include "xmlObjectLoader.h" -ParamChecker::ParamChecker(const xmlpp::Element * p) : +ParamChecker::ParamChecker(ScriptNodePtr p) :  	SourceObject(p), -	message(p, "message", false, "Check failed"), -	group(p, "group", false, "default"), -	present(p, "present", false, "") +	message(p, "message", "Check failed"), +	group(p, "group", "default"), +	present(p, "present", "")  {  } diff --git a/project2/common/paramChecker.h b/project2/common/paramChecker.h index b0940c9..db3d8de 100644 --- a/project2/common/paramChecker.h +++ b/project2/common/paramChecker.h @@ -1,14 +1,13 @@  #ifndef PARAMCHECKER_H  #define PARAMCHECKER_H -#include <libxml/tree.h>  #include "sourceObject.h"  #include "variables.h"  /// Base class for Project2 compoments that perform tests/checks  class ParamChecker : public SourceObject {  	public: -		ParamChecker(const xmlpp::Element * p); +		ParamChecker(ScriptNodePtr p);  		virtual ~ParamChecker();  		virtual bool performCheck() const = 0; diff --git a/project2/common/pch.hpp b/project2/common/pch.hpp index 536dc5a..54637e0 100644 --- a/project2/common/pch.hpp +++ b/project2/common/pch.hpp @@ -14,9 +14,6 @@  #include <glibmm/ustring.h>  #include <intrusivePtrBase.h>  #include <iostream> -#include <libxml++/attribute.h> -#include <libxml++/nodes/element.h> -#include <libxml++/nodes/textnode.h>  #include <list>  #include <map>  #include <set> @@ -29,6 +26,7 @@  #include "xmlObjectLoader.h"  #include "variables.h"  #include "sourceObject.h" +#include "scripts.h"  #endif  #endif diff --git a/project2/common/presenter.h b/project2/common/presenter.h index 6a72495..c0cc700 100644 --- a/project2/common/presenter.h +++ b/project2/common/presenter.h @@ -77,14 +77,14 @@ typedef boost::intrusive_ptr<NameValuePairPresenter> NameValuePairPresenterPtr;  /// Base class to implement presenter modules  class PresenterLoader : public ComponentLoader {  	public: -		virtual MultiRowSetPresenterPtr createFrom(const xmlpp::Element * e) const = 0; +		virtual MultiRowSetPresenterPtr createFrom(ScriptNodePtr e) const = 0;  };  /// Helper implemention for specific presenters  template <class PresenterType>  class PresenterLoaderImpl : public PresenterLoader {  	public: -		virtual MultiRowSetPresenterPtr createFrom(const xmlpp::Element * e) const +		virtual MultiRowSetPresenterPtr createFrom(ScriptNodePtr e) const  		{  			return new PresenterType(e);  		} diff --git a/project2/common/rowProcessor.cpp b/project2/common/rowProcessor.cpp index e186c43..e2ce6ba 100644 --- a/project2/common/rowProcessor.cpp +++ b/project2/common/rowProcessor.cpp @@ -5,16 +5,14 @@  #include "scopeObject.h"  #include <boost/foreach.hpp> -RowProcessor::RowProcessor(const xmlpp::Element * p) : +RowProcessor::RowProcessor(ScriptNodePtr p) :  	IHaveParameters(p), -	recordSource(p->get_attribute_value("source")), -	filter(p->get_attribute_value("filter")), -	CROE(Variable(p, "cacheRowsOnError", false, false)()), -	IRSE(Variable(p, "ignoreRowSourceError", false, false)()) +	recordSource(p->value("source").as<std::string>()), +	filter(p->value("filter", "").as<Glib::ustring>()), +	CROE(p->value("cacheRowsOnError", false)), +	IRSE(p->value("ignoreRowSourceError", false))  { -	LoaderBase loader(true); -	loader.supportedStorers.insert(Storer::into<ElementLoader>(&caches)); -	loader.collectAll(p, true, IgnoreUnsupported); +	p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&caches));  }  void diff --git a/project2/common/rowProcessor.h b/project2/common/rowProcessor.h index e435bf4..18beac7 100644 --- a/project2/common/rowProcessor.h +++ b/project2/common/rowProcessor.h @@ -13,7 +13,7 @@ class Presenter;  /// Base class for Project2 components that work with row sets  class RowProcessor : public IHaveParameters {  	public: -		RowProcessor(const xmlpp::Element *); +		RowProcessor(ScriptNodePtr);  		void loadComplete(const CommonObjects *);  		const std::string recordSource; diff --git a/project2/common/rowSet.cpp b/project2/common/rowSet.cpp index 77d2a2d..cc397d1 100644 --- a/project2/common/rowSet.cpp +++ b/project2/common/rowSet.cpp @@ -10,7 +10,7 @@  RowState::RowValuesStack RowState::stack; -RowSet::RowSet(const xmlpp::Element * p) : +RowSet::RowSet(ScriptNodePtr p) :  	SourceObject(p)  {  } diff --git a/project2/common/rowSet.h b/project2/common/rowSet.h index a181059..2845983 100644 --- a/project2/common/rowSet.h +++ b/project2/common/rowSet.h @@ -23,7 +23,7 @@ class RowSet : public SourceObject {  		SimpleMessageException(FieldDoesNotExist);  		SimpleNumericException(FieldOutOfRange); -		RowSet(const xmlpp::Element *); +		RowSet(ScriptNodePtr);  		virtual ~RowSet() = 0;  		virtual void execute(const Glib::ustring &, const RowProcessor *) const = 0; diff --git a/project2/common/rowView.cpp b/project2/common/rowView.cpp index 5e01061..35b410d 100644 --- a/project2/common/rowView.cpp +++ b/project2/common/rowView.cpp @@ -6,25 +6,20 @@  #include "scopeObject.h"  #include <boost/foreach.hpp>  #include <boost/bind.hpp> -#include <libxml++/nodes/textnode.h>  DECLARE_LOADER("view", RowView); -RowView::RowView(const xmlpp::Element * p) : +RowView::RowView(ScriptNodePtr p) :  	SourceObject(p),  	View(p),  	RowProcessor(p),  	rootName(p, "rootname"),  	recordName(p, "recordname")  { -	BOOST_FOREACH(xmlpp::Node * node, p->find("columns/*")) { -		if (const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node)) { -			viewColumns.insert(Columns::value_type(elem->get_name(), Variable(elem, boost::optional<Glib::ustring>()))); -		} +	BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("columns")) { +		viewColumns.insert(Columns::value_type(node->get_name(), Variable(node)));  	} -	LoaderBase loader(true); -	loader.supportedStorers.insert(Storer::into<ElementLoader>(&subViews)); -	loader.collectAll(p, true, IgnoreUnsupported); +	p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&subViews));  }  RowView::~RowView() diff --git a/project2/common/rowView.h b/project2/common/rowView.h index 558284c..4b90884 100644 --- a/project2/common/rowView.h +++ b/project2/common/rowView.h @@ -1,7 +1,6 @@  #ifndef ROWVIEW_H  #define ROWVIEW_H -#include <libxml++/nodes/element.h>  #include <boost/intrusive_ptr.hpp>  #include "rowProcessor.h"  #include "view.h" @@ -9,7 +8,7 @@  /// Project2 component to create output based on a records in a row set  class RowView : public View, public RowProcessor {  	public: -		RowView(const xmlpp::Element *); +		RowView(ScriptNodePtr);  		virtual ~RowView();  		void loadComplete(const CommonObjects *); diff --git a/project2/common/scripts.cpp b/project2/common/scripts.cpp new file mode 100644 index 0000000..4d15cfe --- /dev/null +++ b/project2/common/scripts.cpp @@ -0,0 +1,29 @@ +#include "scripts.h" +#include "variables-modfixed.h" + +ScriptNode::ScriptNode(ScriptReaderPtr s) : +	script(s) +{ +} + +VariableImpl * +ScriptNode::variable(const Glib::ustring & n, const VariableType & def) const +{ +	try { +		return variable(n); +	} +	catch (const ValueNotFound &) { +		return new VariableFixed(def); +	} +} + +VariableType +ScriptNode::value(const Glib::ustring & n, const VariableType & def) const +{ +	try { +		return value(n); +	} +	catch (const ValueNotFound &) { +		return def; +	} +} diff --git a/project2/common/scripts.h b/project2/common/scripts.h new file mode 100644 index 0000000..2db4bad --- /dev/null +++ b/project2/common/scripts.h @@ -0,0 +1,64 @@ +#ifndef SCRIPTS_H +#define SCRIPTS_H + +#include "intrusivePtrBase.h" +#include <boost/intrusive_ptr.hpp> +#include <boost/function.hpp> +#include <boost/optional.hpp> +#include "xmlObjectLoader.h" +#include "exceptions.h" +#include "variables.h" +#include <vector> + +SimpleMessageException(ValueNotFound); +SimpleMessage2Exception(ScriptNotFound); +SimpleMessage2Exception(DependencyNotFound); + +class ScriptNode; +class ScriptReader; +typedef boost::intrusive_ptr<const ScriptNode> ScriptNodePtr; +typedef boost::intrusive_ptr<ScriptReader> ScriptReaderPtr; + +class ScriptNode : public IntrusivePtrBase { +	public: +		ScriptNode(ScriptReaderPtr); + +		typedef std::vector<ScriptNodePtr> ScriptNodes; +		typedef boost::function1<void, const VariableType &> LiteralCallback; +		typedef boost::function1<void, ScriptNodePtr> NodeCallback; + +		virtual bool componentNamespace() const = 0; +		virtual std::string get_name() const = 0; +		 +		// Child called name +		virtual ScriptNodePtr child(const Glib::ustring & name) const = 0; +		// All children +		virtual ScriptNodes children() const = 0; +		// All children in sub +		virtual ScriptNodes childrenIn(const Glib::ustring & sub) const = 0; +		 +		virtual bool valueExists(const Glib::ustring & name) 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; +		virtual VariableType value(const Glib::ustring & name) const = 0; +		VariableType value(const Glib::ustring & name, const VariableType & def) const; +		virtual void composeWithCallbacks(const LiteralCallback &, const NodeCallback &) const = 0; + +		const ScriptReaderPtr script; +}; + +class ScriptReader : public virtual IntrusivePtrBase { +	public: +		virtual ScriptNodePtr root() = 0; +		LoaderBase loader; +}; + +/// Base class to implement script reader modules +class ScriptReaderLoader : public ComponentLoader { +	public: +		virtual ScriptReaderPtr resolveScript(const std::string & group, const std::string & name) const = 0; +}; + +#endif + diff --git a/project2/common/sessionClearTask.cpp b/project2/common/sessionClearTask.cpp index 17dcf8f..9fba697 100644 --- a/project2/common/sessionClearTask.cpp +++ b/project2/common/sessionClearTask.cpp @@ -7,10 +7,10 @@  DECLARE_LOADER("sessionclear", SessionClearTask); -SessionClearTask::SessionClearTask(const xmlpp::Element * p) : +SessionClearTask::SessionClearTask(ScriptNodePtr p) :  	SourceObject(p),  	Task(p), -	key(p->get_attribute_value("key")) +	key(p->value("key").as<Glib::ustring>())  {  } diff --git a/project2/common/sessionClearTask.h b/project2/common/sessionClearTask.h index 5df0aa5..224c951 100644 --- a/project2/common/sessionClearTask.h +++ b/project2/common/sessionClearTask.h @@ -1,7 +1,6 @@  #ifndef SESSIONCLEARTASK_H  #define SESSIONCLEARTASK_H -#include <libxml++/nodes/element.h>  #include <boost/intrusive_ptr.hpp>  #include <map>  #include "sourceObject.h" @@ -13,7 +12,7 @@ class CommonObjects;  /// Project2 component to remove a variable from the session  class SessionClearTask : public Task {  	public: -		SessionClearTask(const xmlpp::Element * p); +		SessionClearTask(ScriptNodePtr p);  		virtual ~SessionClearTask();  		void execute() const; diff --git a/project2/common/sessionSetTask.cpp b/project2/common/sessionSetTask.cpp index 69e05c5..8cf0788 100644 --- a/project2/common/sessionSetTask.cpp +++ b/project2/common/sessionSetTask.cpp @@ -7,10 +7,10 @@  DECLARE_LOADER("sessionset", SessionSetTask); -SessionSetTask::SessionSetTask(const xmlpp::Element * p) : +SessionSetTask::SessionSetTask(ScriptNodePtr p) :  	SourceObject(p),  	Task(p), -	key(p->get_attribute_value("key")), +	key(p->value("key").as<Glib::ustring>()),  	value(p, "value")  {  } diff --git a/project2/common/sessionSetTask.h b/project2/common/sessionSetTask.h index 1fddbba..c9b22e5 100644 --- a/project2/common/sessionSetTask.h +++ b/project2/common/sessionSetTask.h @@ -1,7 +1,6 @@  #ifndef SESSIONSETTASK_H  #define SESSIONSETTASK_H -#include <libxml++/nodes/element.h>  #include <boost/intrusive_ptr.hpp>  #include <map>  #include "sourceObject.h" @@ -14,7 +13,7 @@ class CommonObjects;  /// Project2 component to add/update a variable in the session  class SessionSetTask : public Task {  	public: -		SessionSetTask(const xmlpp::Element * p); +		SessionSetTask(ScriptNodePtr p);  		virtual ~SessionSetTask();  		void execute() const; diff --git a/project2/common/singleton.cpp b/project2/common/singleton.cpp index eb78a48..91c80ff 100644 --- a/project2/common/singleton.cpp +++ b/project2/common/singleton.cpp @@ -1,5 +1,4 @@  #include <pch.hpp> -#include <libxml++/nodes/element.h>  #include "view.h"  #include "iHaveParameters.h"  #include "presenter.h" @@ -7,18 +6,14 @@  class Singleton : public View {  	public: -		Singleton(const xmlpp::Element * p) : +		Singleton(ScriptNodePtr p) :  			SourceObject(p),  			View(p),  			rootName(p, "rootname") { -			BOOST_FOREACH(xmlpp::Node * node, p->find("columns/*")) { -				if (const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node)) { -					viewColumns.insert(Columns::value_type(elem->get_name(), Variable(elem, boost::optional<Glib::ustring>()))); -				} +			BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("columns")) { +				viewColumns.insert(Columns::value_type(node->get_name(), Variable(node)));  			} -			LoaderBase loader(true); -			loader.supportedStorers.insert(Storer::into<ElementLoader>(&subViews)); -			loader.collectAll(p, true, IgnoreUnsupported); +			p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&subViews));  		}  		void execute(const MultiRowSetPresenter * p) const  		{ diff --git a/project2/common/sourceObject.cpp b/project2/common/sourceObject.cpp index f0423cb..ccc1034 100644 --- a/project2/common/sourceObject.cpp +++ b/project2/common/sourceObject.cpp @@ -3,8 +3,8 @@  unsigned int SourceObject::loadOrder = 1; -SourceObject::SourceObject(const xmlpp::Element * p) : -	name(p ? p->get_attribute_value("name") : "anon"), +SourceObject::SourceObject(ScriptNodePtr p) : +	name(p ? p->value("name", "anon").as<std::string>() : "anon"),  	order(loadOrder++)  {  } diff --git a/project2/common/sourceObject.h b/project2/common/sourceObject.h index 6a6df55..4d10dd4 100644 --- a/project2/common/sourceObject.h +++ b/project2/common/sourceObject.h @@ -1,17 +1,19 @@  #ifndef SOURCEOBJECT_H  #define SOURCEOBJECT_H -#include <libxml++/nodes/element.h>  #include <boost/intrusive_ptr.hpp> +#include <string>  #include "intrusivePtrBase.h"  class CommonObjects;  class SourceObject; +class ScriptNode;  typedef boost::intrusive_ptr<SourceObject> SourceObjectPtr; +typedef boost::intrusive_ptr<const ScriptNode> ScriptNodePtr;  /// Base class for all Project2 components that can be placed in a Project2 script  class SourceObject : public virtual IntrusivePtrBase {  	public: -		SourceObject(const xmlpp::Element * p); +		SourceObject(ScriptNodePtr p);  		SourceObject(const std::string & name);  		virtual ~SourceObject() = 0; diff --git a/project2/common/structExceptHandling.cpp b/project2/common/structExceptHandling.cpp index 0f176c9..bfd2f2b 100644 --- a/project2/common/structExceptHandling.cpp +++ b/project2/common/structExceptHandling.cpp @@ -2,30 +2,44 @@  #include "structExceptHandling.h"  #include "xmlObjectLoader.h"  #include "xmlStorage.h" +#include "scripts.h"  #include <boost/foreach.hpp>  DECLARE_LOADER("handler", StructuredExceptionHandler); -static void -loadHelper(const char * name, const xmlpp::Element * root, ANONORDEREDSTORAGEOF(NoOutputExecute) * noes) +static +ScriptNodePtr +loadHelperSub(const char * name, bool required, ScriptNodePtr root)  { -	LoaderBase loader(true); -	loader.supportedStorers.insert(Storer::into<ElementLoader>(noes)); -	BOOST_FOREACH(const xmlpp::Node * node, root->find(name)) { -		const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node); -		if (elem) { -			loader.collectAll(elem, true, ErrorOnUnsupported); +	if (required) { +		return root->child(name); +	} +	else { +		try { +			return root->child(name);  		} +		catch (const ValueNotFound &) { +			return NULL; +		} +	} +} +static +void +loadHelper(const char * name, bool required, ScriptNodePtr root, ANONORDEREDSTORAGEOF(NoOutputExecute) * noes) +{ +	ScriptNodePtr c = loadHelperSub(name, required, root); +	if (c) { +		root->script->loader.addLoadTarget(c, Storer::into<ElementLoader>(noes));  	}  } -StructuredExceptionHandler::StructuredExceptionHandler(const xmlpp::Element * e) : +StructuredExceptionHandler::StructuredExceptionHandler(ScriptNodePtr e) :  	SourceObject(e),  	IHaveSubTasks(e)  { -	loadHelper("try", e, &normal); -	loadHelper("catch", e, &catches); -	loadHelper("finally", e, &finallies); +	loadHelper("try", true, e, &normal); +	loadHelper("catch", false, e, &catches); +	loadHelper("finally", false, e, &finallies);  }  void diff --git a/project2/common/structExceptHandling.h b/project2/common/structExceptHandling.h index eabd384..067c389 100644 --- a/project2/common/structExceptHandling.h +++ b/project2/common/structExceptHandling.h @@ -5,7 +5,7 @@  class StructuredExceptionHandler : public IHaveSubTasks {  	public: -		StructuredExceptionHandler(const xmlpp::Element *); +		StructuredExceptionHandler(ScriptNodePtr);  		void loadComplete(const CommonObjects*);  		void execute() const; diff --git a/project2/common/task.cpp b/project2/common/task.cpp index 823382b..c4275f8 100644 --- a/project2/common/task.cpp +++ b/project2/common/task.cpp @@ -2,7 +2,7 @@  #include "task.h"  #include <boost/foreach.hpp> -Task::Task(const xmlpp::Element * p) : +Task::Task(ScriptNodePtr p) :  	SourceObject(p),  	NoOutputExecute(p)  { diff --git a/project2/common/task.h b/project2/common/task.h index 57697e2..5303f15 100644 --- a/project2/common/task.h +++ b/project2/common/task.h @@ -1,14 +1,13 @@  #ifndef TASK_H  #define TASK_H -#include <libxml++/nodes/element.h>  #include "sourceObject.h"  #include "noOutputExecute.h"  /// Base class for Project2 components that perform some specific task  class Task : public NoOutputExecute {  	public: -		Task(const xmlpp::Element * p); +		Task(ScriptNodePtr p);  		virtual ~Task();  		virtual void execute() const = 0;  }; diff --git a/project2/common/taskHost.cpp b/project2/common/taskHost.cpp index 98a1fa5..9ee0304 100644 --- a/project2/common/taskHost.cpp +++ b/project2/common/taskHost.cpp @@ -3,15 +3,17 @@  #include "noOutputExecute.h"  #include "dataSource.h"  #include "scopeObject.h" +#include "xmlObjectLoader.h" +#include "commonObjects.h"  #include <boost/foreach.hpp> -TaskHost::TaskHost(const boost::filesystem::path & file) : -	XmlScriptParser(file, false), -	SourceObject(get_document()->get_root_node()), -	CheckHost(file), -	IHaveSubTasks(get_document()->get_root_node()) +TaskHost::TaskHost(ScriptReaderPtr s) : +	SourceObject(s->root()), +	CommonObjects(s), +	CheckHost(s), +	IHaveSubTasks(s->root())  { -	loader.supportedStorers.insert(Storer::into<ElementLoader>(&tasks)); +	s->loader.addLoadTarget(s->root(), Storer::into<ElementLoader>(&tasks));  }  TaskHost::~TaskHost() @@ -27,7 +29,7 @@ TaskHost::loadComplete(const CommonObjects * co)  void  TaskHost::execute() const  { -	parseDocument(); +	loadScriptComponents();  	ScopeObject txHandler(boost::bind(&TaskHost::commitAll, this), boost::bind(&TaskHost::rollbackAll, this));  	run(tasks);  } @@ -35,7 +37,7 @@ TaskHost::execute() const  void  TaskHost::commitAll() const  { -	BOOST_FOREACH(const DataSources::value_type & ds, datasources) { +	BOOST_FOREACH(const CommonObjects::DataSources::value_type & ds, CommonObjects::datasources) {  		ds.second->commit();  	}  } @@ -43,7 +45,7 @@ TaskHost::commitAll() const  void  TaskHost::rollbackAll() const  { -	BOOST_FOREACH(const DataSources::value_type & ds, datasources) { +	BOOST_FOREACH(const CommonObjects::DataSources::value_type & ds, CommonObjects::datasources) {  		ds.second->rollback();  	}  } diff --git a/project2/common/taskHost.h b/project2/common/taskHost.h index ca8275c..9f9a1c5 100644 --- a/project2/common/taskHost.h +++ b/project2/common/taskHost.h @@ -2,16 +2,16 @@  #define TASKHOST_H  #include "xmlStorage.h" -#include "xmlScriptParser.h"  #include "checkHost.h"  #include "iHaveSubTasks.h" +#include "commonObjects.h"  class NoOutputExecute;  class DataSource; -class TaskHost : virtual public XmlScriptParser, public IHaveSubTasks, virtual public CheckHost { +class TaskHost : public IHaveSubTasks, virtual public CheckHost, virtual public CommonObjects {  	protected: -		TaskHost(const boost::filesystem::path & file); +		TaskHost(ScriptReaderPtr script);  		virtual ~TaskHost();  		void loadComplete(const CommonObjects *); diff --git a/project2/common/transform.cpp b/project2/common/transform.cpp index d109c19..0dafcd5 100644 --- a/project2/common/transform.cpp +++ b/project2/common/transform.cpp @@ -9,7 +9,7 @@ TransformChainLink::~TransformChainLink()  typedef std::map<std::string, boost::shared_ptr<TransformLoader> > TransformLoaderMap;  void -TransformSource::addTarget(TransformChainLinkPtr tcl, const xmlpp::Element * e) +TransformSource::addTarget(TransformChainLinkPtr tcl, ScriptNodePtr e)  {  	BOOST_FOREACH(const TransformLoaderMap::value_type & tl, *LoaderBase::objLoaders<TransformLoader>()) {  		TransformPtr t = tl.second->create(); diff --git a/project2/common/transform.h b/project2/common/transform.h index ded356b..06db2c7 100644 --- a/project2/common/transform.h +++ b/project2/common/transform.h @@ -17,7 +17,7 @@ typedef boost::intrusive_ptr<Transform> TransformPtr;  class TransformSource : public TransformChainLink {  	public: -		void addTarget(TransformChainLinkPtr, const xmlpp::Element * e = NULL); +		void addTarget(TransformChainLinkPtr, ScriptNodePtr e = NULL);  		void doTransforms() const;  	private:  		virtual const TransformChainLink * object() const { return this; } @@ -35,7 +35,7 @@ class Transform : public virtual IntrusivePtrBase {  	public:  		virtual void transform(const TransformSource * src, TransformChainLink * dest) const = 0;  		virtual bool canTransform(const TransformSource * src, TransformChainLink * dest) const = 0; -		virtual void configure(const xmlpp::Element *) { }; +		virtual void configure(ScriptNodePtr) { };  };  class TransformLoader : public ComponentLoader { diff --git a/project2/common/validDateCheck.cpp b/project2/common/validDateCheck.cpp index 6f731bb..987fa87 100644 --- a/project2/common/validDateCheck.cpp +++ b/project2/common/validDateCheck.cpp @@ -4,14 +4,15 @@  #include "commonObjects.h"  #include "paramChecker.h"  #include "variables.h" +#include "scripts.h"  class ValidDateCheck : public ParamChecker {  	public: -		ValidDateCheck(const xmlpp::Element * p) : +		ValidDateCheck(ScriptNodePtr p) :  			ParamChecker(p),  			applyTo(p, "apply-to"),  			format(p, "format"), -			warnLev(p->get_attribute_value("warn") == "no" ? LOG_INFO : LOG_WARNING) +			warnLev(p->value("warn", true).as<bool>() ? LOG_WARNING : LOG_INFO)  		{  		} diff --git a/project2/common/variableConvert.cpp b/project2/common/variableConvert.cpp index 7eb16cf..a7ddca4 100644 --- a/project2/common/variableConvert.cpp +++ b/project2/common/variableConvert.cpp @@ -28,7 +28,7 @@ set(const VariableType * var, const T * t)  	return ::set(var, t, deleter<T>);  } -SimpleMessageException(InvalidConversionTo); +SimpleMessage2Exception(InvalidConversionTo);  class NullVariable : std::runtime_error {  	public: @@ -131,7 +131,7 @@ class ConvertVisitor : public boost::static_visitor<DestType> {  			return boost::lexical_cast<DestType>(r);  		}  		DestType operator()(const boost::posix_time::ptime &) const { -			throw InvalidConversionTo(typeid(DestType).name()); +			throw InvalidConversionTo(typeid(DestType).name(), "<Date Time>");  		}  		DestType operator()(const Null &) const {  			throw NullVariable(); @@ -162,7 +162,7 @@ class ConvertVisitorDateTime : public boost::static_visitor<const boost::posix_t  		}  		template <typename T>  		const boost::posix_time::ptime & operator()(const T &) const { -			throw InvalidConversionTo("DateTime"); +			throw InvalidConversionTo("DateTime", typeid(T).name());  		}  	private:  		const VariableType * var; @@ -176,10 +176,10 @@ class ConvertVisitorBool : public boost::static_visitor<bool> {  			const char * str = s.c_str();  			if (strcasecmp(str, "true") == 0 || strcasecmp(str, "yes") == 0 || strcasecmp(str, "on") == 0) return true;  			if (strcasecmp(str, "false") == 0 || strcasecmp(str, "no") == 0 || strcasecmp(str, "off") == 0) return false; -			throw InvalidConversionTo("bool"); +			throw InvalidConversionTo("bool", s);  		}  		bool operator()(const boost::posix_time::ptime &) const { -			throw InvalidConversionTo("bool"); +			throw InvalidConversionTo("bool", "<Date time>");  		}  		bool operator()(const Null &) const {  			throw NullVariable(); diff --git a/project2/common/variables-modconfig.cpp b/project2/common/variables-modconfig.cpp index c44daf2..5a031be 100644 --- a/project2/common/variables-modconfig.cpp +++ b/project2/common/variables-modconfig.cpp @@ -13,9 +13,9 @@ SimpleMessageException(NoSuchConfigurationValue);  /// Variable implementation to access platform configuration values  class VariableConfig : public VariableImplDyn {  	public: -		VariableConfig(const xmlpp::Element * e) : +		VariableConfig(ScriptNodePtr e) :  			VariableImplDyn(e), -			name(e->get_attribute_value("name")) +			name(e->value("name").as<Glib::ustring>())  		{  		}  		VariableType value() const diff --git a/project2/common/variables-modfixed.cpp b/project2/common/variables-modfixed.cpp new file mode 100644 index 0000000..45fa74e --- /dev/null +++ b/project2/common/variables-modfixed.cpp @@ -0,0 +1,13 @@ +#include "variables-modfixed.h" + +VariableFixed::VariableFixed(VariableType v) : +	var(v) +{ +} + +VariableType +VariableFixed::value() const +{ +	return var; +} + diff --git a/project2/common/variables-modfixed.h b/project2/common/variables-modfixed.h new file mode 100644 index 0000000..eceb548 --- /dev/null +++ b/project2/common/variables-modfixed.h @@ -0,0 +1,17 @@ +#ifndef VARIABLES_MODFIXED_H +#define VARIABLES_MODFIXED_H + +#include "variables.h" + +/// Variable implementation which has some fixed value +class VariableFixed : public VariableImpl { +	public: +		VariableFixed(VariableType v); +		VariableType value() const; + +	private: +		VariableType var; +}; + +#endif + diff --git a/project2/common/variables-modliteral.cpp b/project2/common/variables-modliteral.cpp new file mode 100644 index 0000000..8c165ee --- /dev/null +++ b/project2/common/variables-modliteral.cpp @@ -0,0 +1,78 @@ +#include "variables-modliteral.h" +#include "scripts.h" +#include <stdio.h> +#include <boost/foreach.hpp> +#include <boost/bind.hpp> + +/// Variable implementation whose value is a literal value of some known type +VariableLiteral::VariableLiteral(const Glib::ustring & src, const VT_typeID format) : +	val(VariableType::make(src, format)) +{ +} + +template <typename X, typename Y> +static +void +append(VariableLiteral::Vals * vals, const Y & y)  +{ +	vals->push_back(new X(y)); +} + +VariableLiteral::VariableLiteral(ScriptNodePtr s) { +	try { +		val = VariableType::make(s->value("value"), VariableType::getTypeFromName(s->value("type", ""))); +	} +	catch (const ValueNotFound &) { +		s->composeWithCallbacks( +				boost::bind(&append<TextPart, Glib::ustring>, &vals, _1), +				boost::bind(&append<VarPart, ScriptNodePtr>, &vals, _1)); +	} +} + +VariableType +VariableLiteral::value() const +{ +	if (vals.empty()) { +		return val; +	} +	if (vals.size() == 1) { +		return *vals.front(); +	} +	Glib::ustring v; +	BOOST_FOREACH(PartCPtr p, vals) { +		p->appendTo(v); +	} +	return v; +} + +VariableLiteral::TextPart::TextPart(const Glib::ustring & e) : +	txt(e) +{ +} +void +VariableLiteral::TextPart::appendTo(Glib::ustring & str) const +{ +	str += txt; +} +VariableLiteral::TextPart::operator VariableType() const +{ +	return txt; +} + +VariableLiteral::VarPart::VarPart(ScriptNodePtr e) : Variable(e) +{ +} +void +VariableLiteral::VarPart::appendTo(Glib::ustring & str) const +{ +	str += (*this)().operator const Glib::ustring &(); +} +VariableLiteral::VarPart::operator VariableType() const +{ +	return (*this)(); +} + +DECLARE_COMPONENT_LOADER("literal", VariableLiteral, VariableLoader); +DECLARE_CUSTOM_COMPONENT_LOADER("", VariableLiteralDef, VariableLoaderImpl<VariableLiteral>, VariableLoader); + + diff --git a/project2/common/variables-modliteral.h b/project2/common/variables-modliteral.h new file mode 100644 index 0000000..77a43cc --- /dev/null +++ b/project2/common/variables-modliteral.h @@ -0,0 +1,40 @@ +#ifndef VARIABLES_MODLITERAL_H +#define VARIABLES_MODLITERAL_H + +#include "variables.h" +#include <list> + +class VariableLiteral : public VariableImpl { +	public: +		VariableLiteral(const Glib::ustring & src, const VT_typeID format = DefaultType); +		VariableLiteral(ScriptNodePtr); +		virtual VariableType value() 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; +		}; +		class TextPart : public Part { +			public: +				TextPart(const Glib::ustring & e); +				void appendTo(Glib::ustring & str) const; +				operator VariableType() const; +				const Glib::ustring txt; +		}; +		class VarPart : public Part, public Variable { +			public: +				VarPart(ScriptNodePtr e); +				void appendTo(Glib::ustring & str) const; +				operator VariableType() const; +		}; +	private: +		VariableType val; +		Vals vals; +}; + +#endif + diff --git a/project2/common/variables-modlocalparam.cpp b/project2/common/variables-modlocalparam.cpp index 957f76a..f6fd31c 100644 --- a/project2/common/variables-modlocalparam.cpp +++ b/project2/common/variables-modlocalparam.cpp @@ -8,9 +8,9 @@  /// Variable implementation to access call parameters  class VariableLocalParam : public VariableImplDyn {  	public: -		VariableLocalParam(const xmlpp::Element * e) : +		VariableLocalParam(ScriptNodePtr e) :  			VariableImplDyn(e), -			name(e->get_attribute_value("name")) +			name(e->value("name").as<Glib::ustring>())  		{  		}  		VariableType value() const diff --git a/project2/common/variables-modlookup.cpp b/project2/common/variables-modlookup.cpp index 82c3539..c5a2a2e 100644 --- a/project2/common/variables-modlookup.cpp +++ b/project2/common/variables-modlookup.cpp @@ -30,14 +30,12 @@ class VariableLookup : public VariableImplDyn, public RowProcessor {  					return l;  				}  		}; -		VariableLookup(const xmlpp::Element * e) : +		VariableLookup(ScriptNodePtr e) :  			VariableImplDyn(e),  			RowProcessor(e), -			name(e->get_attribute_value("name")) +			name(e->value("name").as<Glib::ustring>())  		{ -			LoaderBase loader(true); -			loader.supportedStorers.insert(Storer::into<ElementLoader>(&rowSets)); -			loader.collectAll(e, false); +			e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&rowSets));  		}  		VariableType value() const  		{ diff --git a/project2/common/variables-modparam.cpp b/project2/common/variables-modparam.cpp index 4908a89..f17cae5 100644 --- a/project2/common/variables-modparam.cpp +++ b/project2/common/variables-modparam.cpp @@ -7,9 +7,9 @@  /// Variable implementation to access call parameters  class VariableParam : public VariableImplDyn {  	public: -		VariableParam(const xmlpp::Element * e) : +		VariableParam(ScriptNodePtr e) :  			VariableImplDyn(e), -			name(e->get_attribute_value("name")) +			name(e->value("name").as<Glib::ustring>())  		{  		}  		VariableType value() const diff --git a/project2/common/variables-modsession.cpp b/project2/common/variables-modsession.cpp index 27f1db2..68d0e56 100644 --- a/project2/common/variables-modsession.cpp +++ b/project2/common/variables-modsession.cpp @@ -7,9 +7,9 @@  /// Variable implementation to access session contents  class VariableSession : public VariableImplDyn {  	public: -		VariableSession(const xmlpp::Element * e) : +		VariableSession(ScriptNodePtr e) :  			VariableImplDyn(e), -			name(e->get_attribute_value("name")) +			name(e->value("name").as<Glib::ustring>())  		{  		}  		VariableType value() const diff --git a/project2/common/variables-moduri.cpp b/project2/common/variables-moduri.cpp index f91423a..8096203 100644 --- a/project2/common/variables-moduri.cpp +++ b/project2/common/variables-moduri.cpp @@ -7,9 +7,9 @@  /// Variable implementation to access URI path fragments  class VariableUri : public VariableImplDyn {  	public: -		VariableUri(const xmlpp::Element * e) : +		VariableUri(ScriptNodePtr e) :  			VariableImplDyn(e), -			index(atoi(e->get_attribute_value("index").c_str())) +			index(e->value("index").as<int32_t>())  		{  		}  		VariableType value() const diff --git a/project2/common/variables.cpp b/project2/common/variables.cpp index a3669aa..8df00e2 100644 --- a/project2/common/variables.cpp +++ b/project2/common/variables.cpp @@ -1,12 +1,12 @@  #include <pch.hpp>  #include "variables.h" +#include "variables-modfixed.h"  #include "iHaveParameters.h"  #include "xmlObjectLoader.h"  #include "exceptions.h"  #include "appEngine.h"  #include "session.h"  #include "rowSet.h" -#include <libxml++/nodes/textnode.h>  #include <stdexcept>  #include <boost/numeric/conversion/cast.hpp>  #include <boost/foreach.hpp> @@ -16,8 +16,6 @@  #include <boost/date_time/posix_time/posix_time.hpp>  SimpleMessageException(UnknownVariableType); -SimpleMessageException(UnknownVariableSource); -SimpleMessageException(NoVariableDefinition);  bool  Null::operator<(const Null &) const @@ -54,41 +52,20 @@ operator<<(std::basic_ostream<unsigned char> & os, const Boolean & b)  	return os;  } -enum VT_typeID { -	DefaultType, -	String, -	Int, -	UInt, -	LInt, -	LUInt, -	LLInt, -	LLUInt, -	Float, -	Double, -	DateTime, -}; - -static  VT_typeID -getVariableTypeFromName(const std::string & src) +VariableType::getTypeFromName(const std::string & src)  {  	if (src.empty()) return String;  	if (src == "string") return String;  	if (src == "int") return Int; -	if (src == "uint") return UInt; -	if (src == "lint") return LInt; -	if (src == "luint") return LUInt; -	if (src == "llint") return LLInt; -	if (src == "lluint") return LLUInt;  	if (src == "float") return Float; -	if (src == "double") return Double;  	if (src == "datetime") return DateTime; +	if (src == "null") return Nul;  	throw UnknownVariableType(src);  } -static  VariableType -makeVariableType(const Glib::ustring & src, const VT_typeID format = DefaultType) +VariableType::make(const Glib::ustring & src, const VT_typeID format)  {  	switch (format) {  		default: @@ -96,23 +73,13 @@ makeVariableType(const Glib::ustring & src, const VT_typeID format = DefaultType  		case String:  			return src;  		case Int: -			return boost::lexical_cast<int>(src); -		case UInt: -			return boost::lexical_cast<unsigned int>(src); -		case LInt: -			return boost::lexical_cast<long int>(src); -		case LUInt: -			return boost::lexical_cast<long unsigned int>(src); -		case LLInt: -			return boost::lexical_cast<long long int>(src); -		case LLUInt: -			return boost::lexical_cast<long long unsigned int>(src); +			return boost::lexical_cast<int64_t>(src);  		case Float: -			return boost::lexical_cast<float>(src); -		case Double:  			return boost::lexical_cast<double>(src);  		case DateTime:  			return boost::posix_time::time_from_string(src); +		case Nul: +			return Null();  	}  } @@ -241,88 +208,7 @@ VariableType::operator<(const VariableType & b) const  	return false;  } -/// Variable implementation whose value is a literal value of some known type -class VariableLiteral : public VariableImpl { -	public: -		VariableLiteral(const Glib::ustring & src, const VT_typeID format = DefaultType) : -			val(makeVariableType(src, format)) -		{ -		} -		VariableLiteral(const xmlpp::Element * c) -		{ -			if (const xmlpp::Attribute * la = c->get_attribute("value")) { -				val = makeVariableType(la->get_value(), getVariableTypeFromName(c->get_attribute_value("type"))); -			} -			else { -				BOOST_FOREACH(const xmlpp::Node * n, c->get_children()) { -					if (const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n)) { -						vals.push_back(new VarPart(e)); -					} -					else if (const xmlpp::TextNode * t = dynamic_cast<const xmlpp::TextNode *>(n)) { -						vals.push_back(new TextPart(t)); -					} -				} -			} -		} - -		virtual VariableType value() const -		{ -			if (vals.empty()) { -				return val; -			} -			if (vals.size() == 1) { -				return *vals.front(); -			} -			Glib::ustring v; -			BOOST_FOREACH(PartCPtr p, vals) { -				p->appendTo(v); -			} -			return v; -		} -	private: -		VariableType val; -		class Part : public IntrusivePtrBase { -			public: -				virtual void appendTo(Glib::ustring & str) const = 0; -				virtual operator VariableType() const = 0; -		}; -		class TextPart : public Part { -			public: -				TextPart(const xmlpp::TextNode * e) : -					txt(e->get_content()) -				{ -				} -				void appendTo(Glib::ustring & str) const -				{ -					str += txt; -				} -				operator VariableType() const -				{ -					return txt; -				} -				const Glib::ustring txt; -		}; -		class VarPart : public Part, public Variable { -			public: -				VarPart(const xmlpp::Element * e) : Variable(e, boost::optional<Glib::ustring>()) -				{ -				} -				void appendTo(Glib::ustring & str) const -				{ -					str += (*this)().operator const Glib::ustring &(); -				} -				operator VariableType() const -				{ -					return (*this)(); -				} -		}; -		typedef boost::intrusive_ptr<Part> PartCPtr; -		std::list<PartCPtr> vals; -}; -DECLARE_COMPONENT_LOADER("literal", VariableLiteral, VariableLoader); -DECLARE_CUSTOM_COMPONENT_LOADER("", VariableLiteralDef, VariableLoaderImpl<VariableLiteral>, VariableLoader); - -VariableImplDyn::VariableImplDyn(const xmlpp::Element * e) +VariableImplDyn::VariableImplDyn(ScriptNodePtr e)  {  	if (e) {  		defaultValue = Variable(e, "default", false); @@ -332,11 +218,11 @@ VariableImplDyn::VariableImplDyn(const xmlpp::Element * e)  /// Variable implementation to access fields in row sets  class VariableParent : public VariableImplDyn {  	public: -		VariableParent(const xmlpp::Element * e) : +		VariableParent(ScriptNodePtr e) :  			VariableImplDyn(e), -			depth(e->get_attribute("depth") ? atoi(e->get_attribute_value("depth").c_str()) : 1), -			attr(e->get_attribute("attribute")), -			name(attr ? e->get_attribute_value("attribute") : e->get_attribute_value("name")) +			depth(e->value("depth", 1).as<int32_t>()), +			attr(e->valueExists("attribute")), +			name((attr ? e->value("attribute") : e->value("name")).as<Glib::ustring>())  		{  		}  		VariableParent(const Glib::ustring & n, bool a, unsigned int d) : @@ -387,66 +273,23 @@ class VariableParent : public VariableImplDyn {  };  DECLARE_COMPONENT_LOADER("parent", VariableParent, VariableLoader); -/// Variable implementation which has some fixed value -class VariableFixed : public VariableImpl { -	public: -		VariableFixed(VariableType v) : -			var(v) -		{ -		} -		VariableType value() const -		{ -			return var; -		} -	private: -		VariableType var; -};  Variable::Variable(VariableType def) :  	var(new VariableFixed(def))  {  } -Variable::Variable(const xmlpp::Element * e, const Glib::ustring & n, bool required, VariableType def) +Variable::Variable(ScriptNodePtr s, const boost::optional<Glib::ustring> & defaultSource) : +	var(s->variable(defaultSource))  { -	xmlpp::Attribute * a = e->get_attribute(n); -	if (a) { -		var = new VariableLiteral(a->get_value()); -		return; -	} -	xmlpp::Element::NodeList cs = e->get_children(n); -	if (cs.size() == 1) { -		const xmlpp::Element * c = dynamic_cast<const xmlpp::Element *>(cs.front()); -		if (c) { -			xmlpp::Attribute * source = c->get_attribute("source"); -			if (source) { -				var = LoaderBase::getLoader<VariableLoader, UnknownVariableSource>(source->get_value())->create(c); -			} -			else { -				var = new VariableLiteral(c); -			} -			return; -		} -	} -	if (!required) { -		var = new VariableFixed(def); -		return; -	} -	throw NoVariableDefinition(n);  } - -Variable::Variable(const xmlpp::Element * c, const boost::optional<Glib::ustring> & defaultSource) +Variable::Variable(ScriptNodePtr s, const Glib::ustring & n) : +	var(s->variable(n)) +{ +} +Variable::Variable(ScriptNodePtr s, const Glib::ustring & n, const VariableType & d) : +	var(s->variable(n, d))  { -	xmlpp::Attribute * source = c->get_attribute("source"); -	if (source) { -		var = LoaderBase::getLoader<VariableLoader, UnknownVariableSource>(source->get_value())->create(c); -	} -	else if (defaultSource) { -		var = LoaderBase::getLoader<VariableLoader, UnknownVariableSource>(defaultSource.get())->create(c); -	} -	else { -		var = new VariableLiteral(c); -	}  }  Variable::Variable(VariableImpl * v) : diff --git a/project2/common/variables.h b/project2/common/variables.h index e42de0c..05b7855 100644 --- a/project2/common/variables.h +++ b/project2/common/variables.h @@ -6,13 +6,22 @@  #include <boost/date_time/posix_time/posix_time_types.hpp>  #include <stdint.h>  #include <glibmm/ustring.h> -#include <libxml++/nodes/element.h> -#include <libxml++/attribute.h>  #include "intrusivePtrBase.h"  #include "xmlObjectLoader.h"  #include <boost/variant.hpp>  #include <boost/shared_ptr.hpp> +SimpleMessageException(UnknownVariableSource); + +enum VT_typeID { +	DefaultType, +	Nul, +	String, +	Int, +	Float, +	DateTime, +}; +  class Null {  	public:  		bool operator<(const Null &) const; @@ -64,6 +73,9 @@ class VariableType : public _VT {  		VariableType();  		VariableType(const VariableType &);  		~VariableType(); +		static VariableType make(const Glib::ustring & src, const VT_typeID format = DefaultType); +		static VT_typeID getTypeFromName(const std::string & src); +  		void operator=(const VariableType &);  		bool operator<(const VariableType &) const; @@ -98,8 +110,9 @@ class Variable {  	public:  		typedef boost::intrusive_ptr<VariableImpl> VariableImplPtr; -		Variable(const xmlpp::Element *, const Glib::ustring & n, bool required = true, VariableType def = VariableType()); -		Variable(const xmlpp::Element *, const boost::optional<Glib::ustring> &); +		Variable(ScriptNodePtr, const boost::optional<Glib::ustring> & = boost::optional<Glib::ustring>()); +		Variable(ScriptNodePtr, const Glib::ustring & n); +		Variable(ScriptNodePtr, const Glib::ustring & n, const VariableType & def);  		Variable(VariableType def);  		static Variable makeParent(const Glib::ustring & name, bool attr, unsigned int depth); @@ -116,7 +129,7 @@ class Variable {  /// Base class for variables whose content is dynamic  class VariableImplDyn : public VariableImpl {  	public: -		VariableImplDyn(const xmlpp::Element * e); +		VariableImplDyn(ScriptNodePtr e);  		virtual VariableType value() const = 0;  	protected: @@ -126,13 +139,13 @@ class VariableImplDyn : public VariableImpl {  /// Base class to create variables  class VariableLoader : public ComponentLoader {  	public: -		virtual VariableImpl * create(const xmlpp::Element *) const = 0; +		virtual VariableImpl * create(ScriptNodePtr) const = 0;  };  /// Helper implementation of VariableLoader for specific variable types  template <class VarType>  class VariableLoaderImpl : public VariableLoader {  	public: -		virtual VariableImpl * create(const xmlpp::Element * e) const +		virtual VariableImpl * create(ScriptNodePtr e) const  		{  			return new VarType(e);  		} diff --git a/project2/common/view.cpp b/project2/common/view.cpp index 34ff3d4..30a6491 100644 --- a/project2/common/view.cpp +++ b/project2/common/view.cpp @@ -1,7 +1,7 @@  #include <pch.hpp>  #include "view.h" -View::View(const xmlpp::Element * p) : +View::View(ScriptNodePtr p) :  	SourceObject(p)  {  } diff --git a/project2/common/view.h b/project2/common/view.h index 5a4b751..23c292f 100644 --- a/project2/common/view.h +++ b/project2/common/view.h @@ -9,7 +9,7 @@ class MultiRowSetPresenter;  /// Base class for Project2 components that output data  class View : public virtual SourceObject {  	public: -		View(const xmlpp::Element *); +		View(ScriptNodePtr);  		virtual ~View();  		virtual void execute(const MultiRowSetPresenter *) const = 0; diff --git a/project2/common/viewHost.cpp b/project2/common/viewHost.cpp index 9d3c14b..4c19370 100644 --- a/project2/common/viewHost.cpp +++ b/project2/common/viewHost.cpp @@ -1,17 +1,17 @@  #include <pch.hpp>  #include "viewHost.h" +#include "commonObjects.h"  #include "transform.h"  #include <boost/foreach.hpp>  #include <iostream> -#define FOREACH_PRESENTER BOOST_FOREACH (const PresenterPtr & p, presenters) - -ViewHost::ViewHost(const boost::filesystem::path & file) : -	XmlScriptParser(file, false), -	CheckHost(file) +ViewHost::ViewHost(ScriptReaderPtr s) : +	CommonObjects(s), +	CheckHost(s), +	root(s->root())  { -	loader.supportedStorers.insert(Storer::into<ElementLoader>(&views)); -	loader.supportedStorers.insert(Storer::into<PresenterLoader>(&presenter)); +	s->loader.addLoadTarget(root, Storer::into<ElementLoader>(&views)); +	s->loader.addLoadTarget(root, Storer::into<PresenterLoader>(&presenter));  }  ViewHost::~ViewHost() @@ -21,16 +21,17 @@ ViewHost::~ViewHost()  void  ViewHost::executeViews(const DefaultPresenterProvider & dpp) const  { -	parseDocument(); +	loadScriptComponents();  	if (!presenter) { -		presenter = dpp(get_document()->get_root_node()); +		presenter = dpp(root); +		root.reset();  	}  	BOOST_FOREACH(const Views::value_type & s, views) {  		s->execute(presenter.get());  	}  	// Caches might open transactions -	BOOST_FOREACH(const DataSources::value_type & ds, datasources) { +	BOOST_FOREACH(const CommonObjects::DataSources::value_type & ds, CommonObjects::datasources) {  		ds.second->commit();  	}  } diff --git a/project2/common/viewHost.h b/project2/common/viewHost.h index 409f195..589e2b1 100644 --- a/project2/common/viewHost.h +++ b/project2/common/viewHost.h @@ -1,19 +1,19 @@  #ifndef VIEWHOST_H  #define VIEWHOST_H -#include "xmlScriptParser.h"  #include "paramChecker.h"  #include "xmlStorage.h"  #include "presenter.h"  #include "checkHost.h"  #include <set>  #include <boost/filesystem/path.hpp> +#include "commonObjects.h" -class ViewHost : virtual public XmlScriptParser, virtual public CheckHost { +class ViewHost : virtual public CheckHost, virtual public CommonObjects {  	public: -		typedef boost::function1<MultiRowSetPresenterPtr, const xmlpp::Element *> DefaultPresenterProvider; +		typedef boost::function1<MultiRowSetPresenterPtr, ScriptNodePtr> DefaultPresenterProvider; -		ViewHost(const boost::filesystem::path & file);  +		ViewHost(ScriptReaderPtr script);   		~ViewHost();  		void executeViews(const DefaultPresenterProvider &) const; @@ -23,6 +23,7 @@ class ViewHost : virtual public XmlScriptParser, virtual public CheckHost {  	private:  		typedef ANONORDEREDSTORAGEOF(View) Views;  		Views views; +		mutable ScriptNodePtr root;  };  typedef boost::intrusive_ptr<ViewHost> ViewHostPtr; diff --git a/project2/common/xmlObjectLoader.cpp b/project2/common/xmlObjectLoader.cpp index d430194..f25ba6b 100644 --- a/project2/common/xmlObjectLoader.cpp +++ b/project2/common/xmlObjectLoader.cpp @@ -6,7 +6,8 @@  #include "appEngine.h"  #include <boost/shared_ptr.hpp>  #include <boost/foreach.hpp> -#include <libxml++/nodes/textnode.h> +#include <boost/function.hpp> +#include <boost/function_equal.hpp>  unsigned int LoaderBase::depth = 0;  std::set<SourceObjectPtr> LoaderBase::loadedObjects; @@ -26,25 +27,21 @@ class DepthCounter {  typedef std::map<std::string, boost::shared_ptr<ElementLoader> > ElementLoaderMap;  typedef std::set<boost::shared_ptr<ComponentLoader> > ComponentLoaderSet; -LoaderBase::LoaderBase(bool r) : -	recursive(r), -	ns(Environment::getCurrent()->xmlNamespace) +LoaderBase::LoaderBase() : +	recursive(true)  { -	supportedStorers.insert(Storer::into<ElementLoader>(&libraries));  } -LoaderBase::LoaderBase(const Glib::ustring & n, bool r) : -	recursive(r), -	ns(n) +LoaderBase::~LoaderBase()  { -	supportedStorers.insert(Storer::into<ElementLoader>(&libraries));  } -LoaderBase::~LoaderBase() -{ +void +LoaderBase::addLoadTarget(ScriptNodePtr src, boost::intrusive_ptr<Storer> target) { +	targets[src].push_back(target);  } -std::set<boost::shared_ptr<ComponentLoader> > * & +	std::set<boost::shared_ptr<ComponentLoader> > * &  LoaderBase::componentLoaders()  {  	static std::set<boost::shared_ptr<ComponentLoader> > * _compLoaders = NULL; @@ -55,54 +52,62 @@ LoaderBase::componentLoaders()  }  void -LoaderBase::collectAll(const xmlpp::Element * node, bool childrenOnly, UnsupportedHandling uh) const +LoaderBase::collectAll(ScriptNodePtr node, bool childrenOnly, const StorerPtrs & sts) const  { -	if (!node) { -		return; -	}  	DepthCounter dc(depth);  	unsigned int created = 0; -	if (!childrenOnly && node->get_namespace_uri() == ns) { +	if (!childrenOnly && node->componentNamespace()) {  		Glib::ustring name = node->get_name();  		unsigned int stored = 0;  		created += 1; -		BOOST_FOREACH(std::set<boost::intrusive_ptr<Storer> >::value_type s, supportedStorers) { -			boost::intrusive_ptr<IntrusivePtrBase> o = s->save(node); -			if (boost::intrusive_ptr<SourceObject> t = boost::dynamic_pointer_cast<SourceObject>(o)) { -				loadedObjects.insert(t); +		boost::intrusive_ptr<IntrusivePtrBase> o; +		BOOST_FOREACH(const StorerPtr & s, sts) { +			try { +				o = s->create(node); +				break;  			} -			if (o) { +			catch (const NotSupported &) { +			} +		} +		if (!o) { +			throw NotSupported(name); +		} +		BOOST_FOREACH(const StorerPtr & s, sts) { +			if (s->save(o, node)) {  				stored += 1; +				break;  			}  		}  		if (stored < 1) { -			if (uh == ErrorOnUnsupported) { -				throw NotSupported(name); -			} -			else if (uh == WarnOnUnsupported) { -				Logger()->messagef(LOG_WARNING, "'%s' unsupported in this location", name.c_str()); -			} +			throw NotSupported(name);  		}  	}  	if (created == 0 && (recursive || childrenOnly)) { -		BOOST_FOREACH(const xmlpp::Node * child, node->get_children()) { -			collectAll(dynamic_cast<const xmlpp::Element *>(child), false, uh); +		BOOST_FOREACH(ScriptNodePtr child, node->children()) { +			collectAll(child, false, sts);  		}  	}  }  void -LoaderBase::collectAll(const CommonObjects * co, const xmlpp::Element * node, bool childrenOnly, UnsupportedHandling uh) const +LoaderBase::collectAll(const CommonObjects * co, bool childrenOnly, ScriptNodePtr node)  { -	if (depth != 0) { +	(void)co; +	addLoadTarget(node, Storer::into<ElementLoader>(&libraries)); +	if (depth != 0 && co) {  		throw std::logic_error("Cannot set CommonObjects in subloader");  	} -	loadedObjects.clear(); -	collectAll(node, childrenOnly, uh); -	BOOST_FOREACH(SourceObjectPtr o, loadedObjects) { -		o->loadComplete(co); +	Targets::iterator i; +	while ((i = targets.begin()) != targets.end()) { +		collectAll(i->first, childrenOnly, i->second); +		targets.erase(i); +	} +	if (co) { +		BOOST_FOREACH(SourceObjectPtr o, loadedObjects) { +			o->loadComplete(co); +		} +		loadedObjects.clear();  	} -	loadedObjects.clear();  }  void @@ -117,22 +122,6 @@ LoaderBase::onAllComponents(const boost::function1<void, ComponentLoader *> & fu  	}  } -Glib::ustring -xmlChildText(const xmlpp::Node * p, const Glib::ustring & t) -{ -	Glib::ustring rtn; -	BOOST_FOREACH(const xmlpp::Node * child, p->get_children(t)) { -		const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(child); -		if (e) { -			const xmlpp::ContentNode * cn = e->get_child_text(); -			if (cn) { -				rtn += cn->get_content(); -			} -		} -	} -	return rtn; -} -  void  ComponentLoader::onBegin()  { diff --git a/project2/common/xmlObjectLoader.h b/project2/common/xmlObjectLoader.h index 3c6fa34..3dd12a4 100644 --- a/project2/common/xmlObjectLoader.h +++ b/project2/common/xmlObjectLoader.h @@ -9,84 +9,86 @@  #include "intrusivePtrBase.h"  #include "sourceObject.h"  #include "exceptions.h" - -namespace xmlpp { -	class Element; -} -Glib::ustring xmlChildText(const xmlpp::Node * p, const Glib::ustring & n); +#include <glibmm/ustring.h> +#include <map> +#include <vector>  enum UnsupportedHandling { ErrorOnUnsupported, WarnOnUnsupported, IgnoreUnsupported };  class ElementLoader;  class ComponentLoader;  class CommonObjects;  class Storer; +class ScriptReader;  class LoaderBase {  	public: -		LoaderBase(bool recursive); -		LoaderBase(const Glib::ustring & ns, bool recursive); +		typedef boost::intrusive_ptr<Storer> StorerPtr; +		typedef std::vector<StorerPtr> StorerPtrs; +		typedef std::map<ScriptNodePtr, StorerPtrs> Targets; + +		LoaderBase();  		virtual ~LoaderBase(); -		void collectAll(const CommonObjects * co, const xmlpp::Element * node, bool childrenOnly, -				UnsupportedHandling uh = ErrorOnUnsupported) const; -		void collectAll(const xmlpp::Element * node, bool childrenOnly, -				UnsupportedHandling uh = ErrorOnUnsupported) const; +		void collectAll(const CommonObjects * co, bool childrenOnly, ScriptNodePtr script); -		std::set<boost::intrusive_ptr<Storer> > supportedStorers; +		void addLoadTarget(ScriptNodePtr src, boost::intrusive_ptr<Storer> target);  		static void onAllComponents(const boost::function1<void, ComponentLoader *> &);  		static std::set<boost::shared_ptr<ComponentLoader> > * & componentLoaders();  		template <class T> -		static std::map<std::string, boost::shared_ptr<T> > * & objLoaders()  -		{ -			static std::map<std::string, boost::shared_ptr<T> > * _objLoaders = NULL; -			if (!_objLoaders) { -				_objLoaders = new std::map<std::string, boost::shared_ptr<T> >(); +			static std::map<std::string, boost::shared_ptr<T> > * & objLoaders()  +			{ +				static std::map<std::string, boost::shared_ptr<T> > * _objLoaders = NULL; +				if (!_objLoaders) { +					_objLoaders = new std::map<std::string, boost::shared_ptr<T> >(); +				} +				return _objLoaders;  			} -			return _objLoaders; -		}  		template <class T> -		static void newLoader(const std::string & n, T * l) -		{ -			boost::shared_ptr<T> p = boost::shared_ptr<T>(l); -			objLoaders<T>()->insert(std::pair<std::string, boost::shared_ptr<T> >(n, p)); -			componentLoaders()->insert(boost::shared_ptr<T>(p)); -		} +			static void newLoader(const std::string & n, T * l) +			{ +				boost::shared_ptr<T> p = boost::shared_ptr<T>(l); +				objLoaders<T>()->insert(std::pair<std::string, boost::shared_ptr<T> >(n, p)); +				componentLoaders()->insert(boost::shared_ptr<T>(p)); +			}  		template <class T> -		static void removeLoader(const std::string & n) -		{ -			std::map<std::string, boost::shared_ptr<T> > * & o = objLoaders<T>(); -			std::set<boost::shared_ptr<ComponentLoader> > * & c = componentLoaders(); -			typename std::map<std::string, boost::shared_ptr<T> >::iterator i = o->find(n); -			c->erase(i->second); -			o->erase(i); -			if (o->empty()) { -				delete o; -				o = NULL; -			} -			if (c->empty()) { -				delete c; -				c = NULL; +			static void removeLoader(const std::string & n) +			{ +				std::map<std::string, boost::shared_ptr<T> > * & o = objLoaders<T>(); +				std::set<boost::shared_ptr<ComponentLoader> > * & c = componentLoaders(); +				typename std::map<std::string, boost::shared_ptr<T> >::iterator i = o->find(n); +				c->erase(i->second); +				o->erase(i); +				if (o->empty()) { +					delete o; +					o = NULL; +				} +				if (c->empty()) { +					delete c; +					c = NULL; +				}  			} -		}  		template <class L, class E> -		static boost::shared_ptr<L> getLoader(const std::string & n)  -		{ -			typename std::map<std::string, boost::shared_ptr<L> >::const_iterator i = objLoaders<L>()->find(n); -			if (i != objLoaders<L>()->end()) { -				return i->second; -			} -			else { -				throw E(n); +			static boost::shared_ptr<L> getLoader(const std::string & n)  +			{ +				typename std::map<std::string, boost::shared_ptr<L> >::const_iterator i = objLoaders<L>()->find(n); +				if (i != objLoaders<L>()->end()) { +					return i->second; +				} +				else { +					throw E(n); +				}  			} -		}  	private: +		void collectAll(ScriptNodePtr script, bool childrenOnly, const StorerPtrs & sts) const; +		Targets targets;  		static unsigned int depth; +		template <class X> friend class ElementLoaderImpl;  		static std::set<SourceObjectPtr> loadedObjects;  		const bool recursive; @@ -121,16 +123,18 @@ class ComponentLoader {  /// Helper for loading and maintaining Project2 script components  class ElementLoader : public ComponentLoader {  	public: -		virtual SourceObjectPtr createFrom(const xmlpp::Element * xml) const = 0; +		virtual SourceObjectPtr createFrom(ScriptNodePtr) const = 0;  };  /// Helper for loading and maintaining Project2 script components (typed implementation)  template <class X>  class ElementLoaderImpl : public ElementLoader {  	public: -		SourceObjectPtr createFrom(const xmlpp::Element * xml) const +		SourceObjectPtr createFrom(ScriptNodePtr sn) const  		{ -			return new X(xml); +			SourceObjectPtr sop = new X(sn); +			LoaderBase::loadedObjects.insert(sop); +			return sop;  		}  };  #endif diff --git a/project2/common/xmlScriptParser.cpp b/project2/common/xmlScriptParser.cpp deleted file mode 100644 index 1db1841..0000000 --- a/project2/common/xmlScriptParser.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include <pch.hpp> -#include "xmlScriptParser.h" -#include <libxml/xinclude.h> -#include <boost/filesystem/convenience.hpp> - -XmlScriptParser::XmlScriptParser(const boost::filesystem::path & file, bool ii) : -	IsInclusion(ii), -	loader(true), -	documentParsed(false) -{ -	loadDocument(file); -} - -void -XmlScriptParser::loadDocument(const boost::filesystem::path & file) -{ -	if (!boost::filesystem::exists(file)) { -		if (IsInclusion) { -			throw DependencyNotFound(file.string()); -		} -		else { -			throw NotFound(file.string()); -		} -	} -	try { -		parse_file(file.string()); -	} -	catch (const xmlpp::internal_error &) { -		throw NotReadable(file.string()); -	} -	for (int x; (x = xmlXIncludeProcessFlags(get_document()->cobj(), XML_PARSE_NOXINCNODE)); ) { -		if (x < 0) { -			throw IncludesError(file.string()); -		} -	} -	loader.supportedStorers.insert(Storer::into<ElementLoader>(&rowSets)); -} - -void -XmlScriptParser::parseDocument() const -{ -	if (!documentParsed) { -		loader.collectAll(this, get_document()->get_root_node(), true, ErrorOnUnsupported); -		documentParsed = true; -	} -} - diff --git a/project2/common/xmlScriptParser.h b/project2/common/xmlScriptParser.h deleted file mode 100644 index 9f1406d..0000000 --- a/project2/common/xmlScriptParser.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef XMLSCRIPTPARSER_H -#define XMLSCRIPTPARSER_H - -#include <libxml++/parsers/domparser.h> -#include <boost/function.hpp> -#include "exceptions.h" -#include "xmlObjectLoader.h" -#include <intrusivePtrBase.h> -#include "commonObjects.h" -#include <boost/filesystem/path.hpp> - -class XmlScriptParser : public xmlpp::DomParser, virtual public CommonObjects, virtual public IntrusivePtrBase { -	public: -		SimpleMessageException(ParseError); -		SimpleMessageExceptionBase(NotFound, ParseError); -		SimpleMessageExceptionBase(DependencyNotFound, ParseError); -		SimpleMessageExceptionBase(NotReadable, ParseError); -		SimpleMessageExceptionBase(IncludesError, ParseError); - -		XmlScriptParser(const boost::filesystem::path & file, bool isInclusion); - -		const bool IsInclusion; - -	protected: -		LoaderBase loader; -		mutable bool documentParsed; -		void parseDocument() const; - -	private: -		void loadDocument(const boost::filesystem::path & file); -}; - - -#endif - diff --git a/project2/common/xmlStorage.h b/project2/common/xmlStorage.h index ceae899..267343f 100644 --- a/project2/common/xmlStorage.h +++ b/project2/common/xmlStorage.h @@ -4,6 +4,7 @@  #include "sourceObject.h"  #include "xmlObjectLoader.h"  #include "exceptions.h" +#include "scripts.h"  #include <set>  #include <list>  #include <map> @@ -33,36 +34,34 @@ class Storer : public virtual IntrusivePtrBase {  		template <class L, class X>  		static StorerPtr into(ANONORDEREDSTORAGEOF(X) * list); -		virtual boost::intrusive_ptr<IntrusivePtrBase> save(const xmlpp::Element *) = 0; +		virtual boost::intrusive_ptr<IntrusivePtrBase> create(ScriptNodePtr) const = 0; +		virtual bool save(boost::intrusive_ptr<IntrusivePtrBase>, ScriptNodePtr) = 0;  };  template <class X, class M, class L>  class StorerBase : public Storer {  	public:  		typedef M * Map; -		boost::intrusive_ptr<IntrusivePtrBase> save(const xmlpp::Element * p) { -			try { -				boost::intrusive_ptr<X> O = boost::dynamic_pointer_cast<X>( -						LoaderBase::getLoader<L, NotSupported>(p->get_name())->createFrom(p)); -				if (O) { -					if (!insert(p, O)) { -						throw StoreFailed(p->get_attribute_value("name")); -					} +		boost::intrusive_ptr<IntrusivePtrBase> create(ScriptNodePtr p) const { +			return LoaderBase::getLoader<L, NotSupported>(p->get_name())->createFrom(p); +		} +		bool save(boost::intrusive_ptr<IntrusivePtrBase> o, ScriptNodePtr p) { +			boost::intrusive_ptr<X> O = boost::dynamic_pointer_cast<X>(o); +			if (O) { +				if (!insert(p, O)) { +					throw StoreFailed(p->get_name());  				} -				return O; -			} -			catch (NotSupported) { -				return NULL;  			} +			return O;  		} -		virtual bool insert(const xmlpp::Element *, boost::intrusive_ptr<X>) = 0; +		virtual bool insert(ScriptNodePtr, boost::intrusive_ptr<X>) = 0;  };  template <class X, class M, class L>  class StorerImpl : public StorerBase<X, M, L> {  	public:  		StorerImpl(M * m); -		bool insert(const xmlpp::Element *, boost::intrusive_ptr<X> O); +		bool insert(ScriptNodePtr, boost::intrusive_ptr<X> O);  };  template <class X, class L>  class StorerImpl<X, SINGLE(X), L> : public StorerBase<X, SINGLE(X), L> { @@ -71,7 +70,7 @@ class StorerImpl<X, SINGLE(X), L> : public StorerBase<X, SINGLE(X), L> {  		StorerImpl(SINGLE(X) * o) : obj(o)  		{  		} -		bool insert(const xmlpp::Element *, boost::intrusive_ptr<X> O) +		bool insert(ScriptNodePtr, boost::intrusive_ptr<X> O)  		{  			*obj = O;  			return true; @@ -85,7 +84,7 @@ class StorerImpl<X, STORAGEOF(X), L> : public StorerBase<X, STORAGEOF(X), L> {  		StorerImpl(STORAGEOF(X) * m) : map(m)  		{  		} -		bool insert(const xmlpp::Element *, boost::intrusive_ptr<X> O) +		bool insert(ScriptNodePtr, boost::intrusive_ptr<X> O)  		{  			return map->insert(typename Map::value_type(O->name, O)).second;  		} @@ -98,7 +97,7 @@ class StorerImpl<X, ANONSTORAGEOF(X), L> : public StorerBase<X, ANONSTORAGEOF(X)  		StorerImpl(ANONSTORAGEOF(X) * m) : map(m)  		{  		} -		bool insert(const xmlpp::Element *, boost::intrusive_ptr<X> O) +		bool insert(ScriptNodePtr, boost::intrusive_ptr<X> O)  		{  			map->insert(O);  			return true; @@ -112,7 +111,7 @@ class StorerImpl<X, ANONORDEREDSTORAGEOF(X), L> : public StorerBase<X, ANONORDER  		StorerImpl(ANONORDEREDSTORAGEOF(X) * m) : map(m)  		{  		} -		bool insert(const xmlpp::Element *, boost::intrusive_ptr<X> O) +		bool insert(ScriptNodePtr, boost::intrusive_ptr<X> O)  		{  			map->push_back(O);  			return true; diff --git a/project2/console/Jamfile.jam b/project2/console/Jamfile.jam index 3a95bd6..b3b60a1 100644 --- a/project2/console/Jamfile.jam +++ b/project2/console/Jamfile.jam @@ -1,10 +1,10 @@ -alias libxmlpp : : : : -	<cflags>"`pkg-config --cflags libxml++-2.6`" -	<linkflags>"`pkg-config --libs libxml++-2.6`" ; - +alias glibmm : : : : +	<cflags>"`pkg-config --cflags glibmm-2.4`" +	<linkflags>"`pkg-config --libs glibmm-2.4`" +	;  cpp-pch pch : pch.hpp :  	<include>../../libmisc -	<library>libxmlpp +	<library>glibmm  	<library>..//p2parts  	;  exe p2console : diff --git a/project2/console/claOptions.cpp b/project2/console/claOptions.cpp index 135eebc..d3f7745 100644 --- a/project2/console/claOptions.cpp +++ b/project2/console/claOptions.cpp @@ -1,8 +1,11 @@  #include <pch.hpp>  #include <boost/foreach.hpp>  #include "../common/optionsSource.h" +#include "../common/exceptions.h"  #include "consoleEnvironment.h" +StaticMessageException(InvalidScriptName, "Script name should be group/name"); +  class CommandLineArguments : public OptionsSource {  	public:  		typedef std::list<Glib::ustring> optionList; @@ -51,7 +54,16 @@ class CommandLineArguments : public OptionsSource {  			}  			BOOST_FOREACH (const optionList::value_type & i, values) { -				ConsoleEnvironment::todolist.push_back(i.raw()); +				Glib::ustring group, name; +				Glib::ustring::size_type sl = i.find('/'); +				if (sl != (Glib::ustring::size_type)-1) { +					group = i.substr(0, sl); +					name = i.substr(sl + 1); +				} +				else { +					throw InvalidScriptName(); +				} +				ConsoleEnvironment::todolist.push_back(ConsoleEnvironment::ToDo(group, name));  			}  		}  }; diff --git a/project2/console/consoleAppEngine.cpp b/project2/console/consoleAppEngine.cpp index 40d369e..7229c36 100644 --- a/project2/console/consoleAppEngine.cpp +++ b/project2/console/consoleAppEngine.cpp @@ -12,12 +12,12 @@  SimpleMessageException(UnknownPlatformAlias); -ConsoleApplicationEngine::ConsoleApplicationEngine(const ConsoleEnvironment * env, const boost::filesystem::path & f) : -	XmlScriptParser(f, false), -	SourceObject(get_document()->get_root_node()), -	CheckHost(f), -	TaskHost(f), -	ViewHost(f), +ConsoleApplicationEngine::ConsoleApplicationEngine(const ConsoleEnvironment * env, ScriptReaderPtr script) : +	SourceObject(script->root()), +	CommonObjects(script), +	CheckHost(script), +	TaskHost(script), +	ViewHost(script),  	_env(env),  	runtime(new Session(UUID::generate_random()))  { diff --git a/project2/console/consoleAppEngine.h b/project2/console/consoleAppEngine.h index f2a0519..d53574f 100644 --- a/project2/console/consoleAppEngine.h +++ b/project2/console/consoleAppEngine.h @@ -16,7 +16,7 @@ class ConsoleEnvironment;  class ConsoleApplicationEngine : public ApplicationEngine, TaskHost, ViewHost {  	public: -		ConsoleApplicationEngine(const ConsoleEnvironment *, const boost::filesystem::path &); +		ConsoleApplicationEngine(const ConsoleEnvironment *, ScriptReaderPtr);  		virtual ~ConsoleApplicationEngine();  		void process() const; diff --git a/project2/console/consoleEnvironment.h b/project2/console/consoleEnvironment.h index 5f4545c..a5530a9 100644 --- a/project2/console/consoleEnvironment.h +++ b/project2/console/consoleEnvironment.h @@ -3,12 +3,13 @@  #include <string>  #include <vector> -#include <boost/filesystem/path.hpp> +#include <boost/tuple/tuple.hpp>  #include "environment.h"  class ConsoleEnvironment : public Environment {  	public: -		typedef std::vector<boost::filesystem::path> ToDoList; +		typedef boost::tuple<Glib::ustring, Glib::ustring> ToDo; +		typedef std::vector<ToDo> ToDoList;  		typedef std::vector<std::string> UriParams;  		typedef std::vector<std::pair<std::string, std::string> > QueryParams; diff --git a/project2/console/consolePresenter.cpp b/project2/console/consolePresenter.cpp index 47c846a..33a7af9 100644 --- a/project2/console/consolePresenter.cpp +++ b/project2/console/consolePresenter.cpp @@ -1,9 +1,10 @@  #include <pch.hpp> +#include <stdio.h>  #include "consolePresenter.h"  DECLARE_COMPONENT_LOADER("console", ConsolePresenter, PresenterLoader) -ConsolePresenter::ConsolePresenter(const xmlpp::Element *) : +ConsolePresenter::ConsolePresenter(ScriptNodePtr) :  	indent(0),  	out(stdout, true)  { diff --git a/project2/console/consolePresenter.h b/project2/console/consolePresenter.h index a411765..6122f7f 100644 --- a/project2/console/consolePresenter.h +++ b/project2/console/consolePresenter.h @@ -6,7 +6,7 @@  class ConsolePresenter : public Presenter {  	public: -		ConsolePresenter(const xmlpp::Element *); +		ConsolePresenter(ScriptNodePtr);  		void pushSub(const Glib::ustring & ns, const Glib::ustring & name) const;  		void addAttribute(const Glib::ustring & name, const Glib::ustring & ns, const VariableType & value) const;  		void addNamedValue(const Glib::ustring & name, const Glib::ustring & ns, const VariableType & value) const; diff --git a/project2/console/p2consoleMain.cpp b/project2/console/p2consoleMain.cpp index c194510..c560bfd 100644 --- a/project2/console/p2consoleMain.cpp +++ b/project2/console/p2consoleMain.cpp @@ -13,10 +13,10 @@ main(int argc, char ** argv)  	ConsoleEnvironment env(argc, argv);  	LoaderBase::onAllComponents(boost::bind(&ComponentLoader::onBegin, _1));  	env.init(); -	BOOST_FOREACH(const boost::filesystem::path & file, env.todoList()) { +	BOOST_FOREACH(const ConsoleEnvironment::ToDo & todo, env.todoList()) {  		LoaderBase::onAllComponents(boost::bind(&ComponentLoader::onBefore, _1)); -		Logger()->messagef(LOG_DEBUG, "%s: Beginning file '%s'", __FUNCTION__, file.string().c_str()); -		ConsoleApplicationEngine app(&env, file); +		Logger()->messagef(LOG_DEBUG, "%s: Beginning script '%s/%s'", __FUNCTION__, todo.get<0>().c_str(), todo.get<1>().c_str()); +		ConsoleApplicationEngine app(&env, env.resolveScript(todo.get<0>(), todo.get<1>(), false));  		Logger()->messagef(LOG_DEBUG, "%s: Processing file", __FUNCTION__);  		app.process(); diff --git a/project2/files/Jamfile.jam b/project2/files/Jamfile.jam index 1b34e3c..dd818b3 100644 --- a/project2/files/Jamfile.jam +++ b/project2/files/Jamfile.jam @@ -1,6 +1,7 @@ -alias libxmlpp : : : : -	<cflags>"`pkg-config --cflags libxml++-2.6`" -	<linkflags>"`pkg-config --libs libxml++-2.6`" ; +alias glibmm : : : : +	<cflags>"`pkg-config --cflags glibmm-2.4`" +	<linkflags>"`pkg-config --libs glibmm-2.4`" +	;  lib boost_system : : <name>boost_system ;  lib boost_filesystem : : <name>boost_filesystem ; @@ -8,7 +9,7 @@ lib p2files :  	[ glob *.cpp ]  	:  	<include>../libmisc -	<library>libxmlpp +	<library>glibmm  	<library>boost_filesystem  	<library>boost_system  	<library>../common//p2common diff --git a/project2/files/fileRows.cpp b/project2/files/fileRows.cpp index 8ba5c0c..af11f55 100644 --- a/project2/files/fileRows.cpp +++ b/project2/files/fileRows.cpp @@ -7,7 +7,7 @@  DECLARE_LOADER("filerows", FileRows); -FileRows::FileRows(const xmlpp::Element * p) : +FileRows::FileRows(ScriptNodePtr p) :  	StreamRows(p),  	path(p, "path")  { diff --git a/project2/files/fileRows.h b/project2/files/fileRows.h index 7d92d20..fccbd08 100644 --- a/project2/files/fileRows.h +++ b/project2/files/fileRows.h @@ -9,7 +9,7 @@ class CommonObjects;  /// Project2 component to create a row set from the contents of a file on the local filesystem  class FileRows : public StreamRows {  	public: -		FileRows(const xmlpp::Element * p); +		FileRows(ScriptNodePtr p);  		~FileRows();  		void execute(const Glib::ustring &, const RowProcessor *) const; diff --git a/project2/files/fsRows.cpp b/project2/files/fsRows.cpp index a76cc02..41ec4b6 100644 --- a/project2/files/fsRows.cpp +++ b/project2/files/fsRows.cpp @@ -127,7 +127,7 @@ class FsRowSpecMaxDepth : public FsRows::SpecBase {  		const unsigned int maxDepth;  }; -FsRows::FsRows(const xmlpp::Element * p) : +FsRows::FsRows(ScriptNodePtr p) :  	RowSet(p)  {  } diff --git a/project2/files/fsRows.h b/project2/files/fsRows.h index 6ef6b31..a6b9c8c 100644 --- a/project2/files/fsRows.h +++ b/project2/files/fsRows.h @@ -1,7 +1,6 @@  #ifndef FSROWS_H  #define FSROWS_H -#include <libxml++/nodes/element.h>  #include <boost/intrusive_ptr.hpp>  #include <boost/filesystem/path.hpp>  #include <sys/stat.h> @@ -28,7 +27,7 @@ class FsRows : public RowSet {  		typedef std::list<Glib::ustring> SpecSpec;  		typedef boost::filesystem::path Path; -		FsRows(const xmlpp::Element * p); +		FsRows(ScriptNodePtr p);  		~FsRows();  		void execute(const Glib::ustring &, const RowProcessor *) const; diff --git a/project2/files/streamRows.cpp b/project2/files/streamRows.cpp index 0be76cd..fc2572d 100644 --- a/project2/files/streamRows.cpp +++ b/project2/files/streamRows.cpp @@ -1,17 +1,17 @@  #include "streamRows.h"  #include "rowProcessor.h" -StreamRows::StreamRows(const xmlpp::Element * p) : -	DefinedColumns(p, "columns/column", boost::bind(&Column::make, _1, _2)), +StreamRows::StreamRows(ScriptNodePtr p) : +	DefinedColumns(p, "columns", boost::bind(&Column::make, _1, _2)),  	RowSet(p), -	fieldSep(p->get_attribute_value("fieldSep")[0]), -	quoteChar(p->get_attribute_value("quoteChar")[0]), -	keepBlankRows(p->get_attribute_value("keepBlankRows") == "true"), -	countBlankRows(p->get_attribute_value("keepBlankRows") == "count"), -	newline(p->get_attribute_value("newline")), +	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>()),  	newlin(newline, 0, newline.length() - 1), -	encoding(p->get_attribute_value("encoding")), -	skipheader(atoi(p->get_attribute_value("skipheader").c_str())) +	encoding(p->value("encoding", "utf-8").as<std::string>()), +	skipheader(p->value("skipheader", 0).as<int64_t>())  {  } diff --git a/project2/files/streamRows.h b/project2/files/streamRows.h index 2d10116..95d8131 100644 --- a/project2/files/streamRows.h +++ b/project2/files/streamRows.h @@ -9,7 +9,7 @@ class RowProcessor;  /// Base class for Project2 components that create a row set based on the contents of a byte stream  class StreamRows : public DefinedColumns, public RowSet {  	public: -		StreamRows(const xmlpp::Element * p); +		StreamRows(ScriptNodePtr p);  		~StreamRows();  	protected: diff --git a/project2/json/Jamfile.jam b/project2/json/Jamfile.jam index 92a6e28..323e4fe 100644 --- a/project2/json/Jamfile.jam +++ b/project2/json/Jamfile.jam @@ -1,19 +1,20 @@ -alias libxmlpp : : : : -	<cflags>"`pkg-config --cflags libxml++-2.6`" -	<linkflags>"`pkg-config --libs libxml++-2.6`" ; +alias glibmm : : : : +	<cflags>"`pkg-config --cflags glibmm-2.4`" +	<linkflags>"`pkg-config --libs glibmm-2.4`" +	;  lib boost_filesystem : : <name>boost_filesystem ;  lib boost_date_time : : <name>boost_date_time ;  cpp-pch pch : pch.hpp :  	<include>../../libmisc -	<library>libxmlpp +	<library>glibmm  	<library>../common//p2common  	;  lib p2json :  	pch [ glob *.cpp ]  	:  	<include>../libmisc -	<library>libxmlpp +	<library>glibmm  	<library>../common//p2common  	<library>../uuid//p2uuid  	<library>../url//p2url diff --git a/project2/json/presenter.cpp b/project2/json/presenter.cpp index 4afd1a0..3b069a4 100644 --- a/project2/json/presenter.cpp +++ b/project2/json/presenter.cpp @@ -7,7 +7,7 @@  class JsonPresenter : public MultiRowSetPresenter, public ContentPresenter, public SourceOf<json::Object> {  	public: -		JsonPresenter(const xmlpp::Element *) : +		JsonPresenter(ScriptNodePtr) :  			ContentPresenter("application/json; charset=UTF-8") {  			curRowSet.push(&object);  		} diff --git a/project2/mail/Jamfile.jam b/project2/mail/Jamfile.jam index 8c8f189..91e507d 100644 --- a/project2/mail/Jamfile.jam +++ b/project2/mail/Jamfile.jam @@ -1,13 +1,14 @@ -alias libxmlpp : : : : -	<cflags>"`pkg-config --cflags libxml++-2.6`" -	<linkflags>"`pkg-config --libs libxml++-2.6`" ; +alias glibmm : : : : +	<cflags>"`pkg-config --cflags glibmm-2.4`" +	<linkflags>"`pkg-config --libs glibmm-2.4`" +	;  lib esmtp : : <name>esmtp ;  lib p2mail :  	sendmailTask.cpp  	:  	<include>../../libmisc -	<library>libxmlpp +	<library>glibmm  	<library>esmtp  	<library>../common//p2common  	<library>../xml//p2xml diff --git a/project2/mail/sendmailTask.cpp b/project2/mail/sendmailTask.cpp index e2ca703..e8b354f 100644 --- a/project2/mail/sendmailTask.cpp +++ b/project2/mail/sendmailTask.cpp @@ -43,13 +43,13 @@ class SendEmailFailed : public std::runtime_error {  typedef boost::shared_ptr<xmlDoc> XmlDocumentPtr; -SendMailTask::SendMailTask(const xmlpp::Element * p) : +SendMailTask::SendMailTask(ScriptNodePtr p) :  	SourceObject(p),  	Task(p),  	to(p, "to"),  	subject(p, "subject"),  	from(p, "from"), -	server(p, "server", defaultMailServer.empty(), defaultMailServer), +	server(p, "server", defaultMailServer),  	present(p, "present")  {  } @@ -189,7 +189,7 @@ class TransformTextToEmail : public TransformImpl<TextDocument, SendMailTask::Pa  DECLARE_TRANSFORM(TransformTextToEmail);  PresenterPtr -SendMailTask::createDefaultPresenter(const xmlpp::Element * n) const +SendMailTask::createDefaultPresenter(ScriptNodePtr n) const  {  	Logger()->message(LOG_DEBUG, "Building default email transform chain");  	XmlPresenterPtr xpp = new XmlPresenter(n); @@ -215,7 +215,7 @@ SendMailTask::execute() const  	parts->parts.insert(new Header("Content-Transfer-Encoding", "binary"));  	parts->parts.insert(new BoundaryEnd()); -	ViewHostPtr vsp = new ViewHost(Environment::getCurrent()->resolveScript("emails", present())); +	ViewHostPtr vsp = new ViewHost(Environment::getCurrent()->resolveScript("emails", present(), false));  	vsp->executeViews(boost::bind(&SendMailTask::createDefaultPresenter, this, _1));  	vsp->doTransforms();  	part = parts->parts.begin(); diff --git a/project2/mail/sendmailTask.h b/project2/mail/sendmailTask.h index 5b10d44..6e2a10b 100644 --- a/project2/mail/sendmailTask.h +++ b/project2/mail/sendmailTask.h @@ -31,7 +31,7 @@ class SendMailTask : public Task {  				PartList parts;  		}; -		SendMailTask(const xmlpp::Element * p); +		SendMailTask(ScriptNodePtr p);  		virtual ~SendMailTask();  		virtual void execute() const; @@ -45,7 +45,7 @@ class SendMailTask : public Task {  	private:  		static const char * writeMailWrapper(void ** buf, int * len, void * arg);  		const char * writeMail(void ** buf, int * len) const; -		PresenterPtr createDefaultPresenter(const xmlpp::Element * n) const; +		PresenterPtr createDefaultPresenter(ScriptNodePtr n) const;  		mutable boost::intrusive_ptr<Parts> parts;  		mutable PartList::iterator part; diff --git a/project2/processes/Jamfile.jam b/project2/processes/Jamfile.jam index 4c0c2b4..aef9251 100644 --- a/project2/processes/Jamfile.jam +++ b/project2/processes/Jamfile.jam @@ -1,12 +1,12 @@ -alias libxmlpp : : : : -	<cflags>"`pkg-config --cflags libxml++-2.6`" -	<linkflags>"`pkg-config --libs libxml++-2.6`" ; - +alias glibmm : : : : +	<cflags>"`pkg-config --cflags glibmm-2.4`" +	<linkflags>"`pkg-config --libs glibmm-2.4`" +	;  lib p2processes :  	procRows.cpp  	:  	<include>../../libmisc -	<library>libxmlpp +	<library>glibmm  	<library>../common//p2common  	<library>../files//p2files  	; diff --git a/project2/processes/procRows.cpp b/project2/processes/procRows.cpp index c868323..a8b6829 100644 --- a/project2/processes/procRows.cpp +++ b/project2/processes/procRows.cpp @@ -1,5 +1,6 @@  #include "procRows.h"  #include "xmlObjectLoader.h" +#include "scripts.h"  #include <exception>  DECLARE_LOADER("procrows", ProcRows); @@ -7,7 +8,7 @@ DECLARE_LOADER("procrows", ProcRows);  SimpleMessageException(SubProcessFailedToStart);  SimpleNumericException(SubProcessFailed); -ProcRows::ProcRows(const xmlpp::Element * p) : +ProcRows::ProcRows(ScriptNodePtr p) :  	FileRows(p)  {  } diff --git a/project2/processes/procRows.h b/project2/processes/procRows.h index 09b6f04..f39749d 100644 --- a/project2/processes/procRows.h +++ b/project2/processes/procRows.h @@ -6,7 +6,7 @@  /// Project2 component to create a row set from the output of a locally executed program  class ProcRows : public FileRows {  	public: -		ProcRows(const xmlpp::Element * p); +		ProcRows(ScriptNodePtr p);  		~ProcRows();  		virtual FileStarChannel doOpen() const; diff --git a/project2/regex/Jamfile.jam b/project2/regex/Jamfile.jam index a83697f..7bb9d16 100644 --- a/project2/regex/Jamfile.jam +++ b/project2/regex/Jamfile.jam @@ -1,12 +1,12 @@ -alias libxmlpp : : : : -	<cflags>"`pkg-config --cflags libxml++-2.6`" -	<linkflags>"`pkg-config --libs libxml++-2.6`" ; - +alias glibmm : : : : +	<cflags>"`pkg-config --cflags glibmm-2.4`" +	<linkflags>"`pkg-config --libs glibmm-2.4`" +	;  lib p2regex :  	regexCheck.cpp regexRows.cpp  	:  	<include>../../libmisc -	<library>libxmlpp +	<library>glibmm  	<library>../common//p2common  	; diff --git a/project2/regex/regexCheck.cpp b/project2/regex/regexCheck.cpp index 1a1add3..e58e8f1 100644 --- a/project2/regex/regexCheck.cpp +++ b/project2/regex/regexCheck.cpp @@ -5,7 +5,7 @@  DECLARE_LOADER("regexcheck", RegexCheck); -RegexCheck::RegexCheck(const xmlpp::Element * p) : +RegexCheck::RegexCheck(ScriptNodePtr p) :  	ParamChecker(p),  	applyTo(p, "apply-to"),  	regex(p, "regex") diff --git a/project2/regex/regexCheck.h b/project2/regex/regexCheck.h index c4f6e02..2ddc545 100644 --- a/project2/regex/regexCheck.h +++ b/project2/regex/regexCheck.h @@ -7,7 +7,7 @@  /// Project2 component to test the value of a variable against a regular expression  class RegexCheck : public ParamChecker {  	public: -		RegexCheck(const xmlpp::Element * p); +		RegexCheck(ScriptNodePtr p);  		virtual ~RegexCheck();  		bool performCheck() const; diff --git a/project2/regex/regexRows.cpp b/project2/regex/regexRows.cpp index a822cf1..1238eb5 100644 --- a/project2/regex/regexRows.cpp +++ b/project2/regex/regexRows.cpp @@ -6,8 +6,8 @@  DECLARE_LOADER("regexrows", RegexRows); -RegexRows::RegexRows(const xmlpp::Element * p) : -	DefinedColumns(p, "columns/column", boost::bind(&Column::make, _1, _2)), +RegexRows::RegexRows(ScriptNodePtr p) : +	DefinedColumns(p, "columns", boost::bind(&Column::make, _1, _2)),  	RowSet(p),  	sourceText(p, "sourceText"),  	regex(p, "regex") diff --git a/project2/regex/regexRows.h b/project2/regex/regexRows.h index 21d9dfa..4d94f52 100644 --- a/project2/regex/regexRows.h +++ b/project2/regex/regexRows.h @@ -7,7 +7,7 @@  /// Base class for Project2 components that create a row set based on the contents of a byte stream  class RegexRows : public DefinedColumns, public RowSet {  	public: -		RegexRows(const xmlpp::Element * p); +		RegexRows(ScriptNodePtr p);  		~RegexRows();  		void execute(const Glib::ustring&, const RowProcessor*) const; diff --git a/project2/sql/Jamfile.jam b/project2/sql/Jamfile.jam index 779aba3..068394f 100644 --- a/project2/sql/Jamfile.jam +++ b/project2/sql/Jamfile.jam @@ -1,12 +1,12 @@ -alias libxmlpp : : : : -	<cflags>"`pkg-config --cflags libxml++-2.6`" -	<linkflags>"`pkg-config --libs libxml++-2.6`" ; - +alias glibmm : : : : +	<cflags>"`pkg-config --cflags glibmm-2.4`" +	<linkflags>"`pkg-config --libs glibmm-2.4`" +	;  explicit object sql-modODBC ;  obj sql-modODBC :  	sql-modODBC.cpp :  	<library>../../libodbcpp//odbcpp -	<library>libxmlpp +	<library>glibmm  	<include>../../libmisc  	<include>../common  	: : @@ -17,7 +17,7 @@ explicit object sql-modPQ ;  obj sql-modPQ :  	sql-modPQ.cpp :  	<library>../../libpqpp//pqpp -	<library>libxmlpp +	<library>glibmm  	<include>../../libmisc  	<include>../common  	: : @@ -27,7 +27,7 @@ obj sql-modPQ :  cpp-pch pch : pch.hpp :  	<include>../../libmisc  	<include>../../libdbpp -	<library>libxmlpp +	<library>glibmm  	<library>../common//p2common  	;  lib p2sql : @@ -38,7 +38,7 @@ lib p2sql :  	:  	<odbc>yes:<library>sql-modODBC  	<pq>yes:<library>sql-modPQ -	<library>libxmlpp +	<library>glibmm  	<library>../common//p2common  	<include>../../libmisc  	; diff --git a/project2/sql/pch.hpp b/project2/sql/pch.hpp index a212245..01c68d4 100644 --- a/project2/sql/pch.hpp +++ b/project2/sql/pch.hpp @@ -21,13 +21,13 @@  #include "sqlWriter.h"  #include "variables.h"  #include "xmlObjectLoader.h" +#include "scripts.h"  #include <boost/bind.hpp>  #include <boost/foreach.hpp>  #include "options.h"  #include <buffer.h>  #include <column.h>  #include <errno.h> -#include <libxml++/nodes/textnode.h>  #include <stdexcept>  #endif diff --git a/project2/sql/rdbmsDataSource.cpp b/project2/sql/rdbmsDataSource.cpp index 20ccaec..4c6ae17 100644 --- a/project2/sql/rdbmsDataSource.cpp +++ b/project2/sql/rdbmsDataSource.cpp @@ -1,7 +1,6 @@  #include <pch.hpp>  #include "rdbmsDataSource.h"  #include "connectionLoader.h" -#include <libxml++/nodes/textnode.h>  #include <sys/utsname.h>  #include "logger.h"  #include <errno.h> @@ -40,16 +39,13 @@ RdbmsDataSource::DBHosts RdbmsDataSource::dbhosts;  RdbmsDataSource::FailedHosts RdbmsDataSource::failedhosts;  RdbmsDataSource::DSNSet RdbmsDataSource::changedDSNs; -RdbmsDataSource::RdbmsDataSource(const xmlpp::Element * p) : +RdbmsDataSource::RdbmsDataSource(ScriptNodePtr p) :  	DataSource(p), -	masterDsn(dynamic_cast<const xmlpp::Element *>(p->find("masterdsn").front())), -	preferLocal(p->get_attribute_value("preferlocal") != "false") +	masterDsn(p->child("masterdsn")), +	preferLocal(p->value("preferlocal", true))  { -	BOOST_FOREACH(const xmlpp::Node * node, p->find("readonly/dsn")) { -		const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node); -		if (elem) { -			roDSNs.insert(ReadonlyDSNs::value_type(elem->get_attribute_value("host"), elem)); -		} +	BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("readonly")) { +		roDSNs.insert(ReadonlyDSNs::value_type(node->value("host"), node));  	}  } @@ -194,12 +190,10 @@ RdbmsDataSource::RdbmsConnection::isExpired() const  	return (time(NULL) > lastUsedTime + keepAliveTime);  } -RdbmsDataSource::ConnectionInfo::ConnectionInfo(const xmlpp::Element * n) +RdbmsDataSource::ConnectionInfo::ConnectionInfo(ScriptNodePtr node)  { -	BOOST_FOREACH(const xmlpp::Node * node, n->get_children()) { -		typeId = LoaderBase::getLoader<ConnectionLoader, UnknownConnectionProvider>(node->get_name()); -		dsn = dynamic_cast<const xmlpp::Element *>(node)->get_child_text()->get_content(); -	} +	typeId = LoaderBase::getLoader<ConnectionLoader, UnknownConnectionProvider>(node->value("provider")); +	dsn = node->value("dsn").as<std::string>();  }  DB::Connection * diff --git a/project2/sql/rdbmsDataSource.h b/project2/sql/rdbmsDataSource.h index 60206ff..bc72b05 100644 --- a/project2/sql/rdbmsDataSource.h +++ b/project2/sql/rdbmsDataSource.h @@ -1,7 +1,6 @@  #ifndef RDBMSDATASOURCE_H  #define RDBMSDATASOURCE_H -#include <libxml/tree.h>  #include <boost/shared_ptr.hpp>  #include <map>  #include <set> @@ -32,7 +31,7 @@ class RdbmsDataSource : public DataSource {  		class ConnectionInfo {  			public: -				ConnectionInfo(const xmlpp::Element *); +				ConnectionInfo(ScriptNodePtr);  				DB::Connection * connect() const; @@ -48,7 +47,7 @@ class RdbmsDataSource : public DataSource {  		typedef std::map<ConnectionInfo, ConnectionPtr> DBHosts; // Map DSN strings to connections  		typedef std::map<ConnectionInfo, const DB::ConnectionError> FailedHosts; // Map DSN strings to failures -		RdbmsDataSource(const xmlpp::Element * p); +		RdbmsDataSource(ScriptNodePtr p);  		~RdbmsDataSource();  		const DB::Connection & getReadonly() const; diff --git a/project2/sql/sqlCache.cpp b/project2/sql/sqlCache.cpp index d1ae930..7ed4ae1 100644 --- a/project2/sql/sqlCache.cpp +++ b/project2/sql/sqlCache.cpp @@ -21,7 +21,7 @@ typedef boost::shared_ptr<DB::ModifyCommand> ModifyPtr;  class SqlCache : public Cache {  	public: -		SqlCache(const xmlpp::Element * p) : +		SqlCache(ScriptNodePtr p) :  			Cache(p)  		{  		} diff --git a/project2/sql/sqlCheck.cpp b/project2/sql/sqlCheck.cpp index d6e0651..879cbca 100644 --- a/project2/sql/sqlCheck.cpp +++ b/project2/sql/sqlCheck.cpp @@ -13,13 +13,13 @@ DECLARE_LOADER("sqlcheck", SqlCheck);  class CantCompareNulls : public std::exception { }; -SqlCheck::SqlCheck(const xmlpp::Element * p) : +SqlCheck::SqlCheck(ScriptNodePtr p) :  	ParamChecker(p),  	dataSource(p, "datasource"), -	filter(p, "filter", false, ""), -	testOp(p, "testOp", false, "=="), +	filter(p, "filter", ""), +	testOp(p, "testOp", "=="),  	testValue(p, "testValue"), -	sqlCommand(dynamic_cast<xmlpp::Element *>(p->get_children("sql").front())) +	sqlCommand(p->child("sql"))  {  } diff --git a/project2/sql/sqlCheck.h b/project2/sql/sqlCheck.h index c9933d7..86492dc 100644 --- a/project2/sql/sqlCheck.h +++ b/project2/sql/sqlCheck.h @@ -10,7 +10,7 @@ class RdbmsDataSource;  /// Project2 component to check the value of a variable against an RDBMS data source  class SqlCheck : public ParamChecker {  	public: -		SqlCheck(const xmlpp::Element * p); +		SqlCheck(ScriptNodePtr p);  		virtual ~SqlCheck();  		virtual void loadComplete(const CommonObjects *); @@ -22,7 +22,7 @@ class SqlCheck : public ParamChecker {  		const Variable testValue;  	private: -		const DynamicSql::SqlCommand sqlCommand; +		DynamicSql::SqlCommand sqlCommand;  		const RdbmsDataSource * db;  }; diff --git a/project2/sql/sqlMergeTask.cpp b/project2/sql/sqlMergeTask.cpp index 96a895a..972b299 100644 --- a/project2/sql/sqlMergeTask.cpp +++ b/project2/sql/sqlMergeTask.cpp @@ -12,7 +12,6 @@  #include <boost/algorithm/string/join.hpp>  #include <boost/foreach.hpp>  #include <boost/bind.hpp> -#include <libxml++/nodes/textnode.h>  bool SqlMergeTask::defaultUseTempTable = true;  static void attach(boost::intrusive_ptr<IHaveSubTasks> i, DB::ModifyCommand * insert); @@ -22,7 +21,7 @@ typedef boost::intrusive_ptr<SqlMergeInsert> SqlMergeInsertPtr;  /// Project2 component insert custom constructed records during an SQL Merge task  class SqlMergeInsert : IHaveParameters, public Task {  	public: -		SqlMergeInsert(const xmlpp::Element * p) : +		SqlMergeInsert(ScriptNodePtr p) :  			SourceObject(p),  			IHaveParameters(p),  			Task(p) { @@ -43,51 +42,51 @@ DECLARE_LOADER("sqlmerge", SqlMergeTask);  DECLARE_LOADER("sqlmergeinsert", SqlMergeInsert);  // Conversion logic -SqlMergeTask::SqlMergeTask(const xmlpp::Element * p) : +SqlMergeTask::SqlMergeTask(ScriptNodePtr p) :  	SourceObject(p),  	Task(p), -	updateWhere(p, "updatewhere", false), -	patchOrder(p, "patchorder", false), -	earlyKeys(p, "earlykeys", false, false), -	useView(p, "useview", false, false), +	updateWhere(p, "updatewhere", Null()), +	patchOrder(p, "patchorder", Null()), +	earlyKeys(p, "earlykeys", false), +	useView(p, "useview", false),  	tempTableCreated(false), +	sqlCommand(NULL),  	insCmd(NULL),  	destdb(NULL),  	dataSource(p, "datasource"), -	dtable(p->get_attribute_value("targettable")), +	dtable(p->value("targettable").as<std::string>()),  	dtablet(stringf("tmp_%s_%d", dtable.c_str(), getpid()))  { -	LoaderBase loader(true); -	loader.supportedStorers.insert(Storer::into<ElementLoader>(&sources)); -	loader.collectAll(p, true); +	p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&sources));  	if (!sources.empty() && useView()) {  		throw NotSupported("useview not supported with iterate fillers");  	} -	BOOST_FOREACH(xmlpp::Node * psi, p->find("columns/column")) { -		xmlpp::Element * e = static_cast<xmlpp::Element *>(psi); -		TargetColumnPtr tcp(new TargetColumn(e->get_child_text()->get_content())); -		tcp->maptable = e->get_attribute_value("maptable"); +	BOOST_FOREACH(ScriptNodePtr e, p->childrenIn("columns")) { +		TargetColumnPtr tcp(new TargetColumn(e->get_name())); +		tcp->maptable = e->value("maptable", "").as<std::string>();  		if (!tcp->maptable.empty()) {  			if (useView()) {  				throw NotSupported("useview not supported with mapped columns");  			} -			tcp->mapcolumn = e->get_attribute_value("mapcolumn"); +			tcp->mapcolumn = e->value("mapcolumn").as<std::string>();  		}  		cols.insert(tcp); +		tcp->isKey = e->value("key", false); +		if (tcp->isKey) { +			keys.insert(tcp->column); +		}  	} -	BOOST_FOREACH(xmlpp::Node * psi, p->find("columns/column[@key='true']")) { -		keys.insert(static_cast<xmlpp::Element *>(psi)->get_child_text()->get_content()); -	} -	BOOST_FOREACH(xmlpp::Node * psi, p->find("sql")) { -		sqls.push_back(static_cast<xmlpp::Element *>(psi)->get_child_text()->get_content()); +	if (p->valueExists("sql")) { +		sqlCommand = new DynamicSql::SqlCommand(p->child("sql"));  	}  }  SqlMergeTask::~SqlMergeTask()  {  	delete insCmd; +	delete sqlCommand;  }  void @@ -143,7 +142,7 @@ SqlMergeTask::createTempTable() const  		DB::ModifyCommand * cv = destdb->newModifyCommand(stringf(  					"CREATE VIEW %s AS %s",  					dtablet.c_str(), -					boost::algorithm::join(sqls, " UNION ").c_str())); +					sqlCommand->getSqlFor("").c_str()));  		cv->execute();  		delete cv;  	} @@ -280,11 +279,13 @@ attach(boost::intrusive_ptr<IHaveSubTasks> i, DB::ModifyCommand * insert)  void  SqlMergeTask::copyToTempTable() const  { -	if (useView()) return; +	if (useView()) { +		return; +	}  	BOOST_FOREACH(const Sources::value_type & i, sources) {  		i->execute();  	} -	BOOST_FOREACH(const std::string & sql, sqls) { +	if (sqlCommand) {  		Buffer ins;  		ins.appendf("INSERT INTO %s(", dtablet.c_str());  		foreach(Columns::const_iterator, cols, c) { @@ -300,7 +301,7 @@ SqlMergeTask::copyToTempTable() const  			}  			ins.append((*c)->column);  		} -		ins.appendf(" FROM (%s) tmp_src", sql.c_str()); +		ins.appendf(" FROM (%s) tmp_src", sqlCommand->getSqlFor("").c_str());  		DB::ModifyCommand * cttt = destdb->newModifyCommand(ins);  		cttt->execute();  		delete cttt; diff --git a/project2/sql/sqlMergeTask.h b/project2/sql/sqlMergeTask.h index 41d1269..dc23936 100644 --- a/project2/sql/sqlMergeTask.h +++ b/project2/sql/sqlMergeTask.h @@ -32,13 +32,14 @@ class SqlMergeTask : public Task {  				Column column;  				Column mapcolumn;  				Table maptable; +				bool isKey;  		};  		typedef std::set<TargetColumnPtr, TargetColumn::Sort> Columns;  		typedef std::set<Column> Keys; -		SqlMergeTask(const xmlpp::Element * p); +		SqlMergeTask(ScriptNodePtr p);  		virtual ~SqlMergeTask();  		virtual void loadComplete(const CommonObjects *); @@ -60,7 +61,7 @@ class SqlMergeTask : public Task {  		mutable bool tempTableCreated;  		typedef ANONSTORAGEOF(Iterate) Sources;  		Sources sources; -		std::list<std::string>	sqls; +		DynamicSql::SqlCommand * sqlCommand;  	protected:  		DB::ModifyCommand * insertCommand() const;  		DB::ModifyCommand * insCmd; diff --git a/project2/sql/sqlRows.cpp b/project2/sql/sqlRows.cpp index ed2d71b..dbcc7be 100644 --- a/project2/sql/sqlRows.cpp +++ b/project2/sql/sqlRows.cpp @@ -2,7 +2,6 @@  #include "sqlRows.h"  #include "sqlHandleAsVariableType.h"  #include "rowProcessor.h" -#include "xml.h"  #include "selectcommand.h"  #include "rdbmsDataSource.h"  #include "column.h" @@ -14,10 +13,10 @@  DECLARE_LOADER("sqlrows", SqlRows); -SqlRows::SqlRows(const xmlpp::Element * p) : +SqlRows::SqlRows(ScriptNodePtr p) :  	RowSet(p),  	dataSource(p, "datasource"), -	sqlCommand(dynamic_cast<xmlpp::Element *>(p->get_children("sql").front())), +	sqlCommand(p->child("sql")),  	db(NULL)  {  } diff --git a/project2/sql/sqlRows.h b/project2/sql/sqlRows.h index 5614fa1..7ed5d3f 100644 --- a/project2/sql/sqlRows.h +++ b/project2/sql/sqlRows.h @@ -1,7 +1,6 @@  #ifndef SQLROWS_H  #define SQLROWS_H -#include <libxml++/nodes/element.h>  #include <boost/intrusive_ptr.hpp>  #include <map>  #include "selectcommand.h" @@ -14,7 +13,7 @@ class RdbmsDataSource;  /// Project2 component to create a row set based on an SQL SELECT statement issued against an RDBMS data source  class SqlRows : public RowSet {  	public: -		SqlRows(const xmlpp::Element * p); +		SqlRows(ScriptNodePtr p);  		~SqlRows();  		void execute(const Glib::ustring &, const RowProcessor *) const; diff --git a/project2/sql/sqlTask.cpp b/project2/sql/sqlTask.cpp index 9f881de..6ff05af 100644 --- a/project2/sql/sqlTask.cpp +++ b/project2/sql/sqlTask.cpp @@ -17,27 +17,26 @@ class SqlIfChangesStorer : public StorerBase<NoOutputExecute, ANONORDEREDSTORAGE  			noChanges(nc)  		{  		} -		bool insert(const xmlpp::Element * p, NoOutputExecutePtr O) { -			xmlpp::Attribute * runon = p->get_attribute("runon"); -			if (!runon) { +		bool insert(ScriptNodePtr p, NoOutputExecutePtr O) { +			try { +				((p->value("runon").as<std::string>() == "changes") ? changes : noChanges)->push_back(O); +				return true; +			} +			catch (const ValueNotFound &) {  				throw	RunOnNotSpecified();  			} -			((runon->get_value() == "changes") ? changes : noChanges)->push_back(O); -			return true;  		}  		Map changes, noChanges;  }; -SqlTask::SqlTask(const xmlpp::Element * p) : +SqlTask::SqlTask(ScriptNodePtr p) :  	SourceObject(p),  	Task(p),  	dataSource(p, "datasource"), -	filter(p, "filter", false, ""), -	sqlCommand(dynamic_cast<xmlpp::Element *>(p->get_children("sql").front())) +	filter(p, "filter", ""), +	sqlCommand(p->child("sql"))  { -	LoaderBase loader(true); -	loader.supportedStorers.insert(new SqlIfChangesStorer(&changesNOEs, &noChangesNOEs)); -	loader.collectAll(p, true, IgnoreUnsupported); +	p->script->loader.addLoadTarget(p, new SqlIfChangesStorer(&changesNOEs, &noChangesNOEs));  }  SqlTask::~SqlTask() diff --git a/project2/sql/sqlTask.h b/project2/sql/sqlTask.h index 384b000..b0d0d27 100644 --- a/project2/sql/sqlTask.h +++ b/project2/sql/sqlTask.h @@ -1,7 +1,6 @@  #ifndef SQLTASK_H  #define SQLTASK_H -#include <libxml++/nodes/element.h>  #include <boost/intrusive_ptr.hpp>  #include <map>  #include "task.h" @@ -14,7 +13,7 @@ class RdbmsDataSource;  /// Project2 component to execute a modifying SQL statement against an RDBMS data source  class SqlTask : public Task {  	public: -		SqlTask(const xmlpp::Element * p); +		SqlTask(ScriptNodePtr p);  		virtual ~SqlTask();  		virtual void loadComplete(const CommonObjects *);  		virtual void execute() const; diff --git a/project2/sql/sqlWriter.cpp b/project2/sql/sqlWriter.cpp index 90de82f..867e1bd 100644 --- a/project2/sql/sqlWriter.cpp +++ b/project2/sql/sqlWriter.cpp @@ -11,25 +11,33 @@ DynamicSql::SqlWriter::~SqlWriter()  {  } -DynamicSql::SqlCommand::SqlCommand(const xmlpp::Element * N) +template <typename Type, typename Cons> +static +void +appendNew(DynamicSql::Writers * w, const Cons & cons)  { -	BOOST_FOREACH(xmlpp::Node * n, N->get_children()) { -		const xmlpp::TextNode * t = dynamic_cast<const xmlpp::TextNode *>(n); -		if (t) { -			writers.push_back(new SqlText(t)); -		} -		const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n); -		if (e) { -			if (e->get_name() == "filter") { -				SqlFilterPtr f = new SqlFilter(e); -				writers.push_back(f); -				filters.insert(Filters::value_type(f->name, f)); -			} -			else if (e->get_name() == "param") { -				writers.push_back(new SqlParameter(e)); -			} -		} +	w->push_back(new Type(cons)); +} + +static +void +appendNewFromNode(DynamicSql::Writers * w, DynamicSql::SqlCommand::Filters * fs, ScriptNodePtr p) +{ +	if (fs && p->get_name() == "filter") { +		DynamicSql::SqlFilterPtr f = new DynamicSql::SqlFilter(p); +		w->push_back(f); +		fs->insert(DynamicSql::SqlCommand::Filters::value_type(f->name, f));  	} +	else if (p->get_name() == "param") { +		w->push_back(new DynamicSql::SqlParameter(p)); +	} +} + +DynamicSql::SqlCommand::SqlCommand(ScriptNodePtr s) +{ +	s->composeWithCallbacks( +			boost::bind(&appendNew<SqlText, Glib::ustring>, &writers, _1), +			boost::bind(&appendNewFromNode, &writers, &filters, _1));  }  Glib::ustring @@ -59,22 +67,13 @@ DynamicSql::SqlCommand::bindParams(DB::Command * cmd, unsigned int & offset) con  	}  } -DynamicSql::SqlFilter::SqlFilter(const xmlpp::Element * N) : -	name(N->get_attribute_value("name")), +DynamicSql::SqlFilter::SqlFilter(ScriptNodePtr p) : +	name(p->value("name").as<Glib::ustring>()),  	active(false)  { -	BOOST_FOREACH(xmlpp::Node * n, N->get_children()) { -		const xmlpp::TextNode * t = dynamic_cast<const xmlpp::TextNode *>(n); -		if (t) { -			writers.push_back(new SqlText(t)); -		} -		const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n); -		if (e) { -			if (e->get_name() == "param") { -				writers.push_back(new SqlParameter(e)); -			} -		} -	} +	p->composeWithCallbacks( +			boost::bind(&appendNew<SqlText, Glib::ustring>, &writers, _1), +			boost::bind(&appendNewFromNode, &writers, (DynamicSql::SqlCommand::Filters *)NULL, _1));  }  void @@ -97,7 +96,7 @@ DynamicSql::SqlFilter::bindParams(DB::Command * cmd, unsigned int & offset) cons  	}  } -DynamicSql::SqlParameter::SqlParameter(const xmlpp::Element * n) : +DynamicSql::SqlParameter::SqlParameter(ScriptNodePtr n) :  	Variable(n, boost::optional<Glib::ustring>("local"))  {  } @@ -114,8 +113,8 @@ DynamicSql::SqlParameter::bindParams(DB::Command * cmd, unsigned int & offset) c  	boost::apply_visitor<const SqlVariableBinder, const VariableType>(SqlVariableBinder(cmd, offset++), (*this));  } -DynamicSql::SqlText::SqlText(const xmlpp::TextNode * n) : -	text(n->get_content()) +DynamicSql::SqlText::SqlText(const Glib::ustring & n) : +	text(n)  {  } diff --git a/project2/sql/sqlWriter.h b/project2/sql/sqlWriter.h index 7693e19..4b57fa9 100644 --- a/project2/sql/sqlWriter.h +++ b/project2/sql/sqlWriter.h @@ -2,7 +2,6 @@  #define SQLWRITER_H  #include <intrusivePtrBase.h> -#include <libxml++/nodes/textnode.h>  #include <command.h>  #include <glibmm/ustring.h>  #include <list> @@ -22,7 +21,7 @@ namespace DynamicSql {  	};  	class SqlText : public SqlWriter {  		public: -			SqlText(const xmlpp::TextNode *); +			SqlText(const Glib::ustring &);  			virtual void writeSql(Glib::ustring & sql) const;  			virtual void bindParams(DB::Command *, unsigned int & offset) const; @@ -30,13 +29,13 @@ namespace DynamicSql {  	};  	class SqlParameter : public SqlWriter, Variable {  		public: -			SqlParameter(const xmlpp::Element *); +			SqlParameter(ScriptNodePtr);  			virtual void writeSql(Glib::ustring & sql) const;  			virtual void bindParams(DB::Command *, unsigned int & offset) const;  	};  	class SqlFilter : public SqlWriter {  		public: -			SqlFilter(const xmlpp::Element *); +			SqlFilter(ScriptNodePtr);  			virtual void writeSql(Glib::ustring & sql) const;  			virtual void bindParams(DB::Command *, unsigned int & offset) const; @@ -48,7 +47,7 @@ namespace DynamicSql {  	typedef boost::intrusive_ptr<SqlFilter> SqlFilterPtr;  	class SqlCommand : public SqlWriter {  		public: -			SqlCommand(const xmlpp::Element *); +			SqlCommand(ScriptNodePtr);  			virtual void writeSql(Glib::ustring & sql) const;  			virtual void bindParams(DB::Command *, unsigned int & offset) const;  			typedef std::multimap<Glib::ustring, SqlFilterPtr> Filters; diff --git a/project2/url/Jamfile.jam b/project2/url/Jamfile.jam index 6e6dc36..1710e17 100644 --- a/project2/url/Jamfile.jam +++ b/project2/url/Jamfile.jam @@ -1,6 +1,7 @@ -alias libxmlpp : : : : -	<cflags>"`pkg-config --cflags libxml++-2.6`" -	<linkflags>"`pkg-config --libs libxml++-2.6`" ; +alias glibmm : : : : +	<cflags>"`pkg-config --cflags glibmm-2.4`" +	<linkflags>"`pkg-config --libs glibmm-2.4`" +	;  lib curl : : <name>curl ;  lib p2url : @@ -11,7 +12,7 @@ lib p2url :  	<library>../common//p2common  	<library>../files//p2files  	<include>../../libmisc -	<library>libxmlpp +	<library>glibmm  	<library>curl  	: :  	<include>. diff --git a/project2/url/curlHelper.cpp b/project2/url/curlHelper.cpp index 1b98d3b..7f698cb 100644 --- a/project2/url/curlHelper.cpp +++ b/project2/url/curlHelper.cpp @@ -1,15 +1,16 @@  #include "curlHelper.h" +#include "scripts.h" -VariableCurlHelper::VariableCurlHelper(const xmlpp::Element * p) : +VariableCurlHelper::VariableCurlHelper(ScriptNodePtr p) :  	url(p, "url"), -	userAgent(p, "useragent", false, "project2/0.3"), -	cookieJar(p, "cookiejar", false), -	proxy(p, "proxy", false), -	referer(p, "referer", false), -	method(p, "method", false), -	userName(p, "username", false), -	password(p, "password", false), -	timeout(p, "timeout", false, Variable(6000)) +	userAgent(p, "useragent", "project2/0.3"), +	cookieJar(p, "cookiejar", Null()), +	proxy(p, "proxy", Null()), +	referer(p, "referer", Null()), +	method(p, "method", Null()), +	userName(p, "username", Null()), +	password(p, "password", Null()), +	timeout(p, "timeout", 6000)  {  } diff --git a/project2/url/curlHelper.h b/project2/url/curlHelper.h index 28395e5..e3e4484 100644 --- a/project2/url/curlHelper.h +++ b/project2/url/curlHelper.h @@ -1,7 +1,6 @@  #ifndef CURLHELPER_H  #define CURLHELPER_H -#include <libxml++/nodes/element.h>  #include "variables.h"  #include "../libmisc/curlsup.h" @@ -35,7 +34,7 @@ class CurlHelper {  /// Project2 helper component to configure CurlHelper from variables  class VariableCurlHelper : public CurlHelper {  	public: -		VariableCurlHelper(const xmlpp::Element * p); +		VariableCurlHelper(ScriptNodePtr p);  		~VariableCurlHelper();  		const Variable url; diff --git a/project2/url/urlRows.cpp b/project2/url/urlRows.cpp index b3abddd..a634126 100644 --- a/project2/url/urlRows.cpp +++ b/project2/url/urlRows.cpp @@ -8,7 +8,7 @@  DECLARE_LOADER("urlrows", UrlRows); -UrlRows::UrlRows(const xmlpp::Element * p) : +UrlRows::UrlRows(ScriptNodePtr p) :  	StreamRows(p),  	VariableCurlHelper(p),  	convertRequired(encoding != "utf-8") diff --git a/project2/url/urlRows.h b/project2/url/urlRows.h index 9bd4302..77c85ab 100644 --- a/project2/url/urlRows.h +++ b/project2/url/urlRows.h @@ -1,7 +1,6 @@  #ifndef URLROWS_H  #define URLROWS_H -#include <libxml++/nodes/element.h>  #include <boost/intrusive_ptr.hpp>  #include <boost/shared_ptr.hpp>  #include <map> @@ -11,7 +10,7 @@  /// Project2 component to create a row set from the contents of a file accessible via libcurl  class UrlRows : public StreamRows, VariableCurlHelper {  	public: -		UrlRows(const xmlpp::Element * p); +		UrlRows(ScriptNodePtr p);  		~UrlRows();  		void execute(const Glib::ustring &, const RowProcessor *) const; diff --git a/project2/xml/Jamfile.jam b/project2/xml/Jamfile.jam index 6078290..1e8fcf7 100644 --- a/project2/xml/Jamfile.jam +++ b/project2/xml/Jamfile.jam @@ -14,8 +14,7 @@ cpp-pch pch : pch.hpp :  	;  lib p2xml :  	pch -	rawView.cpp xmlPresenter.cpp transformXml.cpp transformHtml.cpp transformText.cpp xmlRows.cpp -	xmlRawRows.cpp xpathRows.cpp xmlDocumentCache.cpp xmlDocumentPrefetch.cpp xmlCache.cpp sessionXml.cpp +	[ glob *.cpp ]  	:  	<include>../libmisc  	<library>libxmlpp diff --git a/project2/xml/rawView.cpp b/project2/xml/rawView.cpp index 151d594..8feceb3 100644 --- a/project2/xml/rawView.cpp +++ b/project2/xml/rawView.cpp @@ -6,15 +6,16 @@  #include "xmlObjectLoader.h"  #include "environment.h"  #include "appEngine.h" +#include "xmlScriptParser.h"  #include <boost/foreach.hpp>  #include <libxml++/nodes/textnode.h>  DECLARE_LOADER("rawview", RawView); -RawView::RawView(const xmlpp::Element * p) : +RawView::RawView(ScriptNodePtr p) :  	SourceObject(p),  	View(p), -	copyRoot(p) +	copyRoot(boost::dynamic_pointer_cast<const XmlScriptNode>(p)->xmlElement())  {  } diff --git a/project2/xml/rawView.h b/project2/xml/rawView.h index 54f7b2e..67d5628 100644 --- a/project2/xml/rawView.h +++ b/project2/xml/rawView.h @@ -9,7 +9,7 @@  /// Project2 component to create output based on its own XML tree node  class RawView : public View {  	public: -		RawView(const xmlpp::Element * p); +		RawView(ScriptNodePtr p);  		void execute(const MultiRowSetPresenter *) const;  	private: diff --git a/project2/xml/xmlCache.cpp b/project2/xml/xmlCache.cpp index 8c0dd00..96cf914 100644 --- a/project2/xml/xmlCache.cpp +++ b/project2/xml/xmlCache.cpp @@ -14,7 +14,7 @@  class XmlCache : public Cache {  	public: -		XmlCache(const xmlpp::Element * p) : +		XmlCache(ScriptNodePtr p) :  			Cache(p)  		{  		} diff --git a/project2/xml/xmlDocumentPrefetch.cpp b/project2/xml/xmlDocumentPrefetch.cpp index e5565e6..2be3eea 100644 --- a/project2/xml/xmlDocumentPrefetch.cpp +++ b/project2/xml/xmlDocumentPrefetch.cpp @@ -4,14 +4,14 @@  DECLARE_LOADER("xmldocumentprefetch", XmlDocumentPrefetch); -XmlDocumentPrefetch::XmlDocumentPrefetch(const xmlpp::Element * p) : +XmlDocumentPrefetch::XmlDocumentPrefetch(ScriptNodePtr p) :  	SourceObject(p),  	View(p),  	Task(p),  	VariableCurlHelper(p), -	html(p, "html", false, false), -	warnings(p, "warnings", false, true), -	encoding(p, "encoding", false) +	html(p, "html", false), +	warnings(p, "warnings", true), +	encoding(p, "encoding", Null())  {  } diff --git a/project2/xml/xmlDocumentPrefetch.h b/project2/xml/xmlDocumentPrefetch.h index f75fabe..454492a 100644 --- a/project2/xml/xmlDocumentPrefetch.h +++ b/project2/xml/xmlDocumentPrefetch.h @@ -10,7 +10,7 @@  /// Project2 component to queue up CURL objects to be downloaded  class XmlDocumentPrefetch : public View, public Task, XmlDocumentCache, VariableCurlHelper {  	public: -		XmlDocumentPrefetch(const xmlpp::Element * p); +		XmlDocumentPrefetch(ScriptNodePtr p);  		~XmlDocumentPrefetch();  		void execute(const MultiRowSetPresenter*) const; diff --git a/project2/xml/xmlPresenter.cpp b/project2/xml/xmlPresenter.cpp index 249e4f4..86ec831 100644 --- a/project2/xml/xmlPresenter.cpp +++ b/project2/xml/xmlPresenter.cpp @@ -16,11 +16,11 @@ XmlPresenter::XmlPresenter(const Glib::ustring & responseRootNodeName, const Gli  	createDoc(responseRootNodeName, responseStyle);  } -XmlPresenter::XmlPresenter(const xmlpp::Element * e) : -	ContentPresenter(e->get_attribute_value("contenttype")), +XmlPresenter::XmlPresenter(ScriptNodePtr e) : +	ContentPresenter(e->value("contenttype", "")),  	responseDoc(XmlDocumentPtr(new xmlpp::Document("1.0")))  { -	createDoc(e->get_attribute_value("root"), e->get_attribute_value("style")); +	createDoc(e->value("root", ""), e->value("style", ""));  }  XmlPresenter::~XmlPresenter() diff --git a/project2/xml/xmlPresenter.h b/project2/xml/xmlPresenter.h index 4f3fdbb..38244be 100644 --- a/project2/xml/xmlPresenter.h +++ b/project2/xml/xmlPresenter.h @@ -3,16 +3,18 @@  #include "presenter.h"  #include "transform.h" +#include <libxml/tree.h>  namespace xmlpp {  	class Document; +	class Element;  }  class XmlPresenter : public Presenter, public ContentPresenter, public SourceOf<xmlpp::Document>, public SourceOf<xmlDoc>, public SourceOf<boost::shared_ptr<xmlpp::Document> > {  	public:  		typedef boost::shared_ptr<xmlpp::Document> XmlDocumentPtr;  		XmlPresenter(const Glib::ustring & responseRootNodeName, const Glib::ustring & responseStyle, const Glib::ustring & contentType); -		XmlPresenter(const xmlpp::Element * e); +		XmlPresenter(ScriptNodePtr e);  		~XmlPresenter();  		void declareNamespace(const Glib::ustring & prefix, const Glib::ustring & ns) const; diff --git a/project2/xml/xmlRawRows.cpp b/project2/xml/xmlRawRows.cpp index 73685aa..faca679 100644 --- a/project2/xml/xmlRawRows.cpp +++ b/project2/xml/xmlRawRows.cpp @@ -42,7 +42,7 @@ class XmlRowState : public RowState {  }; -XmlRawRowsBase::XmlRawRowsBase(const xmlpp::Element * p) : +XmlRawRowsBase::XmlRawRowsBase(ScriptNodePtr p) :  	RowSet(p)  {  } @@ -81,7 +81,7 @@ void XmlRawRowsBase::execute(const xmlpp::Document * doc, const RowProcessor * r  	}  } -XmlRawRows::XmlRawRows(const xmlpp::Element * p) : +XmlRawRows::XmlRawRows(ScriptNodePtr p) :  	XmlRawRowsBase(p),  	path(p, "path")  { diff --git a/project2/xml/xmlRawRows.h b/project2/xml/xmlRawRows.h index 81c04a5..15dad48 100644 --- a/project2/xml/xmlRawRows.h +++ b/project2/xml/xmlRawRows.h @@ -6,7 +6,7 @@ namespace xmlpp {  class XmlRawRowsBase : public RowSet {  	public: -		XmlRawRowsBase(const xmlpp::Element * p); +		XmlRawRowsBase(ScriptNodePtr p);  		XmlRawRowsBase();  	protected: @@ -15,7 +15,7 @@ class XmlRawRowsBase : public RowSet {  class XmlRawRows : public XmlRawRowsBase {  	public: -		XmlRawRows(const xmlpp::Element * p); +		XmlRawRows(ScriptNodePtr p);  		XmlRawRows(const Glib::ustring & p);  		void execute(const Glib::ustring&, const RowProcessor * rp) const; diff --git a/project2/xml/xmlRows.cpp b/project2/xml/xmlRows.cpp index d648b10..9ec7be0 100644 --- a/project2/xml/xmlRows.cpp +++ b/project2/xml/xmlRows.cpp @@ -14,7 +14,7 @@  DECLARE_LOADER("xmlrows", XmlRows); -XmlRows::XmlRows(const xmlpp::Element * p) : +XmlRows::XmlRows(ScriptNodePtr p) :  	RowSet(p),  	recordRoot(p, "recordroot"),  	recordTrigger(p, "recordtrigger"), @@ -29,22 +29,19 @@ XmlRows::XmlRows(const xmlpp::Element * p) :  	boost::split(trigger, rT, boost::is_any_of("/"));  	unsigned int col = 0; -	BOOST_FOREACH(const xmlpp::Node * node, p->find("fields/field")) { -		const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node); -		if (elem) { -			Path p(root); -			Glib::ustring path(elem->get_child_text()->get_content()); +	BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("fields")) { +		Path p(root); +		Glib::ustring path = node->value("path"); -			for(ssi It = make_split_iterator(path, first_finder("/", boost::is_equal())); It!=ssi(); ++It) { -				if (It->front() == '@') { -					anyInterestingAttributes = true; -				} -				p.push_back(Glib::ustring(It->begin(), It->end())); +		for(ssi It = make_split_iterator(path, first_finder("/", boost::is_equal())); It!=ssi(); ++It) { +			if (It->front() == '@') { +				anyInterestingAttributes = true;  			} - -			fields[p] = col; -			fieldNames.insert(new Column(col++, elem->get_attribute_value("name"))); +			p.push_back(Glib::ustring(It->begin(), It->end()));  		} + +		fields[p] = col; +		fieldNames.insert(new Column(col++, node->get_name()));  	}  } diff --git a/project2/xml/xmlRows.h b/project2/xml/xmlRows.h index d9971bc..975e290 100644 --- a/project2/xml/xmlRows.h +++ b/project2/xml/xmlRows.h @@ -12,7 +12,7 @@ class XmlRows : public RowSet {  		typedef std::vector<std::string> Path;  		typedef std::map<Path, unsigned int> Interests; -		XmlRows(const xmlpp::Element * p); +		XmlRows(ScriptNodePtr p);  		~XmlRows();  		void execute(const Glib::ustring &, const RowProcessor *) const; diff --git a/project2/xml/xmlScriptParser.cpp b/project2/xml/xmlScriptParser.cpp new file mode 100644 index 0000000..4963b8f --- /dev/null +++ b/project2/xml/xmlScriptParser.cpp @@ -0,0 +1,191 @@ +#include <pch.hpp> +#include "xmlScriptParser.h" +#include "scripts.h" +#include "commonObjects.h" +#include "variables-modliteral.h" +#include <libxml/xinclude.h> +#include <boost/filesystem/convenience.hpp> + +XmlScriptParser::XmlScriptParser(const boost::filesystem::path & file) +{ +	try { +		parse_file(file.string()); +	} +	catch (const xmlpp::internal_error &) { +		throw NotReadable(file.string()); +	} +	for (int x; (x = xmlXIncludeProcessFlags(get_document()->cobj(), XML_PARSE_NOXINCNODE)); ) { +		if (x < 0) { +			throw IncludesError(file.string()); +		} +	} +} + +ScriptNodePtr +XmlScriptParser::root() { +	if (!_root) { +		_root = new XmlScriptNode(get_document()->get_root_node(), this); +	} +	return _root; +} + +class XmlScriptReaderLoader : public ScriptReaderLoader { +	public: +		ScriptReaderPtr resolveScript(const std::string & group, const std::string & name) const { +			boost::filesystem::path script(boost::filesystem::current_path() / group); +			BOOST_FOREACH(const boost::filesystem::path & e, boost::filesystem::path(name)) { +				if (boost::filesystem::is_directory(script / e)) { +					script /= e; +				} +				else { +					boost::filesystem::path path = (script / e).string() + ".xml"; +					if (boost::filesystem::is_regular_file(path)) { +						return new XmlScriptParser(path); +					} +				} +			} +			return NULL; +		} +}; + + +XmlScriptNode::XmlScriptNode(const xmlpp::Element * e, ScriptReaderPtr p) : +	ScriptNode(p), +	element(e) +{ +} + +const xmlpp::Element * +XmlScriptNode::xmlElement() const +{ +	return element; +} + +bool +XmlScriptNode::componentNamespace() const +{ +	return element->get_namespace_uri	() == Environment::getCurrent()->xmlNamespace; +} + +std::string +XmlScriptNode::get_name() const +{ +	return element->get_name(); +} + +bool +XmlScriptNode::valueExists(const Glib::ustring & n) const +{ +	return (element->get_attribute(n) || !element->get_children(n).empty()); +} + +ScriptNode::ScriptNodes +XmlScriptNode::children() const +{ +	ScriptNodes sns; +	BOOST_FOREACH(const xmlpp::Node * n, element->get_children()) { +		if (const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n)) { +			sns.push_back(new XmlScriptNode(e, script)); +		} +	} +	return sns; +} + +ScriptNodePtr +XmlScriptNode::child(const Glib::ustring & n) const +{ +	const xmlpp::Element::NodeList cs = element->get_children(n); +	if (cs.size() == 1) { +		if (const xmlpp::Element * c = dynamic_cast<const xmlpp::Element *>(cs.front())) { +			return new XmlScriptNode(c, script); +		} +	} +	throw ValueNotFound(n); +} + +ScriptNode::ScriptNodes +XmlScriptNode::childrenIn(const Glib::ustring & c) const +{ +	ScriptNodes sns; +	BOOST_FOREACH(const xmlpp::Node * n, element->get_children(c)) { +		if (const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n)) { +			BOOST_FOREACH(const xmlpp::Node * n1, e->get_children()) { +				if (const xmlpp::Element * e1 = dynamic_cast<const xmlpp::Element *>(n1)) { +					sns.push_back(new XmlScriptNode(e1, script)); +				} +			} +		} +	} +	return sns; +} + +VariableImpl * +XmlScriptNode::variable(const Glib::ustring & n) const +{ +	if (const xmlpp::Attribute * a = element->get_attribute(n)) { +		return new VariableLiteral(a->get_value()); +	} +	const xmlpp::Element::NodeList cs = element->get_children(n); +	if (cs.size() == 1) { +		if (const xmlpp::Element * c = dynamic_cast<const xmlpp::Element *>(cs.front())) { +			if (const xmlpp::Attribute * source = c->get_attribute("source")) { +				return LoaderBase::getLoader<VariableLoader, UnknownVariableSource>(source->get_value())->create(new XmlScriptNode(c, script)); +			} +			else { +				return new VariableLiteral(new XmlScriptNode(c, script)); +			} +		} +	} +	throw ValueNotFound(n); +} + +VariableImpl * +XmlScriptNode::variable(const boost::optional<Glib::ustring> & defaultSource) const +{ +	if (const xmlpp::Attribute * source = element->get_attribute("source")) { +		return LoaderBase::getLoader<VariableLoader, UnknownVariableSource>(source->get_value())->create(new XmlScriptNode(element, script)); +	} +	else if (defaultSource) { +		return LoaderBase::getLoader<VariableLoader, UnknownVariableSource>(defaultSource.get())->create(new XmlScriptNode(element, script)); +	} +	else { +		return new VariableLiteral(new XmlScriptNode(element, script)); +	} +} + +VariableType +XmlScriptNode::value(const Glib::ustring & n) const +{ +	if (const xmlpp::Attribute * a = element->get_attribute(n)) { +		return a->get_value(); +	} +	const xmlpp::Element::NodeList cs = element->get_children(n); +	if (cs.size() == 1) { +		if (const xmlpp::Element * c = dynamic_cast<const xmlpp::Element *>(cs.front())) { +			boost::intrusive_ptr<VariableImpl> v; +			if (const xmlpp::Attribute * source = c->get_attribute("source")) { +				v = LoaderBase::getLoader<VariableLoader, UnknownVariableSource>(source->get_value())->create(new XmlScriptNode(c, script)); +			} +			else { +				v = new VariableLiteral(new XmlScriptNode(c, script)); +			} +			return v->value(); +		} +	} +	throw ValueNotFound(n); +} + +void +XmlScriptNode::composeWithCallbacks(const LiteralCallback & lcb, const NodeCallback & ncb) const +{ +	BOOST_FOREACH(const xmlpp::Node * n, element->get_children()) { +		if (const xmlpp::TextNode * t = dynamic_cast<const xmlpp::TextNode *>(n)) { +			lcb(t->get_content()); +		} +		else if (const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n)) { +			ncb(new XmlScriptNode(e, script)); +		} +	} +} + +DECLARE_CUSTOM_COMPONENT_LOADER("xmlScriptReader", XmlScriptReaderLoader, XmlScriptReaderLoader, ScriptReaderLoader); diff --git a/project2/xml/xmlScriptParser.h b/project2/xml/xmlScriptParser.h new file mode 100644 index 0000000..ad0b1bf --- /dev/null +++ b/project2/xml/xmlScriptParser.h @@ -0,0 +1,48 @@ +#ifndef XMLSCRIPTPARSER_H +#define XMLSCRIPTPARSER_H + +#include <boost/function.hpp> +#include "exceptions.h" +#include "xmlObjectLoader.h" +#include "scripts.h" +#include <intrusivePtrBase.h> +#include <boost/filesystem/path.hpp> +#include <libxml++/document.h> +#include <libxml++/nodes/element.h> +#include <libxml++/parsers/domparser.h> + +class XmlScriptNode : public ScriptNode { +	public: +		XmlScriptNode(const xmlpp::Element * xmlElement, ScriptReaderPtr p); + +		const xmlpp::Element * xmlElement() const; +		bool componentNamespace() const; +		std::string get_name() const; +		ScriptNodePtr child(const Glib::ustring&) const; +		ScriptNodes children() const; +		ScriptNodes childrenIn(const Glib::ustring&) const; +		bool valueExists(const Glib::ustring&) const; +		VariableImpl * variable(const boost::optional<Glib::ustring> & defaultSource) const; +		VariableImpl * variable(const Glib::ustring&) const; +		VariableType value(const Glib::ustring&) const; +		void composeWithCallbacks(const ScriptNode::LiteralCallback&, const ScriptNode::NodeCallback&) const; + +	private: +		const xmlpp::Element * element; +}; + +class XmlScriptParser : public xmlpp::DomParser, public ScriptReader { +	public: +		SimpleMessageException(ParseError); +		SimpleMessageExceptionBase(NotReadable, ParseError); +		SimpleMessageExceptionBase(IncludesError, ParseError); + +		XmlScriptParser(const boost::filesystem::path & file); +		ScriptNodePtr root(); +	private: +		ScriptNodePtr _root; +}; + + +#endif + diff --git a/project2/xml/xpathRows.cpp b/project2/xml/xpathRows.cpp index e65104d..bc9481a 100644 --- a/project2/xml/xpathRows.cpp +++ b/project2/xml/xpathRows.cpp @@ -17,25 +17,19 @@ DECLARE_LOADER("xpathrows", XPathRows);  SimpleMessageException(XpathInitError);  SimpleMessageException(XpathEvalError); -XPathRows::XPathRows(const xmlpp::Element * p) : +XPathRows::XPathRows(ScriptNodePtr p) :  	RowSet(p),  	VariableCurlHelper(p), -	html(p, "html", false, false), -	warnings(p, "warnings", false, true), -	encoding(p, "encoding", false) +	html(p, "html", false), +	warnings(p, "warnings", true), +	encoding(p, "encoding", Null())  { -	BOOST_FOREACH(const xmlpp::Node * node, p->find("filterview")) { -		const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node); -		if (elem) { -			FilterViewPtr fv = new FilterView(elem); -			fvs[fv->name] = fv; -		} +	BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("filterviews")) { +		FilterViewPtr fv = new FilterView(node); +		fvs[fv->name] = fv;  	} -	BOOST_FOREACH(const xmlpp::Node * node, p->find("namespace")) { -		const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node); -		if (elem) { -			namespaces[elem->get_attribute_value("prefix")] = elem->get_attribute_value("url"); -		} +	BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("namespaces")) { +		namespaces[node->value("prefix")] = node->value("url").as<Glib::ustring>();  	}  } @@ -122,21 +116,21 @@ XPathRows::execute(const Glib::ustring & filter, const RowProcessor * rp) const  	}  } -XPathRows::FilterView::FilterView(const xmlpp::Element * p) : -	DefinedColumns(p, "field", boost::bind(XPathRows::FilterViewColumn::make, _1, _2)), -	name(p->get_attribute_value("name")), +XPathRows::FilterView::FilterView(ScriptNodePtr p) : +	DefinedColumns(p, "fields", boost::bind(XPathRows::FilterViewColumn::make, _1, _2)), +	name(p->get_name()),  	root(p, "root")  {  } -XPathRows::FilterViewColumn::FilterViewColumn(unsigned int idx, const xmlpp::Element * p) : +XPathRows::FilterViewColumn::FilterViewColumn(unsigned int idx, ScriptNodePtr p) :  	Column(idx, p),  	path(p, "xpath")  {  }  XPathRows::FilterViewColumn * -XPathRows::FilterViewColumn::make(unsigned int idx, const xmlpp::Element * p) +XPathRows::FilterViewColumn::make(unsigned int idx, ScriptNodePtr p)  {  	return new FilterViewColumn(idx, p);  } diff --git a/project2/xml/xpathRows.h b/project2/xml/xpathRows.h index e2c6327..47d34eb 100644 --- a/project2/xml/xpathRows.h +++ b/project2/xml/xpathRows.h @@ -14,7 +14,7 @@  /// Project2 component to create a row set based on the contents of an XML resource and specific XPaths with its hierarchy  class XPathRows : public RowSet, XmlDocumentCache, VariableCurlHelper {  	public: -		XPathRows(const xmlpp::Element * p); +		XPathRows(ScriptNodePtr p);  		~XPathRows();  		void execute(const Glib::ustring &, const RowProcessor *) const; @@ -22,15 +22,15 @@ class XPathRows : public RowSet, XmlDocumentCache, VariableCurlHelper {  	private:  		class FilterViewColumn : public Column {  			public: -				FilterViewColumn(unsigned int, const xmlpp::Element *); -				static FilterViewColumn * make(unsigned int, const xmlpp::Element *); +				FilterViewColumn(unsigned int, ScriptNodePtr); +				static FilterViewColumn * make(unsigned int, ScriptNodePtr);  				const Variable path;  		};  		class FilterView : public DefinedColumns, public virtual IntrusivePtrBase {  			public:  				typedef std::map<const Glib::ustring, Variable> XPaths; -				FilterView(const xmlpp::Element * p); +				FilterView(ScriptNodePtr p);  				const Glib::ustring name;  				const Variable root; | 
