From 2fef4cd9ce9ce3402ca78e49265f9bac61de9f0f Mon Sep 17 00:00:00 2001 From: randomdan Date: Fri, 17 Feb 2012 19:44:04 +0000 Subject: Finer control over output to presenters, addresses issues with JSON output and makes some other bits more sensible Tweaks to XSLT as some things have moved --- project2/cgi/cgiAppEngine.cpp | 16 +++++----------- project2/common/appEngine.cpp | 2 ++ project2/common/presenter.h | 2 ++ project2/common/rowView.cpp | 11 +++++++---- project2/console/consolePresenter.cpp | 11 +++++++++++ project2/console/consolePresenter.h | 2 ++ project2/json/presenter.cpp | 31 +++++++++++++++++++++++-------- project2/xml/xmlPresenter.cpp | 16 ++++++++++++++++ project2/xml/xmlPresenter.h | 2 ++ 9 files changed, 70 insertions(+), 23 deletions(-) diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp index d062d87..be42af9 100644 --- a/project2/cgi/cgiAppEngine.cpp +++ b/project2/cgi/cgiAppEngine.cpp @@ -196,11 +196,11 @@ CgiApplicationEngine::addEnvData(const MultiRowSetPresenter * p, OutputOptionsPt // URL elements p->addNewRowSet("uriElems", env()->scriptNamespacePrefix); p->addAttribute("full", _env->getRedirectURL()); + p->addNewArray("uriElem", true); BOOST_FOREACH(std::string s, _env->elems) { - p->addNewRow("uriElem"); - p->addAttribute("text", s); - p->finishRow(); + p->addNamedValue("uriElem", s); } + p->finishArray(true); p->finishRowSet(); } @@ -208,10 +208,7 @@ CgiApplicationEngine::addEnvData(const MultiRowSetPresenter * p, OutputOptionsPt // Parameters p->addNewRowSet("params", env()->scriptNamespacePrefix); BOOST_FOREACH(cgicc::FormEntry fe, _env->cgi->getElements()) { - p->addNewRow("param"); - p->addAttribute("name", fe.getName()); - p->addAttribute("value", fe.getValue()); - p->finishRow(); + p->addNamedValue(fe.getName(), fe.getValue()); } p->finishRowSet(); } @@ -220,10 +217,7 @@ CgiApplicationEngine::addEnvData(const MultiRowSetPresenter * p, OutputOptionsPt void CgiApplicationEngine::addVarToPresenter(const MultiRowSetPresenter * p, const Glib::ustring & name, const VariableType & value) const { - p->addNewRow("var"); - p->addAttribute("name", name); - p->addAttribute("value", value); - p->finishRow(); + p->addNamedValue(name, value); } void diff --git a/project2/common/appEngine.cpp b/project2/common/appEngine.cpp index b5db2cf..4d0e9bc 100644 --- a/project2/common/appEngine.cpp +++ b/project2/common/appEngine.cpp @@ -34,12 +34,14 @@ ApplicationEngine::addCoreAppData(const MultiRowSetPresenter * p) const { // Message log p->addNewRowSet("messages", env()->scriptNamespacePrefix); + p->addNewArray("message", true); BOOST_FOREACH(const Messages::value_type & m, appMessages) { p->addNewRow("message"); p->addAttribute("group", m->group); p->addAttribute("text", m->message); p->finishRow(); } + p->finishArray(true); p->finishRowSet(); } diff --git a/project2/common/presenter.h b/project2/common/presenter.h index eaba17f..662af22 100644 --- a/project2/common/presenter.h +++ b/project2/common/presenter.h @@ -37,6 +37,8 @@ class MultiRowSetPresenter : public RowSetPresenter { virtual void addNewRowSet(const Glib::ustring & name) const = 0; virtual void addNewRowSet(const Glib::ustring & name, const Glib::ustring & ns) const = 0; virtual void finishRowSet() const = 0; + virtual void addNewArray(const Glib::ustring & name, bool objects) const = 0; + virtual void finishArray(bool objects) const = 0; }; class Presenter : public MultiRowSetPresenter { diff --git a/project2/common/rowView.cpp b/project2/common/rowView.cpp index 749651e..e02ee23 100644 --- a/project2/common/rowView.cpp +++ b/project2/common/rowView.cpp @@ -61,13 +61,16 @@ RowView::execute(const MultiRowSetPresenter * p) const { presenter = p; presenter->addNewRowSet(rootName()); - ScopeObject pres(boost::bind(&MultiRowSetPresenter::finishRowSet, p)); - RowProcessor::execute(); + { + presenter->addNewArray(recordName(), true); + ScopeObject pres(boost::bind(&MultiRowSetPresenter::finishArray, p, true)); + RowProcessor::execute(); + } BOOST_FOREACH(SetAggregateCPtr s, setAggregates) { - presenter->addNewRowSet(s->name); - ScopeObject pres(boost::bind(&MultiRowSetPresenter::finishRowSet, p)); + presenter->addNewArray(s->name, false); + ScopeObject pres(boost::bind(&MultiRowSetPresenter::finishArray, p, false)); s->onResultValues(boost::bind(&MultiRowSetPresenter::addNamedValue, p, "value", _1)); s->reset(); } diff --git a/project2/console/consolePresenter.cpp b/project2/console/consolePresenter.cpp index 3a8bf11..3979c4e 100644 --- a/project2/console/consolePresenter.cpp +++ b/project2/console/consolePresenter.cpp @@ -59,4 +59,15 @@ ConsolePresenter::popSub() const fprintf(stdout, "%*s<<<\n", indent, ""); } +void +ConsolePresenter::addNewArray(const Glib::ustring & name, bool) const +{ + pushSub(name, ""); +} + +void +ConsolePresenter::finishArray(bool) const +{ + popSub(); +} diff --git a/project2/console/consolePresenter.h b/project2/console/consolePresenter.h index 2a67727..0540248 100644 --- a/project2/console/consolePresenter.h +++ b/project2/console/consolePresenter.h @@ -12,6 +12,8 @@ class ConsolePresenter : public Presenter { void addNamedValue(const Glib::ustring & name, const Glib::ustring & ns, const VariableType & value) const; void addText(const VariableType & value) const; void popSub() const; + void addNewArray(const Glib::ustring&, bool objects) const; + void finishArray(bool objects) const; void write(const boost::function1 &) const; private: mutable unsigned int indent; diff --git a/project2/json/presenter.cpp b/project2/json/presenter.cpp index f50c322..00ed334 100644 --- a/project2/json/presenter.cpp +++ b/project2/json/presenter.cpp @@ -13,36 +13,51 @@ class JsonPresenter : public MultiRowSetPresenter, public ContentPresenter, publ SourceOf(s), SourceOf(s) { curRowSet.push(&object); + vaStack.push(&JsonPresenter::addValueToObject); } + typedef void (JsonPresenter::*ValueAdder)(const Glib::ustring &, const VariableType &) const; + typedef std::stack ValueAdderStack; + mutable ValueAdderStack vaStack; void addNamedValue(const Glib::ustring & name, const VariableType & value) const { + (this->*vaStack.top())(name, value); + } + void addValueToObject(const Glib::ustring & name, const VariableType & value) const { (*curRowSet.top())[name] = json::ValuePtr(new json::Value(boost::apply_visitor(Project2ToJson(), value))); } - void addNewRow(const Glib::ustring & name) const { - if (!curRowArray.top()) { - json::Value * v = new json::Value(json::Array()); - curRowArray.top() = boost::get(v); - (*curRowSet.top())[name] = json::ValuePtr(v); - } + void addValueToArray(const Glib::ustring &, const VariableType & value) const { + curRowArray.top()->push_back(json::ValuePtr(new json::Value(boost::apply_visitor(Project2ToJson(), value)))); + } + void addNewRow(const Glib::ustring &) const { json::Value * v = new json::Value(json::Object()); curRowSet.push(boost::get(v)); curRowArray.top()->push_back(json::ValuePtr(v)); + vaStack.push(&JsonPresenter::addValueToObject); } void finishRow() const { + vaStack.pop(); curRowSet.pop(); } void addNewRowSet(const Glib::ustring & name) const { json::Value * v = new json::Value(json::Object()); (*curRowSet.top())[name] = json::ValuePtr(v); curRowSet.push(boost::get(v)); - curRowArray.push(NULL); } void addNewRowSet(const Glib::ustring & name, const Glib::ustring & ns) const { addNewRowSet(ns + ":" + name); } void finishRowSet() const { - curRowArray.pop(); curRowSet.pop(); } + void addNewArray(const Glib::ustring & name, bool) const { + json::Value * v = new json::Value(json::Array()); + curRowArray.push(boost::get(v)); + (*curRowSet.top())[name] = json::ValuePtr(v); + vaStack.push(&JsonPresenter::addValueToArray); + } + void finishArray(bool) const { + vaStack.pop(); + curRowArray.pop(); + } operator const json::Object *() const { return &object; } diff --git a/project2/xml/xmlPresenter.cpp b/project2/xml/xmlPresenter.cpp index bde649d..ba20eb2 100644 --- a/project2/xml/xmlPresenter.cpp +++ b/project2/xml/xmlPresenter.cpp @@ -146,6 +146,22 @@ XmlPresenter::popSub() const nodeStack.pop_back(); } +void +XmlPresenter::addNewArray(const Glib::ustring & name, bool objects) const +{ + if (!objects) { + nodeStack.push_back(nodeStack.back()->add_child(name)); + } +} + +void +XmlPresenter::finishArray(bool objects) const +{ + if (!objects) { + popSub(); + } +} + Glib::ustring XmlPresenter::getContentType() const { return contentType; diff --git a/project2/xml/xmlPresenter.h b/project2/xml/xmlPresenter.h index a7fbb11..1c4391a 100644 --- a/project2/xml/xmlPresenter.h +++ b/project2/xml/xmlPresenter.h @@ -23,6 +23,8 @@ class XmlPresenter : public Presenter, public ContentPresenter, public SourceOf< void addAttribute(const Glib::ustring & name, const Glib::ustring & ns, const VariableType & value) const; void addText(const VariableType & value) const; void popSub() const; + void addNewArray(const Glib::ustring&, bool objects) const; + void finishArray(bool objects) const; operator const xmlpp::Document * () const; operator const xmlDoc * () const; -- cgit v1.2.3