Group.hpp
HttpConnection.hpp
JsonFormatter.hpp
+ Study.hpp
+ StudyService.hpp
User.hpp
UserService.hpp
)
GDESession.cpp
HttpConnection.cpp
JsonFormatter.cpp
+ StudyService.cpp
UserService.cpp
)
#include "GDESession.hpp"
#include "UserService.hpp"
+#include "StudyService.hpp"
std::string
gde::GDESession::getServiceURI(const std::string& serviceName) const
return uri;
}
+/* UserService */
+
const gde::User
gde::GDESession::createUser(const std::string& name, const std::string& password)
{
{
return gde::UserService(*this).removeFromGroup(group, user);
}
+
+/* StudyService */
+
+const gde::Study
+gde::GDESession::createStudy(const std::string& name)
+{
+ return gde::StudyService(*this).createStudy(name);
+}
+
+bool
+gde::GDESession::deleteStudy(const gde::Study& study)
+{
+ return gde::StudyService(*this).deleteStudy(study);
+}
+
+bool
+gde::GDESession::setStudyState(const gde::Study& study, int lock)
+{
+ return gde::StudyService(*this).setStudyState(study, lock);
+}
+
+const gde::Study
+gde::GDESession::readStudy(int studyId)
+{
+ return gde::StudyService(*this).readStudy(studyId);
+}
#ifndef GDE_SESSION_HPP
#define GDE_SESSION_HPP
+#include "Credentials.hpp"
#include "User.hpp"
#include "Group.hpp"
-#include "Credentials.hpp"
+#include "Study.hpp"
#include <string>
std::string getServiceURI(const std::string& serviceName) const;
+ /* UserService */
+
const User createUser(const std::string& name, const std::string& password);
bool deleteUser(const User&);
const User findUser(const std::string& name);
bool addToGroup(const Group&, const User&);
bool removeFromGroup(const Group&, const User&);
+ /* StudyService */
+
+ const Study createStudy(const std::string& name);
+ bool deleteStudy(const Study&);
+
+ bool setStudyState(const Study&, int);
+ const Study readStudy(int);
+
private:
std::string _serverAddress;
Credentials _credentials;
#include "JsonFormatter.hpp"
#include <Poco/JSON/Parser.h>
+#include <Poco/DateTime.h>
+#include <Poco/DateTimeParser.h>
#include <sstream>
}
}
+Poco::Timestamp
+gde::JsonFormatter::extract(Poco::JSON::Object::Ptr object, const std::string& varName)
+{
+ try {
+ Poco::Dynamic::Var v = object->get(varName);
+ std::string formattedDate = v.convert<std::string>();
+
+ Poco::DateTime dt;
+ int tzd;
+ Poco::DateTimeParser::parse(formattedDate, dt, tzd);
+ return dt.timestamp();
+ } catch (Poco::InvalidAccessException& e) {
+ // This exception is raised if Var v is empty
+ return Poco::Timestamp(); // Return current time; not so good, should return nil object
+ }
+}
+
std::string
gde::JsonFormatter::stringify(const Poco::JSON::Object& object) {
std::ostringstream jsonStream;
}
// Declare methods for the supported template type parameters
-template int gde::JsonFormatter::extract<int>(Poco::JSON::Object::Ptr object, const std::string& varName);
-template std::string gde::JsonFormatter::extract<std::string>(Poco::JSON::Object::Ptr object, const std::string& varName);
+template int gde::JsonFormatter::extract<int>(Poco::JSON::Object::Ptr, const std::string&);
+template bool gde::JsonFormatter::extract<bool>(Poco::JSON::Object::Ptr, const std::string&);
+template std::string gde::JsonFormatter::extract<std::string>(Poco::JSON::Object::Ptr, const std::string&);
-#ifndef JSON_FORMATTER_HPP
-#define JSON_FORMATTER_HPP
+#ifndef GDE_JSON_FORMATTER_HPP
+#define GDE_JSON_FORMATTER_HPP
#include <string>
#include <Poco/JSON/Object.h>
+#include <Poco/Timestamp.h>
namespace gde {
public:
static Poco::JSON::Object::Ptr parse(const std::string&);
+
template <typename T> static T extract(Poco::JSON::Object::Ptr, const std::string&);
+ static Poco::Timestamp extract(Poco::JSON::Object::Ptr, const std::string&);
static std::string stringify(const Poco::JSON::Object&);
};
--- /dev/null
+#ifndef GDE_STUDY_HPP
+#define GDE_STUDY_HPP
+
+#include <Poco/Timestamp.h>
+
+#include <string>
+
+namespace gde {
+
+ class Study {
+ friend class StudyService;
+ friend class GDESession;
+
+ public:
+ ~Study() {}
+
+ inline int getId() const { return _id; }
+ inline void setId(int id) { this->_id = id; }
+
+ inline std::string getName() const { return _name; }
+ inline void setName(const std::string& name) { this->_name = name; }
+
+ inline Poco::Timestamp getCreationDate() const { return _creationDate; }
+ inline void setCreationDate(const Poco::Timestamp& creationDate) { this->_creationDate = creationDate; }
+
+ inline Poco::Timestamp getUpdateDate() const { return _updateDate; }
+ inline void setUpdateDate(const Poco::Timestamp& updateDate) { this->_updateDate = updateDate; }
+
+ inline bool getValid() const { return _valid; }
+ inline void setValid(bool valid) { this->_valid = valid; }
+
+ inline bool getDeleted() const { return _deleted; }
+ inline void setDeleted(bool deleted) { this->_deleted = deleted; }
+
+ inline Poco::Timestamp getDeletionDate() const { return _deletionDate; }
+ inline void setDeletionDate(const Poco::Timestamp& deletionDate) { this->_deletionDate = deletionDate; }
+
+ inline int getAttributeGroupId() const { return _attributeGroupId; }
+ inline void setAttributeGroupId(int attributeGroupId) { this->_attributeGroupId = attributeGroupId; }
+
+ inline int getProfileId() const { return _profileId; }
+ inline void setProfileId(int profileId) { this->_profileId = profileId; }
+
+ inline bool getLocked() const { return _locked; }
+ inline void setLocked(bool locked) { this->_locked = locked; }
+
+ inline int getLockOwner() const { return _lockOwner; }
+ inline void setLockOwner(int lockOwner) { this->_lockOwner = lockOwner; }
+
+ private:
+ Study(int id=-1,
+ const std::string& name="",
+ const Poco::Timestamp& creationDate=Poco::Timestamp(),
+ const Poco::Timestamp& updateDate=Poco::Timestamp(),
+ bool valid = false,
+ bool deleted = false,
+ const Poco::Timestamp& deletionDate=Poco::Timestamp(),
+ int attributeGroupId=-1,
+ int profileId=-1,
+ bool locked = false,
+ int lockOwner=-1
+ )
+ : _id(id), _name(name), _creationDate(creationDate), _updateDate(updateDate), _valid(valid), _deleted(deleted), _deletionDate(deletionDate), _attributeGroupId(attributeGroupId), _profileId(profileId), _locked(locked), _lockOwner(lockOwner)
+ {}
+ Study(const Study&); // non copyable
+ Study& operator=(const Study&); // non copyable
+
+ private:
+ int _id;
+ std::string _name;
+ Poco::Timestamp _creationDate;
+ Poco::Timestamp _updateDate;
+ bool _valid;
+ bool _deleted;
+ Poco::Timestamp _deletionDate;
+ int _attributeGroupId;
+ int _profileId;
+ bool _locked;
+ int _lockOwner;
+ };
+
+};
+
+#endif
--- /dev/null
+#include "StudyService.hpp"
+#include "HttpConnection.hpp"
+#include "CommandTO.hpp"
+#include "CommandResultTO.hpp"
+#include "JsonFormatter.hpp"
+#include "Credentials.hpp"
+
+#include <Poco/DateTimeFormatter.h>
+#include <Poco/Timestamp.h>
+#include <Poco/DateTimeFormat.h>
+
+/*
+ * WARNING: keep enum values synchronized to WEB API (StudyService)
+ */
+enum {
+ CREATE_STUDY = 1,
+ SET_STUDY_SATE,
+ READ_STUDY,
+ DELETE_STUDY
+};
+
+std::string gde::StudyService::_servletName = "StudyService";
+
+const gde::Study
+gde::StudyService::createStudy(const std::string& name)
+{
+ // build JSON string for CommandTO data
+ Poco::JSON::Object obj;
+ obj.set("name", Poco::Dynamic::Var(name));
+ std::string creationDate = Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::SORTABLE_FORMAT);
+ obj.set("creationDate", Poco::Dynamic::Var(creationDate));
+ std::string data = JsonFormatter::stringify(obj);
+
+ CommandTO cto(CREATE_STUDY, data);
+ const Credentials& credentials = _session.getCredentials();
+ std::string uri = _session.getServiceURI(_servletName);
+ CommandResultTO crto = gde::HttpConnection(Poco::URI(uri), credentials).doPost(cto);
+
+ // build Study object from CommandResultTO data (json format)
+ {
+ Poco::JSON::Object::Ptr object = JsonFormatter::parse(crto.getData());
+ int id = JsonFormatter::extract<int>(object, "id");
+ std::string name = JsonFormatter::extract<std::string>(object, "name");
+ Poco::Timestamp creationDate = JsonFormatter::extract(object, "creationDate");
+ Poco::Timestamp updateDate = JsonFormatter::extract(object, "updateDate");
+ bool valid = JsonFormatter::extract<bool>(object, "valid");
+ bool deleted = JsonFormatter::extract<bool>(object, "deleted");
+ Poco::Timestamp deletionDate = JsonFormatter::extract(object, "deletionDate");
+ int attributeGroupId = JsonFormatter::extract<int>(object, "attributeGroupId");
+ int profileId = JsonFormatter::extract<int>(object, "profileId");
+ bool locked = JsonFormatter::extract<bool>(object, "locked");
+ int lockOwner = JsonFormatter::extract<int>(object, "lockOwner");
+
+ return gde::Study(id, name, creationDate, updateDate, valid, deleted, deletionDate, attributeGroupId, profileId, locked, lockOwner);
+ }
+}
+
+bool
+gde::StudyService::deleteStudy(const Study& study)
+{
+ CommandTO cto(DELETE_STUDY);
+ cto.setParameter("studyId", study.getId());
+
+ const Credentials& credentials = _session.getCredentials();
+ std::string uri = _session.getServiceURI(_servletName);
+ CommandResultTO crto = gde::HttpConnection(Poco::URI(uri), credentials).doPost(cto);
+ return crto.getCode() == CommandResultTO::OK;
+}
+
+bool
+gde::StudyService::setStudyState(const Study& study, int lock)
+{
+ CommandTO cto(SET_STUDY_SATE);
+ cto.setParameter("studyId", study.getId());
+ cto.setParameter("lock", lock);
+
+ const Credentials& credentials = _session.getCredentials();
+ std::string uri = _session.getServiceURI(_servletName);
+ CommandResultTO crto = gde::HttpConnection(Poco::URI(uri), credentials).doPost(cto);
+ return crto.getCode() == CommandResultTO::OK;
+}
+
+const gde::Study
+gde::StudyService::readStudy(int studyId)
+{
+ CommandTO cto(READ_STUDY);
+ cto.setParameter("studyId", studyId);
+
+ const Credentials& credentials = _session.getCredentials();
+ std::string uri = _session.getServiceURI(_servletName);
+ CommandResultTO crto = gde::HttpConnection(Poco::URI(uri), credentials).doPost(cto);
+
+ // build Study object from CommandResultTO data (json format)
+ {
+ Poco::JSON::Object::Ptr object = JsonFormatter::parse(crto.getData());
+ int id = JsonFormatter::extract<int>(object, "id");
+ std::string name = JsonFormatter::extract<std::string>(object, "name");
+ Poco::Timestamp creationDate = JsonFormatter::extract(object, "creationDate");
+ Poco::Timestamp updateDate = JsonFormatter::extract(object, "updateDate");
+ bool valid = JsonFormatter::extract<bool>(object, "valid");
+ bool deleted = JsonFormatter::extract<bool>(object, "deleted");
+ Poco::Timestamp deletionDate = JsonFormatter::extract(object, "deletionDate");
+ int attributeGroupId = JsonFormatter::extract<int>(object, "attributeGroupId");
+ int profileId = JsonFormatter::extract<int>(object, "profileId");
+ bool locked = JsonFormatter::extract<bool>(object, "locked");
+ int lockOwner = JsonFormatter::extract<int>(object, "lockOwner");
+
+ return gde::Study(id, name, creationDate, updateDate, valid, deleted, deletionDate, attributeGroupId, profileId, locked, lockOwner);
+ }
+}
--- /dev/null
+#ifndef GDE_STUDY_SERVICE_HPP
+#define GDE_STUDY_SERVICE_HPP
+
+#include "Study.hpp"
+#include "GDESession.hpp"
+
+#include <string>
+
+namespace gde {
+
+ class StudyService {
+ friend class GDESession;
+
+ public:
+ const Study createStudy(const std::string& name);
+ bool deleteStudy(const Study&);
+
+ bool setStudyState(const Study&, int lock);
+ const Study readStudy(int studyId);
+
+ private:
+ StudyService(const GDESession& session) : _session(session) {}
+ ~StudyService() {}
+ StudyService(const StudyService&); // non copyable
+ StudyService& operator=(const StudyService&); // non copyable
+
+ private:
+ static std::string _servletName;
+ const GDESession& _session;
+
+ };
+
+};
+
+#endif
--- /dev/null
+#include <iostream>
+
+#include <TestUtilities.hpp>
+#include <Study.hpp>
+#include <GDESession.hpp>
+#include <StudyTest.hpp>
+
+void
+StudyTest::testCreateDeleteStudy()
+{
+ gde::GDESession session(serverAddress, credentials);
+
+ const gde::Study& study = session.createStudy("myStudy");
+ CPPUNIT_ASSERT(study.getName() == "myStudy");
+ CPPUNIT_ASSERT(study.getId() > 0);
+
+ CPPUNIT_ASSERT(session.deleteStudy(study));
+}
+
+void
+StudyTest::testReadStudy()
+{
+ gde::GDESession session(serverAddress, credentials);
+
+ const gde::Study& study = session.createStudy("myStudy");
+ CPPUNIT_ASSERT(study.getId() > 0);
+
+ {
+ const gde::Study& myStudy = session.readStudy(study.getId());
+ CPPUNIT_ASSERT(myStudy.getName() == "myStudy");
+ CPPUNIT_ASSERT(myStudy.getId() > 0);
+ }
+
+ CPPUNIT_ASSERT(session.deleteStudy(study));
+ /*
+ // Will raise an exception: study does not exist anymore
+ {
+ const gde::Study& myStudy = session.readStudy(study.getId());
+ }
+ */
+}
+
+void
+StudyTest::testSetStudySate()
+{
+ gde::GDESession session(serverAddress, credentials);
+
+ const gde::Study& study = session.createStudy("myStudy");
+ CPPUNIT_ASSERT(study.getId() > 0);
+
+ CPPUNIT_ASSERT(session.setStudyState(study, 1));
+ CPPUNIT_ASSERT(session.setStudyState(study, 0));
+
+ CPPUNIT_ASSERT(session.deleteStudy(study));
+}
--- /dev/null
+#ifndef GDE_STUDY_TEST_HPP
+#define GDE_STUDY_TEST_HPP
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class StudyTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(StudyTest);
+ CPPUNIT_TEST(testCreateDeleteStudy);
+ CPPUNIT_TEST(testReadStudy);
+ CPPUNIT_TEST(testSetStudySate);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testCreateDeleteStudy();
+ void testReadStudy();
+ void testSetStudySate();
+};
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StudyTest, "StudyTest");
+
+#endif
#include <string>
-std::string serverAddress = "http://localhost:8080/GDE-war";
-gde::Credentials credentials("admin", "edf123");
+static std::string serverAddress = "http://localhost:8080/GDE-war";
+static gde::Credentials credentials("admin", "edf123");
#endif
import com.edf.gde.transferables.CommandTO;
import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
-import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public abstract void processRequest(HttpServletRequest request, HttpServletResponse response);
+ private String dateFormat = "yyyy-MM-dd HH:mm:ss";
+
protected <T> T read(HttpServletRequest request, Class<T> classOf) {
try {
- Gson gson = new Gson();
+ Gson gson = new GsonBuilder().setDateFormat(dateFormat).create();
return gson.fromJson(request.getReader(), classOf);
} catch (IOException ex) {
Logger.getLogger(BaseService.class.getName()).log(Level.SEVERE, null, ex);
}
protected <T> T fromJson(String json, Class<T> classOf) {
- Gson gson = new Gson();
+ Gson gson = new GsonBuilder().setDateFormat(dateFormat).create();
return gson.fromJson(json, classOf);
}
protected String toJson(Object object) {
- Gson gson = new Gson();
+ Gson gson = new GsonBuilder().setDateFormat(dateFormat).create();
return gson.toJson(object);
}
protected void send(Object object, HttpServletResponse out) {
try {
- Gson gson = new Gson();
+ Gson gson = new GsonBuilder().setDateFormat(dateFormat).create();
gson.toJson(object, out.getWriter());
} catch (IOException ex) {
throw new RuntimeException(ex);