API docs for ObjectMapper, mapping::type::Type, and web::client::RequestExecutor

This commit is contained in:
lganzzzo 2019-03-18 03:50:01 +02:00
parent a09a37ff8b
commit 2dd4af3fe8
6 changed files with 416 additions and 120 deletions

View File

@ -23,3 +23,21 @@
***************************************************************************/
#include "ObjectMapper.hpp"
namespace oatpp { namespace data { namespace mapping {
ObjectMapper::ObjectMapper(const Info& info)
: m_info(info)
{}
const ObjectMapper::Info& ObjectMapper::getInfo() const {
return m_info;
}
oatpp::String ObjectMapper::writeToString(const type::AbstractObjectWrapper& variant) const {
auto stream = stream::ChunkedBuffer::createShared();
write(stream, variant);
return stream->toString();
}
}}}

View File

@ -36,45 +36,80 @@
#include "oatpp/core/parser/ParsingError.hpp"
namespace oatpp { namespace data { namespace mapping {
/**
* Abstract ObjectMapper class.
*/
class ObjectMapper {
public:
/**
* Metadata for ObjectMapper.
*/
class Info {
public:
/**
* Constructor.
* @param _http_content_type
*/
Info(const char* _http_content_type)
: http_content_type(_http_content_type)
{}
/**
* Value for Content-Type http header when DTO is serialized via specified ObjectMapper.
*/
const char* const http_content_type;
};
private:
Info m_info;
public:
ObjectMapper(const Info& info)
: m_info(info)
{}
const Info& getInfo() const {
return m_info;
}
virtual void write(const std::shared_ptr<oatpp::data::stream::OutputStream>& stream,
const type::AbstractObjectWrapper& variant) const = 0;
virtual type::AbstractObjectWrapper read(oatpp::parser::Caret& caret,
const type::Type* const type) const = 0;
oatpp::String writeToString(const type::AbstractObjectWrapper& variant) const {
auto stream = stream::ChunkedBuffer::createShared();
write(stream, variant);
return stream->toString();
}
/**
* Constructor.
* @param info - Metadata for ObjectMapper.
*/
ObjectMapper(const Info& info);
/**
* Get ObjectMapper metadata.
* @return - ObjectMapper metadata.
*/
const Info& getInfo() const;
/**
* Serialize object to stream. Implement this method.
* @param stream - &id:oatpp::data::stream::OutputStream; to serialize object to.
* @param variant - Object to serialize.
*/
virtual void write(const std::shared_ptr<oatpp::data::stream::OutputStream>& stream,
const type::AbstractObjectWrapper& variant) const = 0;
/**
* Deserialize object. Implement this method.
* @param caret - &id:oatpp::parser::Caret; over serialized buffer.
* @param type - pointer to object type. See &id:oatpp::data::mapping::type::Type;.
* @return - deserialized object wrapped in &id:oatpp::data::mapping::type::AbstractObjectWrapper;.
*/
virtual mapping::type::AbstractObjectWrapper read(oatpp::parser::Caret& caret,
const mapping::type::Type* const type) const = 0;
/**
* Serialize object to String.
* @param variant - Object to serialize.
* @return - serialized object as &id:oatpp::String;.
*/
oatpp::String writeToString(const type::AbstractObjectWrapper& variant) const;
/**
* Deserialize object.
* If nullptr is returned - check caret.getError()
* @tparam Class
* @param caret
* @return
* @tparam Class - object class.
* @param caret - &id:oatpp::parser::Caret; over serialized buffer.
* @return - deserialized Object.
* @throws - depends on implementation.
*/
template<class Class>
typename Class::ObjectWrapper readFromCaret(oatpp::parser::Caret& caret) const {
@ -83,10 +118,12 @@ public:
}
/**
* This method will throw on error
* @tparam Class
* @param str
* @return
* Deserialize object.
* @tparam Class - object class.
* @param str - serialized data.
* @return - deserialized Object.
* @throws - &id:oatpp::parser::ParsingError;
* @throws - depends on implementation.
*/
template<class Class>
typename Class::ObjectWrapper readFromString(const oatpp::String& str) const {

View File

@ -37,7 +37,10 @@ namespace __class {
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Type::Properties
void Type::Properties::pushBack(Property* property) {
m_map.insert({property->name, property});
m_list.push_back(property);
@ -47,5 +50,55 @@ void Type::Properties::pushFrontAll(Properties* properties) {
m_map.insert(properties->m_map.begin(), properties->m_map.end());
m_list.insert(m_list.begin(), properties->m_list.begin(), properties->m_list.end());
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Type::Property
Type::Property::Property(Properties* properties, v_int64 pOffset, const char* pName, Type* pType)
: offset(pOffset)
, name(pName)
, type(pType)
{
properties->pushBack(this);
}
void Type::Property::set(void* object, const AbstractObjectWrapper& value) {
AbstractObjectWrapper* property = (AbstractObjectWrapper*)(((v_int64) object) + offset);
*property = value;
}
AbstractObjectWrapper Type::Property::get(void* object) {
AbstractObjectWrapper* property = (AbstractObjectWrapper*)(((v_int64) object) + offset);
return *property;
}
AbstractObjectWrapper& Type::Property::getAsRef(void* object) {
AbstractObjectWrapper* property = (AbstractObjectWrapper*)(((v_int64) object) + offset);
return *property;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Type
Type::Type(const char* pName, const char* pNameQualifier)
: name(pName)
, nameQualifier(pNameQualifier)
, creator(nullptr)
, properties(nullptr)
{}
Type::Type(const char* pName, const char* pNameQualifier, Creator pCreator)
: name(pName)
, nameQualifier(pNameQualifier)
, creator(pCreator)
, properties(nullptr)
{}
Type::Type(const char* pName, const char* pNameQualifier, Creator pCreator, Properties* pProperties)
: name(pName)
, nameQualifier(pNameQualifier)
, creator(pCreator)
, properties(pProperties)
{}
}}}}

View File

@ -36,20 +36,42 @@ namespace oatpp { namespace data { namespace mapping { namespace type {
class Type; // FWD
namespace __class {
/**
* Void Object Class.
*/
class Void {
public:
/**
* Name of the class - CLASS_NAME = "Void".
*/
static const char* const CLASS_NAME;
/**
* Get class type information.
* @return - &l:Type;
*/
static Type* getType();
};
}
/**
* PolymorphicWrapper holds std::shared_ptr to object, object static type, plus object dynamic type information.
* @tparam T - Object Type
*/
template <class T>
class PolymorphicWrapper {
protected:
std::shared_ptr<T> m_ptr;
public:
/**
* Static object type
*/
typedef T ObjectType;
public:
/**
* PolymorphicWrapper has no static object Class info.
* It treats object as of class &id:oatpp::data::mapping::type::__class::Void;.
*/
typedef __class::Void Class;
public:
@ -133,7 +155,11 @@ public:
explicit operator bool() const {
return m_ptr.operator bool();
}
/**
* Value type information.
* See &l:Type;.
*/
const Type* const valueType;
};
@ -142,12 +168,23 @@ template<class T, class F>
inline PolymorphicWrapper<T> static_wrapper_cast(const F& from){
return PolymorphicWrapper<T>(std::static_pointer_cast<T>(from.getPtr()), from.valueType);
}
/**
* ObjectWrapper holds std::shared_ptr to object, object static type, object static class information, plus object dynamic type information.
* @tparam T - Object type.
* @tparam Clazz - Static Object class information.
*/
template <class T, class Clazz>
class ObjectWrapper : public PolymorphicWrapper<T>{
public:
/**
* Object type.
*/
typedef T ObjectType;
public:
/**
* Static object class information.
*/
typedef Clazz Class;
public:
ObjectWrapper(const std::shared_ptr<T>& ptr, const type::Type* const valueType)
@ -202,105 +239,162 @@ public:
}
};
/**
* PolymorphicWrapper over &id:oatpp::base::Countable; object.
*/
typedef PolymorphicWrapper<oatpp::base::Countable> AbstractObjectWrapper;
/**
* Object type data.
*/
class Type {
public:
typedef AbstractObjectWrapper (*Creator)();
public:
class Property; // FWD
public:
/**
* Object type properties table.
*/
class Properties {
private:
std::unordered_map<std::string, Property*> m_map;
std::list<Property*> m_list;
public:
void pushBack(Property* property);
void pushFrontAll(Properties* properties);
/**
* get properties as unordered map for random access
* Add property to the end of the list.
* @param property
*/
void pushBack(Property* property);
/**
* Add all properties to the beginning of the list.
* @param properties
*/
void pushFrontAll(Properties* properties);
/**
* Get properties as unordered map for random access.
* @return reference to std::unordered_map of std::string to &id:oatpp::data::mapping::type::Type::Property;*.
*/
const std::unordered_map<std::string, Property*>& getMap() const {
return m_map;
}
/**
* get properties in ordered way
* Get properties in ordered way.
* @return std::list of &id:oatpp::data::mapping::type::Type::Property;*.
*/
const std::list<Property*>& getList() const {
return m_list;
}
};
//typedef std::unordered_map<std::string, Property*> Properties;
public:
/**
* Class to map object properties.
*/
class Property {
private:
const v_int64 offset;
public:
Property(Properties* properties, v_int64 pOffset, const char* pName, Type* pType)
: offset(pOffset)
, name(pName)
, type(pType)
{
properties->pushBack(this);
}
/**
* Constructor.
* @param properties - &l:Type::Properties;*. to push this property to.
* @param pOffset - memory offset of object field from object start address.
* @param pName - name of the property.
* @param pType - &l:Type; of the property.
*/
Property(Properties* properties, v_int64 pOffset, const char* pName, Type* pType);
/**
* Property name.
*/
const char* const name;
/**
* Property type.
*/
const Type* const type;
void set(void* object, const AbstractObjectWrapper& value) {
AbstractObjectWrapper* property = (AbstractObjectWrapper*)(((v_int64) object) + offset);
*property = value;
}
AbstractObjectWrapper get(void* object) {
AbstractObjectWrapper* property = (AbstractObjectWrapper*)(((v_int64) object) + offset);
return *property;
}
AbstractObjectWrapper& getAsRef(void* object) {
AbstractObjectWrapper* property = (AbstractObjectWrapper*)(((v_int64) object) + offset);
return *property;
}
/**
* Set value of object field mapped by this property.
* @param object - object address.
* @param value - value to set.
*/
void set(void* object, const AbstractObjectWrapper& value);
/**
* Get value of object field mapped by this property.
* @param object - object address.
* @return - value of the field.
*/
AbstractObjectWrapper get(void* object);
/**
* Get reference to ObjectWrapper of the object field.
* @param object - object address.
* @return - reference to ObjectWrapper of the object field.
*/
AbstractObjectWrapper& getAsRef(void* object);
};
public:
Type(const char* pName, const char* pNameQualifier)
: name(pName)
, nameQualifier(pNameQualifier)
, creator(nullptr)
, properties(nullptr)
{}
Type(const char* pName, const char* pNameQualifier, Creator pCreator)
: name(pName)
, nameQualifier(pNameQualifier)
, creator(pCreator)
, properties(nullptr)
{}
Type(const char* pName, const char* pNameQualifier, Creator pCreator, Properties* pProperties)
: name(pName)
, nameQualifier(pNameQualifier)
, creator(pCreator)
, properties(pProperties)
{}
/**
* Constructor.
* @param pName - type name.
* @param pNameQualifier - type name qualifier.
*/
Type(const char* pName, const char* pNameQualifier);
/**
* Constructor.
* @param pName - type name.
* @param pNameQualifier - type name qualifier.
* @param pCreator - function pointer of Creator - function to create instance of this type.
*/
Type(const char* pName, const char* pNameQualifier, Creator pCreator);
/**
* Constructor.
* @param pName - type name.
* @param pNameQualifier - type name qualifier.
* @param pCreator - function pointer of Creator - function to create instance of this type.
* @param pProperties - pointer to type properties.
*/
Type(const char* pName, const char* pNameQualifier, Creator pCreator, Properties* pProperties);
/**
* Type name.
*/
const char* const name;
/**
* Type name qualifier.
*/
const char* const nameQualifier;
/**
* List of type parameters - for templated types.
*/
std::list<Type*> params;
/**
* Creator - function to create instance of this type.
*/
const Creator creator;
/**
* Pointer to type properties.
*/
const Properties* const properties;
};

View File

@ -23,3 +23,26 @@
***************************************************************************/
#include "RequestExecutor.hpp"
namespace oatpp { namespace web { namespace client {
RequestExecutor::RequestExecutionError::RequestExecutionError(v_int32 errorCode, const char* message, v_int32 readErrorCode = 0)
: std::runtime_error(message)
, m_errorCode(errorCode)
, m_message(message)
, m_readErrorCode(readErrorCode)
{}
v_int32 RequestExecutor::RequestExecutionError::getErrorCode() const {
return m_errorCode;
}
const char* RequestExecutor::RequestExecutionError::getMessage() const {
return m_message;
}
v_int32 RequestExecutor::RequestExecutionError::getReadErrorCode() const {
return m_readErrorCode;
}
}}}

View File

@ -30,14 +30,36 @@
#include "oatpp/web/protocol/http/Http.hpp"
namespace oatpp { namespace web { namespace client {
/**
* Abstract RequestExecutor.
* RequestExecutor is class responsible for making http requests.
*/
class RequestExecutor {
public:
/**
* Convenience typedef for &id:oatpp::String;.
*/
typedef oatpp::String String;
/**
* Convenience typedef for &id:oatpp::async::Action;.
*/
typedef oatpp::async::Action Action;
public:
/**
* Convenience typedef for &id:oatpp::web::protocol::http::Protocol::Headers;.
*/
typedef oatpp::web::protocol::http::Protocol::Headers Headers;
/**
* Convenience typedef for &id:oatpp::web::protocol::http::incoming::Response;.
*/
typedef oatpp::web::protocol::http::incoming::Response Response;
/**
* Convenience typedef for &id:oatpp::web::protocol::http::outgoing::Body;.
*/
typedef oatpp::web::protocol::http::outgoing::Body Body;
public:
@ -55,65 +77,114 @@ public:
typedef Action (oatpp::async::AbstractCoroutine::*AsyncCallback)(const std::shared_ptr<Response>&);
typedef Action (oatpp::async::AbstractCoroutine::*AsyncConnectionCallback)(const std::shared_ptr<ConnectionHandle>&);
public:
/**
* Class representing Request Execution Error.
*/
class RequestExecutionError : public std::runtime_error {
public:
/**
* Error code for "can't connect" error.
*/
constexpr static const v_int32 ERROR_CODE_CANT_CONNECT = 1;
/**
* Error code for "can't parse starting line" error.
*/
constexpr static const v_int32 ERROR_CODE_CANT_PARSE_STARTING_LINE = 2;
/**
* Error code for "can't parse headers" error.
*/
constexpr static const v_int32 ERROR_CODE_CANT_PARSE_HEADERS = 3;
/**
* Error code for "can't read response" error.
*/
constexpr static const v_int32 ERROR_CODE_CANT_READ_RESPONSE = 4;
/**
* Error code for "no response" error.
*/
constexpr static const v_int32 ERROR_CODE_NO_RESPONSE = 5;
private:
v_int32 m_errorCode;
const char* m_message;
v_int32 m_readErrorCode;
public:
RequestExecutionError(v_int32 errorCode, const char* message, v_int32 readErrorCode = 0)
:std::runtime_error(message)
, m_errorCode(errorCode)
, m_message(message)
, m_readErrorCode(readErrorCode)
{}
v_int32 getErrorCode() const {
return m_errorCode;
}
const char* getMessage() const {
return m_message;
}
/**
* Constructor.
* @param errorCode - error code.
* @param message - error message.
* @param readErrorCode - io error code.
*/
RequestExecutionError(v_int32 errorCode, const char* message, v_int32 readErrorCode = 0);
/**
* Get error code.
* @return - error code.
*/
v_int32 getErrorCode() const;
/**
* Get error message.
* @return - error message.
*/
const char* getMessage() const;
/**
* This value is valid if errorCode == ERROR_CODE_CANT_READ_RESPONSE
* For more information about the read error you get check out:
* - oatpp::data::stream::IOStream for possible error codes
* - implementation of Connection provided by your ConnectionProvider for implementation-specific behaviour
* - &id:oatpp::data::stream::IOStream; for possible error codes.
* - Implementation-specific behaviour of corresponding Connection and ConnectionProvider.
*/
v_int32 getReadErrorCode() const {
return m_readErrorCode;
}
v_int32 getReadErrorCode() const;
};
public:
/**
* Obtain ConnectionHandle which then can be passed to execute()
* Obtain &l:RequestExecutor::ConnectionHandle; which then can be passed to &l:RequestExecutor::execute ();.
* @return std::shared_ptr to &l:RequestExecutor::ConnectionHandle;.
*/
virtual std::shared_ptr<ConnectionHandle> getConnection() = 0;
/**
* Same as getConnection but Async
* Same as &l:RequestExecutor::getConnection (); but Async.
* @param parentCoroutine - caller coroutine as &id:oatpp::async::AbstractCoroutine;*.
* @param callback - function pointer to asynchronous callback.
* @return - &id:oatpp::async::Action;.
*/
virtual Action getConnectionAsync(oatpp::async::AbstractCoroutine* parentCoroutine, AsyncConnectionCallback callback) = 0;
/**
* Execute http request.
* @param method - http method ["GET", "POST", "PUT", etc.].
* @param path - path to resource.
* @param headers - headers map.
* @param body - `std::shared_ptr` to Body object.
* @param connectionHandle - &l:RequestExecutor::ConnectionHandle;
* @return - &id:oatpp::web::protocol::http::incoming::Response;.
*/
virtual std::shared_ptr<Response> execute(const String& method,
const String& path,
const Headers& headers,
const std::shared_ptr<Body>& body,
const std::shared_ptr<ConnectionHandle>& connectionHandle = nullptr) = 0;
/**
* Same as &l:RequestExecutor::execute (); but Async.
* @param parentCoroutine - caller coroutine as &id:oatpp::async::AbstractCoroutine;*.
* @param callback - function pointer to asynchronous callback.
* @param method - http method ["GET", "POST", "PUT", etc.].
* @param path - path to resource.
* @param headers - headers map.
* @param body - `std::shared_ptr` to Body object.
* @param connectionHandle - &l:RequestExecutor::ConnectionHandle;
* @return - &id:oatpp::async::Action;.
*/
virtual Action executeAsync(oatpp::async::AbstractCoroutine* parentCoroutine,
AsyncCallback callback,
const String& method,