diff options
Diffstat (limited to 'project2/sessionXml.cpp')
-rw-r--r-- | project2/sessionXml.cpp | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/project2/sessionXml.cpp b/project2/sessionXml.cpp new file mode 100644 index 0000000..68e19ea --- /dev/null +++ b/project2/sessionXml.cpp @@ -0,0 +1,171 @@ +#include "sessionXml.h" +#include <libxml++/nodes/element.h> +#include <libxml++/parsers/domparser.h> +#include <libxml++/nodes/textnode.h> +#include <set> +#include <boost/uuid/uuid.hpp> +#include <boost/foreach.hpp> +#include <boost/uuid/uuid_generators.hpp> +#include <boost/lexical_cast.hpp> +#include <boost/uuid/uuid_io.hpp> + +using namespace boost::uuids; +class SessionXml : public Session { + public: + SessionXml(boost::uuids::uuid & sid); + SessionXml(const xmlpp::Element *); + virtual ~SessionXml(); + + Glib::ustring GetValue(const Glib::ustring & name) const; + Values GetValuesCopy() const; + void SetValue(const Glib::ustring & name, const Glib::ustring & value); + void ClearValue(const Glib::ustring & name); + time_t ExpiryTime() const; + void ExpiryTime(time_t); + + const uuid sessionID; + + private: + Values vars; + time_t expires; + + friend class SessionContainerXml; +}; +typedef boost::intrusive_ptr<SessionXml> SessionXmlPtr; + + +const char * xmlFile = "/tmp/project2sessions.xml"; +SessionXmlPtr currentSession; + +SessionContainerXml::SessionContainerXml() +{ +} + +SessionContainerXml::~SessionContainerXml() +{ + CleanUp(); +} + +void +SessionContainerXml::CleanUp() +{ + if (currentSession) { + xmlpp::DomParser parser; + xmlpp::Document * doc; + try { + parser.parse_file(xmlFile); + doc = parser.get_document(); + char xpath[200]; + snprintf(xpath, 200, "/sessions/session[@id='%s' or @expires < %lu]", + boost::lexical_cast<std::string>(currentSession->sessionID).c_str(), time(NULL)); + xmlpp::NodeSet sess = doc->get_root_node()->find(xpath); + BOOST_FOREACH(xmlpp::Node * n, sess) { + n->get_parent()->remove_child(n); + } + } + catch (...) { + doc = new xmlpp::Document(); + doc->create_root_node("sessions"); + } + xmlpp::Element * sess = doc->get_root_node()->add_child("session"); + sess->set_attribute("id", boost::lexical_cast<Glib::ustring>(currentSession->sessionID)); + sess->set_attribute("expires", boost::lexical_cast<Glib::ustring>(currentSession->expires)); + BOOST_FOREACH(const SessionXml::Values::value_type & nvp, currentSession->vars) { + xmlpp::Element * v = sess->add_child("var"); + v->add_child_text(nvp.second); + v->set_attribute("name", nvp.first); + } + doc->write_to_file(xmlFile); + if (!parser) { + delete doc; + } + currentSession = NULL; + } +} + +SessionPtr +SessionContainerXml::getSession(boost::uuids::uuid & sid) +{ + if (!currentSession || currentSession->sessionID != sid) { + try { + xmlpp::DomParser sessions(xmlFile); + char xpath[200]; + snprintf(xpath, 200, "/sessions/session[@id='%s' and @expires > %lu]", + boost::lexical_cast<std::string>(sid).c_str(), time(NULL)); + xmlpp::NodeSet sess = sessions.get_document()->get_root_node()->find(xpath); + if (sess.size() == 1) { + currentSession = new SessionXml(dynamic_cast<const xmlpp::Element *>(sess[0])); + } + else { + currentSession = new SessionXml(sid); + } + } + catch (...) { + currentSession = new SessionXml(sid); + } + } + return currentSession; +} + +SessionXml::SessionXml(boost::uuids::uuid & sid) : + sessionID(sid.is_nil() ? sid = boost::uuids::random_generator()() : sid) +{ +} + +SessionXml::SessionXml(const xmlpp::Element * p) : + sessionID(boost::lexical_cast<uuid>(p->get_attribute_value("id"))), + expires(boost::lexical_cast<time_t>(p->get_attribute_value("expires"))) +{ + xmlpp::NodeSet xvars = p->find("var"); + BOOST_FOREACH(const xmlpp::Node * n, xvars) { + const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n); + if (e) { + vars[e->get_attribute_value("name")] = e->get_child_text()->get_content(); + } + } +} + +SessionXml::~SessionXml() +{ +} + +void +SessionXml::ExpiryTime(time_t t) +{ + expires = t; +} + +time_t +SessionXml::ExpiryTime() const +{ + return expires; +} + +Glib::ustring +SessionXml::GetValue(const Glib::ustring & name) const +{ + Values::const_iterator i = vars.find(name); + if (i == vars.end()) { + throw Session::VariableNotFound(); + } + return i->second; +} + +void +SessionXml::SetValue(const Glib::ustring & name, const Glib::ustring & value) +{ + vars[name] = value; +} + +void +SessionXml::ClearValue(const Glib::ustring & name) +{ + vars.erase(name); +} + +Session::Values +SessionXml::GetValuesCopy() const +{ + return vars; +} + |