summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2011-12-27 14:52:27 +0000
committerrandomdan <randomdan@localhost>2011-12-27 14:52:27 +0000
commitd3c6af11a145cee0fb28fa40c749c315e8f8c072 (patch)
tree96f024bef38e793c2b8a37264c7c55684341fdd1
parentFix cut point in fsRows since fixes to fsRoot were made (diff)
downloadproject2-d3c6af11a145cee0fb28fa40c749c315e8f8c072.tar.bz2
project2-d3c6af11a145cee0fb28fa40c749c315e8f8c072.tar.xz
project2-d3c6af11a145cee0fb28fa40c749c315e8f8c072.zip
Add type safety to XML documents
Includes minor fixes around date serialisation and parsing
-rw-r--r--project2/cgi/cgiAppEngine.cpp4
-rw-r--r--project2/common/cache.cpp9
-rw-r--r--project2/common/functions/dates.cpp7
-rw-r--r--project2/common/variables.cpp18
-rw-r--r--project2/common/variables.h1
-rw-r--r--project2/xml/xmlCache.cpp2
-rw-r--r--project2/xml/xmlPresenter.cpp45
-rw-r--r--project2/xml/xmlRawRows.cpp3
8 files changed, 74 insertions, 15 deletions
diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp
index f94597c..8d079f9 100644
--- a/project2/cgi/cgiAppEngine.cpp
+++ b/project2/cgi/cgiAppEngine.cpp
@@ -95,7 +95,9 @@ CgiApplicationEngine::process() const
std::fstream * ddd = NULL;
if (!_env->dumpdatadoc.empty()) {
ddd = new std::fstream(_env->dumpdatadoc.c_str(), std::fstream::trunc | std::fstream::out);
- ts->addTarget(new ostreamWrapper(*ddd));
+ if (ddd->good()) {
+ ts->addTarget(new ostreamWrapper(*ddd));
+ }
}
ts->addTarget(new ostreamWrapper(IO));
ts->doTransforms();
diff --git a/project2/common/cache.cpp b/project2/common/cache.cpp
index f5edc43..ff9f41f 100644
--- a/project2/common/cache.cpp
+++ b/project2/common/cache.cpp
@@ -4,6 +4,7 @@
#include "rowProcessor.h"
#include "logger.h"
#include <boost/foreach.hpp>
+#include <glibmm/exception.h>
Cache::Cache(ScriptNodePtr p) :
IHaveParameters(p),
@@ -21,8 +22,14 @@ bool Cache::checkAndExecute(const Glib::ustring & n, const Glib::ustring & f, co
cached->execute(f, rp);
return true;
}
+ catch (const Glib::Exception & e) {
+ Logger()->messagef(LOG_WARNING, "Cache failed (%s)", e.what().c_str());
+ }
+ catch (const std::exception & e) {
+ Logger()->messagef(LOG_WARNING, "Cache failed (%s)", e.what());
+ }
catch (...) {
- Logger()->messagef(LOG_WARNING, "Cache failed");
+ Logger()->message(LOG_WARNING, "Cache failed");
}
}
return false;
diff --git a/project2/common/functions/dates.cpp b/project2/common/functions/dates.cpp
index c1992f7..7ace436 100644
--- a/project2/common/functions/dates.cpp
+++ b/project2/common/functions/dates.cpp
@@ -7,7 +7,7 @@
#include <iostream>
#include <boost/date_time.hpp>
-class ParseError { };
+SimpleMessage2Exception(DateParseError);
/// Variable implementation to access platform configuration values
class ParseDate : public VariableImplDyn {
public:
@@ -21,15 +21,14 @@ class ParseDate : public VariableImplDyn {
{
const char * s = string();
const char * f = format();
- boost::posix_time::ptime t;
struct tm tm;
memset(&tm, 0, sizeof(struct tm));
mktime(&tm);
const char * e = strptime(s, f, &tm);
- if (!e) {
+ if (!e || *e) {
Logger()->messagef(LOG_ERR, "%s: check failed (parse) for '%s' against '%s' (remaining chars='%s')",
__PRETTY_FUNCTION__, s, f, e);
- throw ParseError();
+ throw DateParseError(string(), format());
}
return boost::posix_time::ptime(boost::posix_time::ptime_from_tm(tm));
}
diff --git a/project2/common/variables.cpp b/project2/common/variables.cpp
index 4dc4538..6b2d7c9 100644
--- a/project2/common/variables.cpp
+++ b/project2/common/variables.cpp
@@ -1,4 +1,5 @@
#include <pch.hpp>
+#include "logger.h"
#include "variables.h"
#include "variables-modfixed.h"
#include "iHaveParameters.h"
@@ -57,6 +58,7 @@ VariableType::getTypeFromName(const std::string & src)
{
if (src.empty()) return String;
if (src == "string") return String;
+ if (src == "bool") return Bool;
if (src == "int") return Int;
if (src == "float") return Float;
if (src == "datetime") return DateTime;
@@ -64,6 +66,7 @@ VariableType::getTypeFromName(const std::string & src)
throw UnknownVariableType(src);
}
+SimpleMessageException(DateParseError);
VariableType
VariableType::make(const Glib::ustring & src, const VT_typeID format)
{
@@ -72,12 +75,25 @@ VariableType::make(const Glib::ustring & src, const VT_typeID format)
case DefaultType:
case String:
return src;
+ case Bool:
+ return boost::lexical_cast<bool>(src);
case Int:
return boost::lexical_cast<int64_t>(src);
case Float:
return boost::lexical_cast<double>(src);
case DateTime:
- return boost::posix_time::time_from_string(src);
+ {
+ struct tm tm;
+ memset(&tm, 0, sizeof(struct tm));
+ mktime(&tm);
+ const char * e = strptime(src.c_str(), "%FT%T", &tm);
+ if (!e || *e) {
+ Logger()->messagef(LOG_ERR, "%s: check failed (parse) for '%s' against '%s' (remaining chars='%s')",
+ __PRETTY_FUNCTION__, src.c_str(), "%FT%T", e);
+ throw DateParseError(src);
+ }
+ return boost::posix_time::ptime_from_tm(tm);
+ }
case Nul:
return Null();
}
diff --git a/project2/common/variables.h b/project2/common/variables.h
index a52e2b1..2c1f15d 100644
--- a/project2/common/variables.h
+++ b/project2/common/variables.h
@@ -17,6 +17,7 @@ enum VT_typeID {
DefaultType,
Nul,
String,
+ Bool,
Int,
Float,
DateTime,
diff --git a/project2/xml/xmlCache.cpp b/project2/xml/xmlCache.cpp
index 5233928..0ec745b 100644
--- a/project2/xml/xmlCache.cpp
+++ b/project2/xml/xmlCache.cpp
@@ -35,7 +35,7 @@ class XmlCache : public Cache {
RowSetPresenterPtr openFor(const Glib::ustring & n, const Glib::ustring &, const IHaveParameters *)
{
- writeTo = new XmlPresenter(n, Glib::ustring(), Glib::ustring());
+ writeTo = new XmlPresenter(n, Environment::getCurrent()->scriptNamespace, Environment::getCurrent()->scriptNamespacePrefix);
return writeTo;
}
diff --git a/project2/xml/xmlPresenter.cpp b/project2/xml/xmlPresenter.cpp
index 9d9f0fd..70cb743 100644
--- a/project2/xml/xmlPresenter.cpp
+++ b/project2/xml/xmlPresenter.cpp
@@ -84,16 +84,49 @@ XmlPresenter::addAttribute(const Glib::ustring & name, const Glib::ustring & ns,
}
}
+class XmlNodeWriter : public boost::static_visitor<bool> {
+ public:
+ XmlNodeWriter(xmlpp::Element * n) : node(n) { }
+ bool operator()(const Null &) const {
+ addType("null");
+ return false;
+ }
+ bool operator()(const Boolean &) const {
+ addType("bool");
+ return true;
+ }
+ bool operator()(const Glib::ustring &) const {
+ addType("string");
+ return true;
+ }
+ bool operator()(const int64_t &) const {
+ addType("int");
+ return true;
+ }
+ bool operator()(const double &) const {
+ addType("float");
+ return true;
+ }
+ bool operator()(const boost::posix_time::ptime & i) const {
+ addType("datetime");
+ node->set_attribute("time", boost::posix_time::to_simple_string(i.time_of_day()));
+ node->set_attribute("date", boost::gregorian::to_iso_extended_string(i.date()));
+ return true;
+ }
+
+ protected:
+ void addType(const char * type) const {
+ node->set_attribute("type", type, Environment::getCurrent()->scriptNamespacePrefix);
+ }
+ private:
+ xmlpp::Element * node;
+};
+
void
XmlPresenter::addText(const VariableType & value) const
{
- if (!value.get<Null>()) {
+ if (boost::apply_visitor(XmlNodeWriter(nodeStack.back()), value)) {
nodeStack.back()->add_child_text(value);
- // Special cases
- if (const boost::posix_time::ptime * dt = value.get<boost::posix_time::ptime>()) {
- nodeStack.back()->set_attribute("time", boost::posix_time::to_simple_string(dt->time_of_day()));
- nodeStack.back()->set_attribute("date", boost::gregorian::to_iso_extended_string(dt->date()));
- }
}
}
diff --git a/project2/xml/xmlRawRows.cpp b/project2/xml/xmlRawRows.cpp
index faca679..af550bb 100644
--- a/project2/xml/xmlRawRows.cpp
+++ b/project2/xml/xmlRawRows.cpp
@@ -71,7 +71,8 @@ void XmlRawRowsBase::execute(const xmlpp::Document * doc, const RowProcessor * r
if (const xmlpp::Element * ie = dynamic_cast<const xmlpp::Element *>(in)) {
const xmlpp::TextNode * t = ie->get_child_text();
if (t) {
- rs.fields[col] = t->get_content();
+ rs.fields[col] = VariableType::make(t->get_content(),
+ VariableType::getTypeFromName(ie->get_attribute_value("type", Environment::getCurrent()->scriptNamespacePrefix)));
}
col++;
}