diff options
| -rw-r--r-- | project2/Jamfile.jam | 5 | ||||
| -rw-r--r-- | project2/variables-modconfig.cpp | 26 | ||||
| -rw-r--r-- | project2/variables-modlookup.cpp | 110 | ||||
| -rw-r--r-- | project2/variables-modparam.cpp | 34 | ||||
| -rw-r--r-- | project2/variables-modsession.cpp | 31 | ||||
| -rw-r--r-- | project2/variables-moduri.cpp | 34 | ||||
| -rw-r--r-- | project2/variables.cpp | 279 | ||||
| -rw-r--r-- | project2/variables.h | 28 | 
8 files changed, 298 insertions, 249 deletions
diff --git a/project2/Jamfile.jam b/project2/Jamfile.jam index 5d7186d..5fc26f2 100644 --- a/project2/Jamfile.jam +++ b/project2/Jamfile.jam @@ -60,6 +60,11 @@ lib p2common :  	sessionClearTask.cpp session.cpp sessionSetTask.cpp commonObjects.cpp xmlPresenter.cpp taskHost.cpp checkHost.cpp  	rowView.cpp rowSet.cpp rowUser.cpp rowProcessor.cpp config.cpp fileStrmVarWriter.cpp noOutputExecute.cpp  	transform.cpp transformHtml.cpp transformText.cpp definedColumns.cpp +	variables-modconfig.cpp +	variables-modlookup.cpp +	variables-modparam.cpp +	variables-modsession.cpp +	variables-moduri.cpp  	../libmisc/buffer.cpp  	../libmisc/misc.cpp  	: diff --git a/project2/variables-modconfig.cpp b/project2/variables-modconfig.cpp new file mode 100644 index 0000000..935e2d6 --- /dev/null +++ b/project2/variables-modconfig.cpp @@ -0,0 +1,26 @@ +#include "variables.h" +#include "xmlObjectLoader.h" +#include "xmlStorage.h" +#include "appEngine.h" + +/// Variable implementation to access platform configuration values +class VariableConfig : public VariableImplDyn { +	public: +		VariableConfig(const xmlpp::Element * e) : +			VariableImplDyn(e), +			name(e->get_attribute_value("name")) +		{ +		} +		const VariableType & value() const +		{ +			if (!cacheValid) { +				cache = ApplicationEngine::getCurrent()->getCurrentConfig()->getValue(name); +				cacheValid = true; +			} +			return cache; +		} +	private: +		const Glib::ustring name; +}; +DECLARE_COMPONENT_LOADER("config", VariableConfig, VariableLoader); + diff --git a/project2/variables-modlookup.cpp b/project2/variables-modlookup.cpp new file mode 100644 index 0000000..e020d9a --- /dev/null +++ b/project2/variables-modlookup.cpp @@ -0,0 +1,110 @@ +#include "variables.h" +#include "logger.h" +#include "rowProcessor.h" +#include "rowSet.h" +#include <boost/foreach.hpp> +#include "xmlObjectLoader.h" +#include "xmlStorage.h" + +template <class S> +class compi : public boost::static_visitor<bool> { +	public: +		compi(const S & s) : _s(s) { } +		bool operator()(const S & t) const +		{ +			return _s < t; +		} +		template <class T> +		bool operator()(const T &) const +		{ +			// should never be called +			throw std::logic_error("Shouldn't ever be comparing variables of different type"); +		} +	private: +		const S & _s; +}; + +class comp : public boost::static_visitor<bool> { +	public: +		comp(const VariableType & a) : _a(a) { } +		template <class T> +		bool operator()(const T & t) const +		{ +			return boost::apply_visitor(compi<T>(t), _a); +		} +	private: +		const VariableType & _a; +}; + +bool +operator<(const VariableType & a, const VariableType & b) +{ +	if (a.which() < b.which()) { +		return true; +	} +	if (a.which() == b.which()) { +		return boost::apply_visitor(comp(a), b); +	} +	return false; +} + +/// Variable implementation that looks up it's value in a map of key(s)/value pairs +class VariableLookup : public VariableImplDyn, public RowProcessor { +	private: +		typedef std::vector<VariableType> Key; +		typedef std::map<Key, VariableType> Map; +	public: +		class NotFound { }; +		VariableLookup(const xmlpp::Element * e) : +			VariableImplDyn(e), +			RowProcessor(e), +			name(e->get_attribute_value("name")) +		{ +			LoaderBase loader(true); +			loader.supportedStorers.insert(Storer::into(&rowSets)); +			loader.collectAll(e, false); +		} +		const VariableType & value() const +		{ +			if (map.empty()) { +				fillCache(); +			} +			Key k; +			k.reserve(parameters.size()); +			BOOST_FOREACH(const Parameters::value_type & p, parameters) { +				k.push_back(p.second->value()); +			} +			Map::const_iterator i = map.find(k); +			if (i != map.end()) { +				cache = i->second; +				return cache; +			} +			throw NotFound(); +		} +	private: +		void fillCache() const +		{ +			BOOST_FOREACH(const RowSets::value_type & rs, rowSets) { +				cs = rs; +				rs->execute(this); +			} +			cs.reset(); +			Logger()->messagef(LOG_DEBUG, "%s: %s has filled cached with %zu items", +					__PRETTY_FUNCTION__, name.c_str(), map.size()); +		} +		void rowReady() const +		{ +			Key k; +			k.reserve(cs->columnCount() - 1); +			BOOST_FOREACH(const Parameters::value_type & p, parameters) { +				k.push_back(cs->getCurrentValue(p.first)); +			} +			map[k] = cs->getCurrentValue(name); +		} +		mutable Map map; +		mutable RowSetPtr cs; +		typedef ANONSTORAGEOF(RowSet) RowSets; +		RowSets rowSets; +		const Glib::ustring name; +}; +DECLARE_COMPONENT_LOADER("lookup", VariableLookup, VariableLoader); diff --git a/project2/variables-modparam.cpp b/project2/variables-modparam.cpp new file mode 100644 index 0000000..a932412 --- /dev/null +++ b/project2/variables-modparam.cpp @@ -0,0 +1,34 @@ +#include "variables.h" +#include "xmlObjectLoader.h" +#include "xmlStorage.h" +#include "appEngine.h" + +/// Variable implementation to access call parameters +class VariableParam : public VariableImplDyn { +	public: +		VariableParam(const xmlpp::Element * e) : +			VariableImplDyn(e), +			name(e->get_attribute_value("name")) +		{ +		} +		const VariableType & value() const +		{ +			if (!cacheValid) { +				try { +					cache = ApplicationEngine::getCurrent()->env()->getParamQuery(name); +				} +				catch (ParamNotFound) { +					if (!defaultValue) { +						throw; +					} +					cache = (*defaultValue)(); +				} +				cacheValid = true; +			} +			return cache; +		} +	private: +		const Glib::ustring name; +}; +DECLARE_COMPONENT_LOADER("param", VariableParam, VariableLoader); + diff --git a/project2/variables-modsession.cpp b/project2/variables-modsession.cpp new file mode 100644 index 0000000..0d39695 --- /dev/null +++ b/project2/variables-modsession.cpp @@ -0,0 +1,31 @@ +#include "variables.h" +#include "xmlObjectLoader.h" +#include "xmlStorage.h" +#include "appEngine.h" + +/// Variable implementation to access session contents +class VariableSession : public VariableImplDyn { +	public: +		VariableSession(const xmlpp::Element * e) : +			VariableImplDyn(e), +			name(e->get_attribute_value("name")) +		{ +		} +		const VariableType & value() const +		{ +			try { +				cache = ApplicationEngine::getCurrent()->session()->GetValue(name); +			} +			catch (Session::VariableNotFound) { +				if (!defaultValue) { +					throw; +				} +				cache = (*defaultValue)(); +			} +			return cache; +		} +	private: +		const Glib::ustring name; +}; +DECLARE_COMPONENT_LOADER("session", VariableSession, VariableLoader); + diff --git a/project2/variables-moduri.cpp b/project2/variables-moduri.cpp new file mode 100644 index 0000000..f6793e1 --- /dev/null +++ b/project2/variables-moduri.cpp @@ -0,0 +1,34 @@ +#include "variables.h" +#include "xmlObjectLoader.h" +#include "xmlStorage.h" +#include "appEngine.h" + +/// Variable implementation to access URI path fragments +class VariableUri : public VariableImplDyn { +	public: +		VariableUri(const xmlpp::Element * e) : +			VariableImplDyn(e), +			index(atoi(e->get_attribute_value("index").c_str())) +		{ +		} +		const VariableType & value() const +		{ +			if (!cacheValid) { +				try { +					cache = ApplicationEngine::getCurrent()->env()->getParamUri(index); +				} +				catch (UriElementOutOfRange) { +					if (!defaultValue) { +						throw; +					} +					cache = (*defaultValue)(); +				} +				cacheValid = true; +			} +			return cache; +		} +	private: +		unsigned int index; +}; +DECLARE_COMPONENT_LOADER("uri", VariableUri, VariableLoader); + diff --git a/project2/variables.cpp b/project2/variables.cpp index 969c17f..4e18fc0 100644 --- a/project2/variables.cpp +++ b/project2/variables.cpp @@ -1,5 +1,4 @@  #include "variables.h" -#include "logger.h"  #include "iHaveParameters.h"  #include "xmlObjectLoader.h"  #include "exceptions.h" @@ -7,7 +6,6 @@  #include "session.h"  #include "rowUser.h"  #include "rowSet.h" -#include "rowProcessor.h"  #include <libxml++/nodes/textnode.h>  #include <stdexcept>  #include <boost/tokenizer.hpp> @@ -121,115 +119,38 @@ class VariableLiteral : public VariableImpl {  			val(makeVariableType(src, format))  		{  		} - -		virtual const VariableType & value() const { return val; } -	private: -		VariableType val; -}; - -/// Base class for variables whose content is dynamic -class VariableImplDyn : public VariableImpl { -	public: -		VariableImplDyn(const xmlpp::Element * e) : -			cacheValid(false) +		VariableLiteral(const xmlpp::Element * c)  		{ -			try { -				if (e) { -					defaultValue = Variable(e, "default"); -				} +			if (const xmlpp::Attribute * la = c->get_attribute("value")) { +				val = makeVariableType(la->get_value(), getVariableTypeFromName(c->get_attribute_value("type")));  			} -			catch (NoVariableDefinition) { -				// That's cool... no default +			else if (const xmlpp::TextNode * t = c->get_child_text()) { +				val = makeVariableType(t->get_content(), getVariableTypeFromName(c->get_attribute_value("type")));  			} -		} -		virtual const VariableType & value() const = 0; - -	protected: -		mutable VariableType cache; -		mutable bool cacheValid; -		boost::optional<Variable> defaultValue; -}; - -/// Variable implementation to access session contents -class VariableSession : public VariableImplDyn { -	public: -		VariableSession(const xmlpp::Element * e) : -			VariableImplDyn(e), -			name(e->get_attribute_value("name")) -		{ -		} -		const VariableType & value() const -		{ -			try { -				cache = ApplicationEngine::getCurrent()->session()->GetValue(name); -			} -			catch (Session::VariableNotFound) { -				if (!defaultValue) { -					throw; -				} -				cache = (*defaultValue)(); +			else { +				val = VariableType();  			} -			return cache;  		} -	private: -		const Glib::ustring name; -}; -/// Variable implementation to access call parameters -class VariableParam : public VariableImplDyn { -	public: -		VariableParam(const xmlpp::Element * e) : -			VariableImplDyn(e), -			name(e->get_attribute_value("name")) -		{ -		} -		const VariableType & value() const -		{ -			if (!cacheValid) { -				try { -					cache = ApplicationEngine::getCurrent()->env()->getParamQuery(name); -				} -				catch (ParamNotFound) { -					if (!defaultValue) { -						throw; -					} -					cache = (*defaultValue)(); -				} -				cacheValid = true; -			} -			return cache; -		} +		virtual const VariableType & value() const { return val; }  	private: -		const Glib::ustring name; +		VariableType val;  }; +DECLARE_COMPONENT_LOADER("literal", VariableLiteral, VariableLoader); +DECLARE_CUSTOM_COMPONENT_LOADER("", VariableLiteralDef, VariableLoaderImpl<VariableLiteral>, VariableLoader); -/// Variable implementation to access URI path fragments -class VariableUri : public VariableImplDyn { -	public: -		VariableUri(const xmlpp::Element * e) : -			VariableImplDyn(e), -			index(atoi(e->get_attribute_value("index").c_str())) -		{ -		} -		const VariableType & value() const -		{ -			if (!cacheValid) { -				try { -					cache = ApplicationEngine::getCurrent()->env()->getParamUri(index); -				} -				catch (UriElementOutOfRange) { -					if (!defaultValue) { -						throw; -					} -					cache = (*defaultValue)(); -				} -				cacheValid = true; -			} -			return cache; +VariableImplDyn::VariableImplDyn(const xmlpp::Element * e) : +	cacheValid(false) +{ +	try { +		if (e) { +			defaultValue = Variable(e, "default");  		} -	private: -		unsigned int index; -}; +	} +	catch (NoVariableDefinition) { +		// That's cool... no default +	} +}  static void assignHelper(VariableType & dest, const VariableType & src) {  	dest = src; @@ -238,7 +159,7 @@ static void assignHelper(VariableType & dest, const VariableType & src) {  /// Variable implementation to access fields in row sets  class VariableParent : public VariableImplDyn, public RowUser {  	public: -		VariableParent(const xmlpp::Element * e, const RowUser * d) : +		VariableParent(const xmlpp::Element * e, const RowUser * d = NULL) :  			VariableImplDyn(e),  			row(NULL),  			depth(atoi(e->get_attribute_value("depth").c_str())), @@ -323,6 +244,7 @@ class VariableParent : public VariableImplDyn, public RowUser {  		const RowUser * dep;  		mutable boost::function2<void, VariableType &, ConstRowSetPtr> getValue;  }; +DECLARE_COMPONENT_LOADER("parent", VariableParent, VariableLoader);  /// Variable implementation which has some fixed value  class VariableFixed : public VariableImpl { @@ -339,128 +261,6 @@ class VariableFixed : public VariableImpl {  		VariableType var;  }; -/// Variable implementation to access platform configuration values -class VariableConfig : public VariableImplDyn { -	public: -		VariableConfig(const xmlpp::Element * e) : -			VariableImplDyn(e), -			name(e->get_attribute_value("name")) -		{ -		} -		const VariableType & value() const -		{ -			if (!cacheValid) { -				cache = ApplicationEngine::getCurrent()->getCurrentConfig()->getValue(name); -				cacheValid = true; -			} -			return cache; -		} -	private: -		const Glib::ustring name; -}; - -template <class S> -class compi : public boost::static_visitor<bool> { -	public: -		compi(const S & s) : _s(s) { } -		bool operator()(const S & t) const -		{ -			return _s < t; -		} -		template <class T> -		bool operator()(const T &) const -		{ -			// should never be called -			return false; -		} -	private: -		const S & _s; -}; - -class comp : public boost::static_visitor<bool> { -	public: -		comp(const VariableType & a) : _a(a) { } -		template <class T> -		bool operator()(const T & t) const -		{ -			return boost::apply_visitor(compi<T>(t), _a); -		} -	private: -		const VariableType & _a; -}; - -bool -operator<(const VariableType & a, const VariableType & b) -{ -	if (a.which() < b.which()) { -		return true; -	} -	if (a.which() == b.which()) { -		return boost::apply_visitor(comp(a), b); -	} -	return false; -} - -/// Variable implementation that looks up it's value in a map of key(s)/value pairs -class VariableLookup : public VariableImplDyn, public RowProcessor { -	private: -		typedef std::vector<VariableType> Key; -		typedef std::map<Key, VariableType> Map; -	public: -		class NotFound { }; -		VariableLookup(const xmlpp::Element * e) : -			VariableImplDyn(e), -			RowProcessor(e), -			name(e->get_attribute_value("name")) -		{ -			LoaderBase loader(true); -			loader.supportedStorers.insert(Storer::into(&rowSets)); -			loader.collectAll(e, false); -		} -		const VariableType & value() const -		{ -			if (map.empty()) { -				fillCache(); -			} -			Key k; -			k.reserve(parameters.size()); -			BOOST_FOREACH(const Parameters::value_type & p, parameters) { -				k.push_back(p.second->value()); -			} -			Map::const_iterator i = map.find(k); -			if (i != map.end()) { -				cache = i->second; -				return cache; -			} -			throw NotFound(); -		} -	private: -		void fillCache() const -		{ -			BOOST_FOREACH(const RowSets::value_type & rs, rowSets) { -				cs = rs; -				rs->execute(this); -			} -			cs.reset(); -			Logger()->messagef(LOG_DEBUG, "%s: %s has filled cached with %zu items", -					__PRETTY_FUNCTION__, name.c_str(), map.size()); -		} -		void rowReady() const -		{ -			Key k; -			k.reserve(cs->columnCount() - 1); -			BOOST_FOREACH(const Parameters::value_type & p, parameters) { -				k.push_back(cs->getCurrentValue(p.first)); -			} -			map[k] = cs->getCurrentValue(name); -		} -		mutable Map map; -		mutable RowSetPtr cs; -		typedef ANONSTORAGEOF(RowSet) RowSets; -		RowSets rowSets; -		const Glib::ustring name; -}; -  Variable::Variable(VariableType def) :  	var(new VariableFixed(def))  { @@ -477,32 +277,13 @@ Variable::Variable(const xmlpp::Element * e, const Glib::ustring & n, bool requi  	if (cs.size() == 1) {  		const xmlpp::Element * c = dynamic_cast<const xmlpp::Element *>(cs.front());  		if (c) { -			Glib::ustring source = c->get_attribute_value("source"); -			if (source == "session") -				var = new VariableSession(c); -			else if (source == "parent") -				var = new VariableParent(c, NULL); -			else if (source == "uri") -				var = new VariableUri(c); -			else if (source == "param") -				var = new VariableParam(c); -			else if (source == "config") -				var = new VariableConfig(c); -			else if (source == "lookup") -				var = new VariableLookup(c); -			else if (source == "literal" || source.empty()) { -				if (const xmlpp::Attribute * la = c->get_attribute("value")) { -					var = new VariableLiteral(la->get_value(), getVariableTypeFromName(c->get_attribute_value("type"))); -				} -				else if (const xmlpp::TextNode * t = c->get_child_text()) { -					var = new VariableLiteral(t->get_content(), getVariableTypeFromName(c->get_attribute_value("type"))); -				} -				else { -					var = new VariableLiteral(VariableType()); -				} +			xmlpp::Attribute * source = c->get_attribute("source"); +			if (source) { +				var = LoaderBase::getLoader<VariableLoader, UnknownVariableSource>(source->get_value())->create(c); +			} +			else { +				var = new VariableLiteral(c);  			} -			else -				throw UnknownVariableSource(source);  			return;  		}  	} diff --git a/project2/variables.h b/project2/variables.h index a6dfb05..92aac4b 100644 --- a/project2/variables.h +++ b/project2/variables.h @@ -9,6 +9,7 @@  #include <libxml++/nodes/element.h>  #include <libxml++/attribute.h>  #include "intrusivePtrBase.h" +#include "xmlObjectLoader.h"  #include <boost/variant.hpp>  #include <boost/shared_ptr.hpp> @@ -88,5 +89,32 @@ class Variable {  		VariableImplPtr var;  }; +/// Base class for variables whose content is dynamic +class VariableImplDyn : public VariableImpl { +	public: +		VariableImplDyn(const xmlpp::Element * e); +		virtual const VariableType & value() const = 0; + +	protected: +		mutable VariableType cache; +		mutable bool cacheValid; +		boost::optional<Variable> defaultValue; +}; + +/// Base class to create variables +class VariableLoader : public ComponentLoader { +	public: +		virtual VariableImpl * create(const xmlpp::Element *) 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 +		{ +			return new VarType(e); +		} +}; +  #endif  | 
