From 59513bee1e638f280d8411098cce9367c49596c4 Mon Sep 17 00:00:00 2001 From: randomdan Date: Fri, 20 Apr 2012 09:23:42 +0000 Subject: Add support for simple mutations of XML output (node rearrangement) --- project2/common/presenter.cpp | 5 +++++ project2/common/presenter.h | 1 + project2/common/viewHost.cpp | 1 + project2/xml/Jamfile.jam | 2 +- project2/xml/mutators/copy.cpp | 30 ++++++++++++++++++++++++++++++ project2/xml/mutators/copyToAttr.cpp | 35 +++++++++++++++++++++++++++++++++++ project2/xml/mutators/create.cpp | 22 ++++++++++++++++++++++ project2/xml/mutators/delete.cpp | 22 ++++++++++++++++++++++ project2/xml/mutators/rename.cpp | 25 +++++++++++++++++++++++++ project2/xml/xmlPresenter.cpp | 15 +++++++++++++++ project2/xml/xmlPresenter.h | 12 ++++++++++++ 11 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 project2/xml/mutators/copy.cpp create mode 100644 project2/xml/mutators/copyToAttr.cpp create mode 100644 project2/xml/mutators/create.cpp create mode 100644 project2/xml/mutators/delete.cpp create mode 100644 project2/xml/mutators/rename.cpp diff --git a/project2/common/presenter.cpp b/project2/common/presenter.cpp index b8fc545..becfb50 100644 --- a/project2/common/presenter.cpp +++ b/project2/common/presenter.cpp @@ -115,3 +115,8 @@ MultiRowSetPresenter::setNamespace(const Glib::ustring &, const Glib::ustring &) { } +void +MultiRowSetPresenter::finalizeContent() const +{ +} + diff --git a/project2/common/presenter.h b/project2/common/presenter.h index e1a78dd..ebcbe93 100644 --- a/project2/common/presenter.h +++ b/project2/common/presenter.h @@ -40,6 +40,7 @@ class MultiRowSetPresenter : public RowSetPresenter { virtual void addNewArray(const Glib::ustring & name, bool objects) const = 0; virtual void finishArray(bool objects) const = 0; virtual void init() = 0; + virtual void finalizeContent() const; }; class Presenter : public MultiRowSetPresenter { diff --git a/project2/common/viewHost.cpp b/project2/common/viewHost.cpp index cbae417..04e0d88 100644 --- a/project2/common/viewHost.cpp +++ b/project2/common/viewHost.cpp @@ -30,6 +30,7 @@ ViewHost::executeViews() const BOOST_FOREACH(const CommonObjects::DataSources::value_type & ds, CommonObjects::datasources) { ds.second->commit(); } + presenter->finalizeContent(); } void diff --git a/project2/xml/Jamfile.jam b/project2/xml/Jamfile.jam index 1e8fcf7..2adadaf 100644 --- a/project2/xml/Jamfile.jam +++ b/project2/xml/Jamfile.jam @@ -14,7 +14,7 @@ cpp-pch pch : pch.hpp : ; lib p2xml : pch - [ glob *.cpp ] + [ glob-tree *.cpp ] : ../libmisc libxmlpp diff --git a/project2/xml/mutators/copy.cpp b/project2/xml/mutators/copy.cpp new file mode 100644 index 0000000..d7170e6 --- /dev/null +++ b/project2/xml/mutators/copy.cpp @@ -0,0 +1,30 @@ +#include "../pch.hpp" +#include "../xmlPresenter.h" + +class Copy : public XmlDocMutator { + public: + Copy(ScriptNodePtr s) : + XmlDocMutator(s), + from(s, "fromxpath"), + to(s, "toxpath"), + delAfter(s, "delete", false) + { + } + void mutateElement(xmlpp::Element * root) const + { + BOOST_FOREACH(xmlpp::Node * e, root->find(from())) { + BOOST_FOREACH(xmlpp::Node * t, e->find(to())) { + t->import_node(e); + if (delAfter()) { + e->get_parent()->remove_child(e); + } + } + } + } + Variable from; + Variable to; + Variable delAfter; +}; + +DECLARE_GENERIC_LOADER("copy", XmlDocMutatorLoader, Copy); + diff --git a/project2/xml/mutators/copyToAttr.cpp b/project2/xml/mutators/copyToAttr.cpp new file mode 100644 index 0000000..c8b32d5 --- /dev/null +++ b/project2/xml/mutators/copyToAttr.cpp @@ -0,0 +1,35 @@ +#include "../pch.hpp" +#include "../xmlPresenter.h" + +class CopyToAttr : public XmlDocMutator { + public: + CopyToAttr(ScriptNodePtr s) : + XmlDocMutator(s), + from(s, "fromxpath"), + to(s, "toxpath"), + delAfter(s, "delete", false) + { + } + void mutateElement(xmlpp::Element * root) const + { + BOOST_FOREACH(xmlpp::Node * e, root->find(from())) { + if (xmlpp::Element * ee = dynamic_cast(e)) { + BOOST_FOREACH(xmlpp::Node * t, e->find(to())) { + if (xmlpp::Element * te = dynamic_cast(t)) { + te->set_attribute(e->get_name(), ee->get_child_text()->get_content()); + if (delAfter()) { + e->get_parent()->remove_child(e); + } + } + } + } + } + } + Variable from; + Variable to; + Variable delAfter; +}; + +DECLARE_GENERIC_LOADER("copytoattr", XmlDocMutatorLoader, CopyToAttr); + + diff --git a/project2/xml/mutators/create.cpp b/project2/xml/mutators/create.cpp new file mode 100644 index 0000000..812da24 --- /dev/null +++ b/project2/xml/mutators/create.cpp @@ -0,0 +1,22 @@ +#include "../pch.hpp" +#include "../xmlPresenter.h" + +class Create : public XmlDocMutator { + public: + Create(ScriptNodePtr s) : + XmlDocMutator(s), + xpath(s, "xpath"), + name(s, "name") + { + } + void mutateElement(xmlpp::Element * root) const + { + BOOST_FOREACH(xmlpp::Node * e, root->find(xpath())) { + e->add_child(name()); + } + } + Variable xpath; + Variable name; +}; + +DECLARE_GENERIC_LOADER("create", XmlDocMutatorLoader, Create); diff --git a/project2/xml/mutators/delete.cpp b/project2/xml/mutators/delete.cpp new file mode 100644 index 0000000..8cc3a94 --- /dev/null +++ b/project2/xml/mutators/delete.cpp @@ -0,0 +1,22 @@ +#include "../pch.hpp" +#include "../xmlPresenter.h" + +class Delete : public XmlDocMutator { + public: + Delete(ScriptNodePtr s) : + XmlDocMutator(s), + xpath(s, "xpath") + { + } + void mutateElement(xmlpp::Element * root) const + { + BOOST_FOREACH(xmlpp::Node * e, root->find(xpath())) { + e->get_parent()->remove_child(e); + } + } + Variable xpath; +}; + +DECLARE_GENERIC_LOADER("delete", XmlDocMutatorLoader, Delete); + + diff --git a/project2/xml/mutators/rename.cpp b/project2/xml/mutators/rename.cpp new file mode 100644 index 0000000..ceb7627 --- /dev/null +++ b/project2/xml/mutators/rename.cpp @@ -0,0 +1,25 @@ +#include "../pch.hpp" +#include "../xmlPresenter.h" + +class Rename : public XmlDocMutator { + public: + Rename(ScriptNodePtr s) : + XmlDocMutator(s), + xpath(s, "xpath"), + newname(s, "newname") + { + } + void mutateElement(xmlpp::Element * root) const + { + BOOST_FOREACH(xmlpp::Node * e, root->find(xpath())) { + e->set_name(newname()); + } + } + Variable xpath; + Variable newname; +}; + +DECLARE_GENERIC_LOADER("rename", XmlDocMutatorLoader, Rename); + + + diff --git a/project2/xml/xmlPresenter.cpp b/project2/xml/xmlPresenter.cpp index a6d6f40..1d77959 100644 --- a/project2/xml/xmlPresenter.cpp +++ b/project2/xml/xmlPresenter.cpp @@ -1,6 +1,7 @@ #include #include "xmlPresenter.h" #include "scriptLoader.h" +#include "scriptStorage.h" #include "variables.h" #include "appEngine.h" #include @@ -77,6 +78,7 @@ XmlPresenter::XmlPresenter(ScriptNodePtr e) : root(e, "root"), style(e, "style", Null()) { + e->script->loader.addLoadTarget(e, Storer::into(&mutators)); } XmlPresenter::~XmlPresenter() @@ -235,3 +237,16 @@ void XmlPresenter::writeTo(std::ostream & o, const std::string & enc) const { responseDoc->write_to_stream_formatted(o, enc); } + +void +XmlPresenter::finalizeContent() const +{ + BOOST_FOREACH(const XmlDocMutatorPtr & m, mutators) { + m->mutateElement(responseDoc->get_root_node()); + } +} + +XmlDocMutator::XmlDocMutator(ScriptNodePtr) +{ +} + diff --git a/project2/xml/xmlPresenter.h b/project2/xml/xmlPresenter.h index dc88fa9..e2e0b84 100644 --- a/project2/xml/xmlPresenter.h +++ b/project2/xml/xmlPresenter.h @@ -10,6 +10,14 @@ namespace xmlpp { class Element; } +class XmlDocMutator : public IntrusivePtrBase { + public: + XmlDocMutator(ScriptNodePtr); + virtual void mutateElement(xmlpp::Element *) const = 0; +}; +typedef boost::intrusive_ptr XmlDocMutatorPtr; +typedef GenLoader XmlDocMutatorLoader; + class XmlPresenter : public Presenter, public ContentPresenter, public SourceOf, public SourceOf, public SourceOf >, public WritableContent, public SourceOf { public: typedef boost::shared_ptr XmlDocumentPtr; @@ -33,6 +41,7 @@ class XmlPresenter : public Presenter, public ContentPresenter, public SourceOf< Class getContentClass() const; Glib::ustring getContentType() const; void writeTo(std::ostream &, const std::string & enc) const; + void finalizeContent() const; void init(); private: @@ -41,6 +50,9 @@ class XmlPresenter : public Presenter, public ContentPresenter, public SourceOf< mutable std::vector nodeStack; const Variable root; const Variable style; + + typedef ANONORDEREDSTORAGEOF(XmlDocMutator) Mutators; + Mutators mutators; }; typedef boost::intrusive_ptr XmlPresenterPtr; -- cgit v1.2.3