Salome HOME
API c++
authorCédric Aguerre <cedric.aguerre@edf.fr>
Fri, 7 Aug 2015 13:54:43 +0000 (15:54 +0200)
committerCédric Aguerre <cedric.aguerre@edf.fr>
Fri, 7 Aug 2015 13:54:43 +0000 (15:54 +0200)
14 files changed:
projects/GDE_API_CPP/api/CMakeLists.txt [new file with mode: 0644]
projects/GDE_API_CPP/api/cmake_files/FindPOCO.cmake [new file with mode: 0644]
projects/GDE_API_CPP/api/src/CMakeLists.txt [new file with mode: 0644]
projects/GDE_API_CPP/api/src/CommandResultTO.cpp [new file with mode: 0644]
projects/GDE_API_CPP/api/src/CommandResultTO.hpp [new file with mode: 0644]
projects/GDE_API_CPP/api/src/CommandTO.cpp [new file with mode: 0644]
projects/GDE_API_CPP/api/src/CommandTO.hpp [new file with mode: 0644]
projects/GDE_API_CPP/api/src/HttpConnection.cpp [new file with mode: 0644]
projects/GDE_API_CPP/api/src/HttpConnection.hpp [new file with mode: 0644]
projects/GDE_API_CPP/api/src/JsonFormatter.cpp [new file with mode: 0644]
projects/GDE_API_CPP/api/src/JsonFormatter.hpp [new file with mode: 0644]
projects/GDE_API_CPP/api/src/User.hpp [new file with mode: 0644]
projects/GDE_API_CPP/api/src/UserService.cpp [new file with mode: 0644]
projects/GDE_API_CPP/api/src/UserService.hpp [new file with mode: 0644]

diff --git a/projects/GDE_API_CPP/api/CMakeLists.txt b/projects/GDE_API_CPP/api/CMakeLists.txt
new file mode 100644 (file)
index 0000000..48e3fb4
--- /dev/null
@@ -0,0 +1,11 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(GdeApiCpp C CXX)
+
+# Ensure a proper linker behavior:
+CMAKE_POLICY(SET CMP0003 NEW)
+
+LIST(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_files")
+FIND_PACKAGE(POCO REQUIRED)
+INCLUDE_DIRECTORIES(${Poco_INCLUDE_DIRS})
+
+ADD_SUBDIRECTORY(src)
diff --git a/projects/GDE_API_CPP/api/cmake_files/FindPOCO.cmake b/projects/GDE_API_CPP/api/cmake_files/FindPOCO.cmake
new file mode 100644 (file)
index 0000000..dcbd767
--- /dev/null
@@ -0,0 +1,167 @@
+# - Find the Poco includes and libraries.
+# The following variables are set if Poco is found. If Poco is not
+# found, Poco_FOUND is set to false.
+# Poco_FOUND - True when the Poco include directory is found.
+# Poco_INCLUDE_DIRS - the path to where the poco include files are.
+# Poco_LIBRARY_DIRS - The path to where the poco library files are.
+# Poco_BINARY_DIRS - The path to where the poco dlls are.
+
+# ----------------------------------------------------------------------------
+# If you have installed Poco in a non-standard location.
+# Then you have three options.
+# In the following comments, it is assumed that <Your Path>
+# points to the root directory of the include directory of Poco. e.g
+# If you have put poco in C:\development\Poco then <Your Path> is
+# "C:/development/Poco" and in this directory there will be two
+# directories called "include" and "lib".
+# 1) After CMake runs, set Poco_INCLUDE_DIR to <Your Path>/poco<-version>
+# 2) Use CMAKE_INCLUDE_PATH to set a path to <Your Path>/poco<-version>. This will allow find_path()
+# to locate Poco_INCLUDE_DIR by utilizing the PATH_SUFFIXES option. e.g.
+# set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "<Your Path>/include")
+# 3) Set an environment variable called ${POCO_ROOT} that points to the root of where you have
+# installed Poco, e.g. <Your Path>. It is assumed that there is at least a subdirectory called
+# Foundation/include/Poco in this path.
+#
+# Note:
+# 1) If you are just using the poco headers, then you do not need to use
+# Poco_LIBRARY_DIR in your CMakeLists.txt file.
+# 2) If Poco has not been installed, then when setting Poco_LIBRARY_DIR
+# the script will look for /lib first and, if this fails, then for /stage/lib.
+#
+# Usage:
+# In your CMakeLists.txt file do something like this:
+# ...
+# # Poco
+# find_package(Poco)
+# ...
+# include_directories(${Poco_INCLUDE_DIRS})
+# link_directories(${Poco_LIBRARY_DIR})
+#
+# In Windows, we make the assumption that, if the Poco files are installed, the default directory
+# will be C:\poco or C:\Program Files\Poco or C:\Programme\Poco.
+
+set(POCO_INCLUDE_PATH_DESCRIPTION "top-level directory containing the poco include directories.")
+set(POCO_INCLUDE_DIR_MESSAGE "Set the Poco_INCLUDE_DIR cmake cache entry to the ${POCO_INCLUDE_PATH_DESCRIPTION}")
+set(POCO_LIBRARY_PATH_DESCRIPTION "directory containing the poco libraries:")
+
+
+set(POCO_DIR_SEARCH $ENV{POCO_ROOT})
+if(POCO_DIR_SEARCH)
+ file(TO_CMAKE_PATH ${POCO_DIR_SEARCH} POCO_DIR_SEARCH)
+endif(POCO_DIR_SEARCH)
+list(APPEND POCO_DIR_SEARCH ${Poco_DIR})
+
+if(WIN32)
+ set(POCO_DIR_SEARCH
+ ${POCO_DIR_SEARCH}
+ C:/poco
+ D:/poco
+ "C:/Program Files/poco"
+ "C:/Programme/poco"
+ "D:/Program Files/poco"
+ "D:/Programme/poco"
+ )
+endif(WIN32)
+
+# Add in some path suffixes. These will have to be updated whenever a new Poco version comes out.
+set(SUFFIX_FOR_INCLUDE_PATH
+ include
+)
+
+set(SUFFIX_FOR_LIBRARY_PATH
+ lib
+ bin
+)
+
+#
+# Look for an installation.
+#
+find_path(Poco_INCLUDE_DIR NAMES Poco/Poco.h PATH_SUFFIXES ${SUFFIX_FOR_INCLUDE_PATH} PATHS
+
+ # Look in other places.
+ ${POCO_DIR_SEARCH}
+
+ # Help the user find it if we cannot.
+ DOC "The ${POCO_INCLUDE_PATH_DESCRIPTION}"
+)
+
+if(NOT Poco_INCLUDE_DIR)
+
+ # Look for standard unix include paths
+ find_path(Poco_INCLUDE_DIR Poco/Poco.h DOC "The ${POCO_INCLUDE_PATH_DESCRIPTION}")
+
+endif(NOT Poco_INCLUDE_DIR)
+
+# Assume we didn't find it.
+set(Poco_FOUND 0)
+
+set(Poco_LIBRARIES )
+set(Poco_LIBRARY_DIRS )
+
+# Now try to get the include and library path.
+# Find all libraries, store debug and release separately
+foreach(lib
+ Crypto
+ Data
+ DataMySQL
+ DataSQLite
+ Foundation
+ JSON
+ MongoDB
+ Net
+ NetSSL
+ PDF
+ Util
+ XML
+ Zip
+ )
+
+ # Find Release libraries
+ find_library(Poco_${lib}_LIBRARY_RELEASE
+ NAMES Poco${lib}
+ PATH_SUFFIXES ${SUFFIX_FOR_LIBRARY_PATH}
+ PATHS ${POCO_DIR_SEARCH}
+ DOC "The ${POCO_LIBRARY_PATH_DESCRIPTION} Poco${lib}"
+ )
+
+ # Find Debug libraries
+ find_library(Poco_${lib}_LIBRARY_DEBUG
+ NAMES Poco${lib}d
+ PATH_SUFFIXES ${SUFFIX_FOR_LIBRARY_PATH}
+ PATHS ${POCO_DIR_SEARCH}
+ DOC "The ${POCO_LIBRARY_PATH_DESCRIPTION} Poco${lib}d"
+ )
+
+ mark_as_advanced(Poco_${lib}_LIBRARY_RELEASE)
+ mark_as_advanced(Poco_${lib}_LIBRARY_DEBUG)
+
+ # Add libraries to variable according to build type
+ set(Poco_${lib}_LIBRARY)
+ if(Poco_${lib}_LIBRARY_RELEASE)
+ list(APPEND Poco_LIBRARIES optimized ${Poco_${lib}_LIBRARY_RELEASE})
+ list(APPEND Poco_${lib}_LIBRARY optimized ${Poco_${lib}_LIBRARY_RELEASE})
+ get_filename_component(lib_dir ${Poco_${lib}_LIBRARY_RELEASE} PATH)
+ list(APPEND Poco_LIBRARY_DIRS ${lib_dir})
+ endif()
+
+ if(Poco_${lib}_LIBRARY_DEBUG)
+ list(APPEND Poco_LIBRARIES debug ${Poco_${lib}_LIBRARY_DEBUG})
+ list(APPEND Poco_${lib}_LIBRARY debug ${Poco_${lib}_LIBRARY_DEBUG})
+ get_filename_component(lib_dir ${Poco_${lib}_LIBRARY_RELEASE} PATH)
+ list(APPEND Poco_LIBRARY_DIRS ${lib_dir})
+ endif()
+
+endforeach()
+
+if(Poco_LIBRARY_DIRS)
+ list(REMOVE_DUPLICATES Poco_LIBRARY_DIRS)
+endif()
+
+set(Poco_INCLUDE_DIRS ${Poco_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Poco DEFAULT_MSG
+ Poco_INCLUDE_DIRS
+ Poco_Foundation_LIBRARY
+ Poco_LIBRARIES
+ )
diff --git a/projects/GDE_API_CPP/api/src/CMakeLists.txt b/projects/GDE_API_CPP/api/src/CMakeLists.txt
new file mode 100644 (file)
index 0000000..c9a9655
--- /dev/null
@@ -0,0 +1,38 @@
+
+INCLUDE_DIRECTORIES(
+  ${Poco_INCLUDE_DIRS}
+)
+
+LINK_DIRECTORIES(
+  ${Poco_LIBRARY_DIRS}
+  )
+
+SET(_link_LIBRARIES
+#  ${Poco_LIBRARIES} # all packages
+  PocoFoundation
+  PocoNet
+  PocoJSON
+)
+
+SET(gde_api_cpp_HEADERS
+  CommandResultTO.hpp
+  CommandTO.hpp
+  HttpConnection.hpp
+  JsonFormatter.hpp
+  User.hpp
+  UserService.hpp
+)
+
+SET(gde_api_cpp_SOURCES
+  CommandResultTO.cpp
+  CommandTO.cpp
+  HttpConnection.cpp
+  JsonFormatter.cpp
+  UserService.cpp
+)
+
+ADD_LIBRARY(GdeApiCpp SHARED ${gde_api_cpp_SOURCES})
+TARGET_LINK_LIBRARIES(GdeApiCpp ${_link_LIBRARIES} )
+INSTALL(TARGETS GdeApiCpp EXPORT ${PROJECT_NAME}TargetGroup DESTINATION lib)
+
+INSTALL(FILES ${gde_api_cpp_HEADERS} DESTINATION include)
diff --git a/projects/GDE_API_CPP/api/src/CommandResultTO.cpp b/projects/GDE_API_CPP/api/src/CommandResultTO.cpp
new file mode 100644 (file)
index 0000000..011bd62
--- /dev/null
@@ -0,0 +1,28 @@
+#include "CommandResultTO.hpp"
+#include "JsonFormatter.hpp"
+
+gde::CommandResultTO::CommandResultTO(const CommandResultTO& cto)
+  : _code(cto._code), _message(cto._message), _data(cto._data)
+{
+}
+
+gde::CommandResultTO
+gde::CommandResultTO::fromJson(std::string json)
+{
+  Poco::JSON::Object::Ptr object = JsonFormatter::parse(json);
+  int code = JsonFormatter::extract<int>(object, "code");
+  std::string message = JsonFormatter::extract<std::string>(object, "message");
+  std::string data = JsonFormatter::extract<std::string>(object, "data");
+  return CommandResultTO(code, message, data);
+}
+
+std::string
+gde::CommandResultTO::toJson()
+{
+  Poco::JSON::Object obj;
+  obj.set("code", Poco::Dynamic::Var(_code));
+  obj.set("message", Poco::Dynamic::Var(_message));
+  obj.set("data", Poco::Dynamic::Var(_data));
+
+  return JsonFormatter::stringify(obj);
+}
diff --git a/projects/GDE_API_CPP/api/src/CommandResultTO.hpp b/projects/GDE_API_CPP/api/src/CommandResultTO.hpp
new file mode 100644 (file)
index 0000000..c29e709
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef GDE_COMMAND_RESULT_TO_HPP
+#define GDE_COMMAND_RESULT_TO_HPP
+
+#include <string>
+#include <map>
+
+namespace gde {
+
+  class CommandResultTO {
+
+  public :
+    // WARNING: keep enum values synchronized to WEB API (CommandResultTO)
+    enum { OK = 1, ERROR = 2};
+
+  public:
+    CommandResultTO(int code = -1,
+                    std::string message = std::string(),
+                    std::string data = std::string())
+      : _code(code), _message(message), _data(data) {}
+    CommandResultTO(const CommandResultTO&);
+    ~CommandResultTO() {}
+
+    inline std::string getMessage() const { return _message; }
+    inline void setMessage(std::string message) { this->_message = message; }
+
+    inline std::string getData() const { return _data; }
+    inline void setData(std::string data) { this->_data = data; }
+
+    inline int getCode() const { return _code; }
+    inline void setCode(int code) { this->_code = code; }
+
+    static CommandResultTO fromJson(std::string json);
+    std::string toJson();
+
+  private:
+    int _code;
+    std::string _message; // JSON format
+    std::string _data; // JSON format
+  };
+
+};
+
+#endif
diff --git a/projects/GDE_API_CPP/api/src/CommandTO.cpp b/projects/GDE_API_CPP/api/src/CommandTO.cpp
new file mode 100644 (file)
index 0000000..92d19b9
--- /dev/null
@@ -0,0 +1,91 @@
+#include "CommandTO.hpp"
+#include "JsonFormatter.hpp"
+
+#include <iostream>
+#include <sstream>
+
+template <typename T>
+std::string
+toString(const T& value)
+{
+  std::ostringstream oss;
+  oss << value;
+  return oss.str();
+}
+
+template <typename T>
+T
+fromString(const std::string& valueString)
+{
+  std::istringstream iss(valueString);
+  T value;
+  return iss >> value ? value : 0;
+}
+
+
+gde::CommandTO::CommandTO(const CommandTO& cto)
+  : _method(cto._method), _data(cto._data), _parameters(cto._parameters)
+{
+}
+
+template <typename T>
+T
+gde::CommandTO::getParameter(std::string name)
+{
+  if (_parameters.find(name) == _parameters.end()) {
+    std::cerr << "Unknown parameter: " << name << std::endl;
+    return 0;
+  }
+  else {
+    return fromString<T>(_parameters[name]);
+  }
+}
+
+template <typename T>
+void
+gde::CommandTO::setParameter(std::string name, const T& value, bool replaceIfExist)
+{
+  if (replaceIfExist) {
+    _parameters[name] = toString(value);
+  }
+  else {
+    if (_parameters.find(name) != _parameters.end()) {
+      std::cerr << "Parameter already exists: " << name << std::endl;
+    }
+  }
+}
+
+gde::CommandTO
+gde::CommandTO::fromJson(std::string json)
+{
+  Poco::JSON::Object::Ptr object = JsonFormatter::parse(json);
+  int method = JsonFormatter::extract<int>(object, "method");
+  std::string data = JsonFormatter::extract<std::string>(object, "data");
+
+  ParametersMap parameters;
+  Poco::JSON::Object::Ptr objParameters = JsonFormatter::extract<Poco::JSON::Object::Ptr>(object, "parameters");
+  for (Poco::JSON::Object::ConstIterator itr = objParameters->begin(); itr != objParameters->end(); ++itr) {
+    std::string paramName = itr->first;
+    std::string paramValue = itr->second;
+    parameters[paramName] = paramValue;
+  }
+
+  return CommandTO(method, data, parameters);
+}
+
+std::string
+gde::CommandTO::toJson()
+{
+  Poco::JSON::Object obj;
+  obj.set("method", Poco::Dynamic::Var(_method));
+  obj.set("data", Poco::Dynamic::Var(_data));
+
+  Poco::JSON::Object::Ptr objParameters = new Poco::JSON::Object(true);
+  typedef std::map<std::string, std::string>::iterator MapIterator;
+  for (MapIterator itr = _parameters.begin(); itr != _parameters.end(); ++itr) {
+    objParameters->set(itr->first, itr->second);
+  }
+  obj.set("parameters", objParameters);
+
+  return JsonFormatter::stringify(obj);
+}
diff --git a/projects/GDE_API_CPP/api/src/CommandTO.hpp b/projects/GDE_API_CPP/api/src/CommandTO.hpp
new file mode 100644 (file)
index 0000000..b00d847
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef GDE_COMMAND_TO_HPP
+#define GDE_COMMAND_TO_HPP
+
+#include <string>
+#include <map>
+
+namespace gde {
+
+  class CommandTO {
+
+    typedef std::map<std::string, std::string> ParametersMap;
+
+  public:
+    CommandTO(int method = -1,
+              std::string data = std::string(),
+              const ParametersMap& parameters=ParametersMap())
+      : _method(method), _data(data), _parameters(parameters) {}
+    CommandTO(const CommandTO&);
+    ~CommandTO() {}
+
+    inline std::string getData() const { return _data; }
+    inline void setData(std::string data) { this->_data = data; }
+
+    inline int getMethod() const { return _method; }
+    inline void setMethod(int method) { this->_method = method; }
+
+    template <typename T> T getParameter(std::string name);
+    template <typename T> void setParameter(std::string name, const T& value, bool replaceIfExist=true);
+
+    static CommandTO fromJson(std::string json);
+    std::string toJson();
+
+  private:
+    int _method;
+    std::string _data; // JSON format
+    ParametersMap _parameters;
+  };
+
+};
+
+#endif
diff --git a/projects/GDE_API_CPP/api/src/HttpConnection.cpp b/projects/GDE_API_CPP/api/src/HttpConnection.cpp
new file mode 100644 (file)
index 0000000..5a2e16d
--- /dev/null
@@ -0,0 +1,84 @@
+#include "HttpConnection.hpp"
+#include "JsonFormatter.hpp"
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+#include <Poco/StreamCopier.h>
+#include <Poco/Net/HTTPResponse.h>
+
+using namespace Poco::Net;
+
+gde::HttpConnection::HttpConnection(Poco::URI uri)
+  : _path("/")
+{
+  try {
+    _session.setHost(uri.getHost());
+    _session.setPort(uri.getPort());
+    //_session.setProxy(machine, port);
+  } catch (Poco::Exception& e) {
+    std::cerr << e.displayText() << std::endl;
+    return;
+  }
+
+  _path = uri.getPathAndQuery();
+  if (_path.empty())
+    _path = "/";
+}
+
+gde::HttpConnection::~HttpConnection()
+{
+}
+
+// Workflow:
+// 1. request (json) --> CommandTO object
+// 2. command data (json) from CommandTO --> <something>TO
+// 3. call DAO with <something>TO and obtain another <something>TO
+// 4. latter <something>TO --> (json) CommandResultTO data
+// 5. set CommandResultTO code
+// 6. CommandResultTO --> (json) response
+
+gde::CommandResultTO
+gde::HttpConnection::_processRequest(const HTTPRequest& request,
+                                     const std::string& requestBody)
+{
+  int code = CommandResultTO::OK;
+  std::string message = "";
+  std::string data = "";
+
+  try {
+    std::ostream& os = _session.sendRequest((HTTPRequest&)request);
+    // Send request body, if any
+    if (!requestBody.empty()) {
+      std::istringstream iss(requestBody);
+      Poco::StreamCopier::copyStream((std::istream&)iss, os);
+    }
+
+    // Get response
+    HTTPResponse response;
+    std::istream& rs = _session.receiveResponse(response);
+    //std::cout << response.getStatus() << " " << response.getReason() << endl;
+    std::ostringstream responseBody;
+    Poco::StreamCopier::copyStream(rs, responseBody);
+    // responseBody contains a CommandResultTO in json format
+    return CommandResultTO::fromJson(responseBody.str());
+  } catch (Poco::Exception& e) {
+    std::cerr << e.displayText() << std::endl;
+    return CommandResultTO(CommandResultTO::ERROR);
+  }
+}
+
+gde::CommandResultTO
+gde::HttpConnection::doGet(const CommandTO& cto)
+{
+  HTTPRequest request(HTTPRequest::HTTP_GET, _path, HTTPMessage::HTTP_1_1);
+  return _processRequest(request, cto.getData());
+}
+
+gde::CommandResultTO
+gde::HttpConnection::doPost(const CommandTO& cto)
+{
+  HTTPRequest request(HTTPRequest::HTTP_PUT, _path, HTTPMessage::HTTP_1_1);
+  return _processRequest(request, cto.getData());
+}
diff --git a/projects/GDE_API_CPP/api/src/HttpConnection.hpp b/projects/GDE_API_CPP/api/src/HttpConnection.hpp
new file mode 100644 (file)
index 0000000..661358a
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef GDE_HTTP_CONNECTION_HPP
+#define GDE_HTTP_CONNECTION_HPP
+
+#include "CommandTO.hpp"
+#include "CommandResultTO.hpp"
+
+#include <string>
+
+#include <Poco/URI.h>
+#include <Poco/Net/HTTPClientSession.h>
+#include <Poco/Net/HTTPRequest.h>
+
+namespace gde {
+
+  class HttpConnection {
+
+  public:
+    HttpConnection(Poco::URI);
+    ~HttpConnection();
+
+    CommandResultTO doGet(const CommandTO&);
+    CommandResultTO doPost(const CommandTO&);
+
+  private:
+    gde::CommandResultTO _processRequest(const Poco::Net::HTTPRequest&,
+                                         const std::string& requestBody);
+
+  private:
+    Poco::Net::HTTPClientSession _session;
+    std::string _path;
+  };
+
+};
+
+#endif
diff --git a/projects/GDE_API_CPP/api/src/JsonFormatter.cpp b/projects/GDE_API_CPP/api/src/JsonFormatter.cpp
new file mode 100644 (file)
index 0000000..2bee2a5
--- /dev/null
@@ -0,0 +1,30 @@
+#include "JsonFormatter.hpp"
+
+#include <Poco/JSON/Parser.h>
+
+#include <sstream>
+
+Poco::JSON::Object::Ptr
+gde::JsonFormatter::parse(const std::string& json)
+{
+  Poco::JSON::Parser parser;
+  Poco::Dynamic::Var result = parser.parse(json);
+  // use pointers to avoid copying
+  Poco::JSON::Object::Ptr object = result.extract<Poco::JSON::Object::Ptr>();
+  return object;
+}
+
+template <typename T>
+T
+gde::JsonFormatter::extract(Poco::JSON::Object::Ptr object, const std::string& varName)
+{
+  Poco::Dynamic::Var v = object->get(varName);
+  return v.convert<T>();
+}
+
+std::string
+gde::JsonFormatter::stringify(const Poco::JSON::Object& object) {
+  std::ostringstream jsonStream;
+  object.stringify(jsonStream);
+  return jsonStream.str();
+}
diff --git a/projects/GDE_API_CPP/api/src/JsonFormatter.hpp b/projects/GDE_API_CPP/api/src/JsonFormatter.hpp
new file mode 100644 (file)
index 0000000..395bbcb
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef JSON_FORMATTER_HPP
+#define JSON_FORMATTER_HPP
+
+#include <string>
+
+#include <Poco/JSON/Object.h>
+
+namespace gde {
+
+  class JsonFormatter {
+  public:
+
+    static Poco::JSON::Object::Ptr parse(const std::string&);
+    template <typename T> static T extract(Poco::JSON::Object::Ptr, const std::string&);
+
+    static std::string stringify(const Poco::JSON::Object&);
+  };
+
+};
+
+#endif
diff --git a/projects/GDE_API_CPP/api/src/User.hpp b/projects/GDE_API_CPP/api/src/User.hpp
new file mode 100644 (file)
index 0000000..131508b
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef GDE_USER_HPP
+#define GDE_USER_HPP
+
+#include <string>
+
+namespace gde {
+
+  class User {
+    friend class UserService;
+
+  public:
+    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 std::string getPassword() const { return _password; }
+    inline void setPassword(const std::string& password) { this->_password = password; }
+
+  private:
+    User(int id=-1, std::string name="", std::string password="")
+      : _id(id), _name(name), _password(password) {}
+    ~User() {}
+    User(const User&); // non copyable
+    User& operator=(const User&); // non copyable
+
+  private:
+    int _id;
+    std::string _name;
+    std::string _password;
+  };
+
+};
+
+#endif
diff --git a/projects/GDE_API_CPP/api/src/UserService.cpp b/projects/GDE_API_CPP/api/src/UserService.cpp
new file mode 100644 (file)
index 0000000..2465ed9
--- /dev/null
@@ -0,0 +1,55 @@
+#include "UserService.hpp"
+#include "HttpConnection.hpp"
+#include "CommandTO.hpp"
+#include "CommandResultTO.hpp"
+#include "JsonFormatter.hpp"
+
+#include <iostream>
+#include <sstream>
+
+/*
+ * WARNING: keep enum values synchronized to WEB API (UserService)
+ */
+enum {
+  CREATE_USER = 1,
+  DELETE_USER,
+  ADD_TO_GROUP,
+  REMOVE_FROM_GROUP,
+  CREATE_GROUP,
+  DELETE_GROUP,
+  FIND_USER
+};
+
+gde::UserService::UserService()
+  : _servletName("/UserService")
+{
+}
+
+gde::UserService::~UserService()
+{
+}
+
+gde::User
+gde::UserService::createUser(std::string name, std::string password)
+{
+  // build JSON string for CommandTO data
+  Poco::JSON::Object obj;
+  obj.set("name", Poco::Dynamic::Var(name));
+  obj.set("password", Poco::Dynamic::Var(password));
+  std::string data = JsonFormatter::stringify(obj);
+
+  CommandTO cto(CREATE_USER, data);
+  CommandResultTO crto = gde::HttpConnection(Poco::URI(_servletName)).doPost(cto);
+
+  std::cout << "createUser command:\n";
+  std::cout << "\tStatus code (OK=1, ERROR=2): " << crto.getCode() << std::endl;
+
+  // build User 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");
+    std::string password = JsonFormatter::extract<std::string>(object, "password");
+    return gde::User(id, name, password);
+  }
+}
diff --git a/projects/GDE_API_CPP/api/src/UserService.hpp b/projects/GDE_API_CPP/api/src/UserService.hpp
new file mode 100644 (file)
index 0000000..33ca6b8
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef GDE_USER_SERVICE_HPP
+#define GDE_USER_SERVICE_HPP
+
+#include "User.hpp"
+
+#include <string>
+
+namespace gde {
+
+  class UserService {
+
+  public:
+    User createUser(std::string name, std::string password);
+
+    void createUser();
+    void deleteUser();
+    void findUser();
+
+    void createGroup();
+    void deleteGroup();
+
+    void addToGroup();
+    void removeFromGroup();
+
+  private:
+    UserService();
+    ~UserService();
+    UserService(const UserService&); // non copyable
+    UserService& operator=(const UserService&); // non copyable
+
+  private:
+    std::string _servletName;
+  };
+
+};
+
+#endif