Commit 9e211ead authored by Martin Straka's avatar Martin Straka

Merge branch 'records-management-shared-code-changes' into 'develop'

Pulled Changes in Shared Code

See merge request !135
parents 34473ed6 c27e8eef
......@@ -26,7 +26,7 @@
#include "src/datovka_shared/log/log.h"
#include "src/datovka_shared/records_management/conversion.h"
QList<qint64> createIdList(const QStringList &strList, bool *ok)
QList<qint64> RecMgmt::createIdList(const QStringList &strList, bool *ok)
{
QList<qint64> idList;
bool iOk = false;
......
......@@ -26,11 +26,15 @@
#include <QList>
#include <QStringList>
/*!
namespace RecMgmt {
/*!
* @brief Convert list of strings into list of qint64.
*
* @param[in] strList String list.
* @param[out] ok Set to true if all entries are successfully converted.
* @return List if qint64.
*/
QList<qint64> createIdList(const QStringList &strList, bool *ok);
QList<qint64> createIdList(const QStringList &strList, bool *ok);
}
......@@ -30,13 +30,13 @@
#include "src/datovka_shared/records_management/io/records_management_connection.h"
/* Must be set to false for production releases. */
const bool RecordsManagementConnection::ignoreSslErrorsDflt = false;
const bool RecMgmt::Connection::ignoreSslErrorsDflt = false;
/*!
* @brief Converts service identifier onto service name.
*/
static
const QString &serviceName(enum RecordsManagementConnection::ServiceId srvcId)
const QString &serviceName(enum RecMgmt::Connection::ServiceId srvcId)
{
static const QString SrvServiceInfo(QStringLiteral("service_info"));
static const QString SrvUploadHierarchy(QStringLiteral("upload_hierarchy"));
......@@ -45,16 +45,16 @@ const QString &serviceName(enum RecordsManagementConnection::ServiceId srvcId)
static const QString InvalidService;
switch (srvcId) {
case RecordsManagementConnection::SRVC_SERVICE_INFO:
case RecMgmt::Connection::SRVC_SERVICE_INFO:
return SrvServiceInfo;
break;
case RecordsManagementConnection::SRVC_UPLOAD_HIERARCHY:
case RecMgmt::Connection::SRVC_UPLOAD_HIERARCHY:
return SrvUploadHierarchy;
break;
case RecordsManagementConnection::SRVC_UPLOAD_FILE:
case RecMgmt::Connection::SRVC_UPLOAD_FILE:
return SrvUploadFile;
break;
case RecordsManagementConnection::SRVC_STORED_FILES:
case RecMgmt::Connection::SRVC_STORED_FILES:
return SrvStoredFiles;
break;
default:
......@@ -68,8 +68,7 @@ const QString &serviceName(enum RecordsManagementConnection::ServiceId srvcId)
* @brief Create URL from base URL and from service identifier.
*/
static
QUrl constructUrl(QString baseUrl,
enum RecordsManagementConnection::ServiceId srvcId)
QUrl constructUrl(QString baseUrl, enum RecMgmt::Connection::ServiceId srvcId)
{
const QString &srvcName(serviceName(srvcId));
......@@ -83,7 +82,7 @@ QUrl constructUrl(QString baseUrl,
return QUrl(baseUrl + srvcName);
}
RecordsManagementConnection::RecordsManagementConnection(bool ignoreSslErrors,
RecMgmt::Connection::Connection(bool ignoreSslErrors,
QObject *parent)
: QObject(parent),
m_baseUrlStr(),
......@@ -97,14 +96,14 @@ RecordsManagementConnection::RecordsManagementConnection(bool ignoreSslErrors,
this, SLOT(handleSslErrors(QNetworkReply *, const QList<QSslError>)));
}
void RecordsManagementConnection::setConnection(const QString &baseUrl,
void RecMgmt::Connection::setConnection(const QString &baseUrl,
const QString &token)
{
m_baseUrlStr = baseUrl;
m_tokenStr = token;
}
bool RecordsManagementConnection::communicate(enum ServiceId srvcId,
bool RecMgmt::Connection::communicate(enum ServiceId srvcId,
const QByteArray &requestData, QByteArray &replyData, QObject *cbObj)
{
debugFuncCall();
......@@ -125,7 +124,7 @@ bool RecordsManagementConnection::communicate(enum ServiceId srvcId,
cbObj, SLOT(onUploadProgress(qint64, qint64)));
}
bool retVal = waitReplyFinished(reply, m_timeOut);
bool retVal = waitReplyFinished(reply, m_timeOut, cbObj);
if (cbObj != Q_NULLPTR) {
cbObj->disconnect(SIGNAL(callAbort()), reply, SLOT(abort()));
......@@ -180,7 +179,7 @@ bool readAndAddCert(const QByteArray &certData, QSsl::EncodingFormat fmt)
return true;
}
bool RecordsManagementConnection::addTrustedCertificate(const QString &filePath)
bool RecMgmt::Connection::addTrustedCertificate(const QString &filePath)
{
QByteArray certData;
......@@ -218,7 +217,7 @@ bool RecordsManagementConnection::addTrustedCertificate(const QString &filePath)
return false;
}
void RecordsManagementConnection::handleSslErrors(QNetworkReply *reply,
void RecMgmt::Connection::handleSslErrors(QNetworkReply *reply,
const QList<QSslError> &errors)
{
Q_UNUSED(reply);
......@@ -246,8 +245,7 @@ void RecordsManagementConnection::handleSslErrors(QNetworkReply *reply,
}
}
QNetworkRequest RecordsManagementConnection::createRequest(
enum ServiceId srvcId) const
QNetworkRequest RecMgmt::Connection::createRequest(enum ServiceId srvcId) const
{
debugFuncCall();
......@@ -265,8 +263,8 @@ QNetworkRequest RecordsManagementConnection::createRequest(
return request;
}
QNetworkReply *RecordsManagementConnection::sendRequest(
const QNetworkRequest &request, const QByteArray &data)
QNetworkReply *RecMgmt::Connection::sendRequest(const QNetworkRequest &request,
const QByteArray &data)
{
debugFuncCall();
......@@ -297,8 +295,8 @@ QNetworkReply *RecordsManagementConnection::sendRequest(
return reply;
}
bool RecordsManagementConnection::waitReplyFinished(QNetworkReply *reply,
unsigned int timeOut)
bool RecMgmt::Connection::waitReplyFinished(QNetworkReply *reply,
unsigned int timeOut, QObject *cbObj)
{
if (Q_UNLIKELY(reply == Q_NULLPTR)) {
Q_ASSERT(0);
......@@ -309,26 +307,46 @@ bool RecordsManagementConnection::waitReplyFinished(QNetworkReply *reply,
QTimer timer;
timer.setSingleShot(true);
QEventLoop eventLoop;
if (cbObj != Q_NULLPTR) {
connect(&timer, SIGNAL(timeout()), cbObj, SLOT(onTimeout()));
}
connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
do {
timer.start(timeOut);
eventLoop.exec();
if (timer.isActive()) {
/*
* Repeat if a callback object is present and while
* communication has not been stopped.
* Exit if no callback object is specified.
*/
} while ((cbObj != Q_NULLPTR) && reply->isRunning());
if (cbObj != Q_NULLPTR) {
timer.disconnect(SIGNAL(timeout()), cbObj, SLOT(onTimeout()));
}
timer.disconnect(SIGNAL(timeout()), &eventLoop, SLOT(quit()));
reply->disconnect(SIGNAL(finished()), &eventLoop, SLOT(quit()));
if (reply->isFinished()) {
timer.stop();
return true;
} else {
/* Timeout expired. */
disconnect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
logErrorNL("%s",
"Connection timed out. Check your internet connection.");
reply->abort();
}
return false;
/*
* The value QNetworkReply::OperationCanceledError means cancelled via
* abort() or close().
*/
return reply->error() == QNetworkReply::NoError;
}
bool RecordsManagementConnection::processReply(QNetworkReply *reply,
bool RecMgmt::Connection::processReply(QNetworkReply *reply,
QByteArray &replyData)
{
debugFuncCall();
......
......@@ -30,13 +30,58 @@
#include <QObject>
#include <QString>
/*!
namespace RecMgmt {
#if 0
/*!
* @brief An connection timeout handler prototype.
*
* @note There is a problem in Qt with multiple inheritance from
* QObject classes. E.g. we cannot use this class to directly derive
* dialogues from it. This class serves as an illustration how a
* progress handler (callback) object could look like. See
* https://stackoverflow.com/a/2998374 on pure virtual slots
* https://stackoverflow.com/a/8578921 on QObject multiple inheritance
*/
class ProgressHandler : protected QObject {
Q_OBJECT
signals:
/*!
* @brief When this signal is emitted then the network
* communication is directly aborted.
*/
void callAbort(void);
public slots:
/*!
* @brief This slot is connected to the network reply object and
* handles the ingoing communication.
*/
void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
/*!
* @brief This slot is connected to the network reply object and
* handles the outgoing communication.
*/
void onUploadProgress(qint64 bytesSent, qint64 bytesTotal);
/*!
* @brief This slot is connected to the internal timer object
* and should watch the progress of the data transfer. It
* should be able to emit the callAbort() signal.
*/
void onTimeout(void);
};
#endif
/*!
* @brief Encapsulates connection to records management service.
*/
class RecordsManagementConnection : public QObject {
class Connection : public QObject {
Q_OBJECT
public:
public:
/*!
* @brief Records management service identifiers.
*/
......@@ -56,7 +101,7 @@ public:
/*!
* @brief Constructor.
*/
explicit RecordsManagementConnection(bool ignoreSslErrors = false,
explicit Connection(bool ignoreSslErrors = false,
QObject *parent = Q_NULLPTR);
/*!
......@@ -80,11 +125,12 @@ public:
* @param[in] srvcId Srvice identifier.
* @param[in] requestData Data to be sent.
* @param[out] replyData Data from the reply.
* @param[in,out] cbObj Callback object to be connected to the internal
* network reply object.
* @param[in,out] cbObj Callback object to be connected to the
* internal network reply object.
*/
bool communicate(enum ServiceId srvcId, const QByteArray &requestData,
QByteArray &replyData, QObject *cbObj = Q_NULLPTR);
bool communicate(enum ServiceId srvcId,
const QByteArray &requestData, QByteArray &replyData,
QObject *cbObj = Q_NULLPTR);
/*!
* @brief Add certificate to certificate store.
......@@ -95,7 +141,7 @@ public:
static
bool addTrustedCertificate(const QString &filePath);
signals:
signals:
/*!
* @brief Emitted when some error during communication occurs.
*
......@@ -103,15 +149,15 @@ signals:
*/
void connectionError(const QString &message);
private slots:
private slots:
void handleSslErrors(QNetworkReply *reply,
const QList<QSslError> &errors);
private:
private:
/*!
* @brief Create network request.
*
* @param[in] srvcId Srvice identifier.
* @param[in] srvcId Service identifier.
* @return Created network request.
*/
QNetworkRequest createRequest(enum ServiceId srvcId) const;
......@@ -127,18 +173,22 @@ private:
const QByteArray &data);
/*!
* @brief Blocks until all data are sent and received or until timed out.
* @brief Blocks until all data are sent and received or until
* timed out.
*
* @note The reply is aborted when it times out. In this case the reply
* is not deleted.
* @note The reply is aborted when it times out and no callback
* object is specified. In this case the reply is not deleted.
*
* @param[in,out] reply Communication context.
* @param[in] timeOut Communication timeout.
* @param[in,out] cbObj Callback object to be connected to the
* internal timer object.
* @return True if all data have been received,
* false if communication timed out.
*/
static
bool waitReplyFinished(QNetworkReply *reply, unsigned int timeOut);
bool waitReplyFinished(QNetworkReply *reply,
unsigned int timeOut, QObject *cbObj);
/*!
* @brief Process reply data.
......@@ -157,4 +207,6 @@ private:
unsigned int m_timeOut; /*!< Communication timeout. */
bool m_ignoreSslErrors; /*!< True if SSL errors should be ignored. */
QNetworkAccessManager m_nam; /*!< Network access manager. */
};
};
}
......@@ -41,35 +41,35 @@ static const QString strAlreadyPresent("ALREADY_PRESENT");
static const QString strLimitExceeded("LIMIT_EXCEEDED");
static const QString strUnspecified("UNSPECIFIED");
ErrorEntry::ErrorEntry(void)
RecMgmt::ErrorEntry::ErrorEntry(void)
: m_code(ERR_NO_ERROR),
m_description()
{
}
ErrorEntry::ErrorEntry(enum Code code, const QString &description)
RecMgmt::ErrorEntry::ErrorEntry(enum Code code, const QString &description)
: m_code(code),
m_description(description)
{
}
ErrorEntry::ErrorEntry(const ErrorEntry &ee)
: m_code(ee.m_code),
m_description(ee.m_description)
RecMgmt::ErrorEntry::ErrorEntry(const ErrorEntry &other)
: m_code(other.m_code),
m_description(other.m_description)
{
}
enum ErrorEntry::Code ErrorEntry::code(void) const
enum RecMgmt::ErrorEntry::Code RecMgmt::ErrorEntry::code(void) const
{
return m_code;
}
const QString &ErrorEntry::description(void) const
const QString &RecMgmt::ErrorEntry::description(void) const
{
return m_description;
}
bool ErrorEntry::fromJsonVal(const QJsonValue *jsonVal)
bool RecMgmt::ErrorEntry::fromJsonVal(const QJsonValue *jsonVal)
{
if (jsonVal == Q_NULLPTR) {
Q_ASSERT(0);
......@@ -107,7 +107,7 @@ bool ErrorEntry::fromJsonVal(const QJsonValue *jsonVal)
return true;
}
bool ErrorEntry::toJsonVal(QJsonValue *jsonVal) const
bool RecMgmt::ErrorEntry::toJsonVal(QJsonValue *jsonVal) const
{
if (jsonVal == Q_NULLPTR) {
Q_ASSERT(0);
......@@ -126,7 +126,7 @@ bool ErrorEntry::toJsonVal(QJsonValue *jsonVal) const
return true;
}
QString ErrorEntry::trVerbose(void) const
QString RecMgmt::ErrorEntry::trVerbose(void) const
{
QString retStr(codeToString(m_code) + QLatin1String(" ("));
QString explanation;
......@@ -166,7 +166,7 @@ QString ErrorEntry::trVerbose(void) const
return retStr;
}
const QString &ErrorEntry::codeToString(enum Code code)
const QString &RecMgmt::ErrorEntry::codeToString(enum Code code)
{
switch (code) {
case ERR_NO_ERROR:
......@@ -201,18 +201,19 @@ const QString &ErrorEntry::codeToString(enum Code code)
}
}
enum ErrorEntry::Code ErrorEntry::stringToCode(const QString &str, bool *ok)
enum RecMgmt::ErrorEntry::Code RecMgmt::ErrorEntry::stringToCode(
const QString &str, bool *ok)
{
if (str == strNoError) {
if (ok != Q_NULLPTR) {
*ok = true;
}
return ErrorEntry::ERR_NO_ERROR;
return ERR_NO_ERROR;
} else if (str == strMalformedRequest) {
if (ok != Q_NULLPTR) {
*ok = true;
}
return ErrorEntry::ERR_MALFORMED_REQUEST;
return ERR_MALFORMED_REQUEST;
} else if (str == strMissingIdentifier) {
if (ok != Q_NULLPTR) {
*ok = true;
......@@ -227,26 +228,26 @@ enum ErrorEntry::Code ErrorEntry::stringToCode(const QString &str, bool *ok)
if (ok != Q_NULLPTR) {
*ok = true;
}
return ErrorEntry::ERR_UNSUPPORTED_FILE_FORMAT;
return ERR_UNSUPPORTED_FILE_FORMAT;
} else if (str == strAlreadyPresent) {
if (ok != Q_NULLPTR) {
*ok = true;
}
return ErrorEntry::ERR_ALREADY_PRESENT;
return ERR_ALREADY_PRESENT;
} else if (str == strLimitExceeded) {
if (ok != Q_NULLPTR) {
*ok = true;
}
return ErrorEntry::ERR_LIMIT_EXCEEDED;
return ERR_LIMIT_EXCEEDED;
} else if (str == strUnspecified) {
if (ok != Q_NULLPTR) {
*ok = true;
}
return ErrorEntry::ERR_UNSPECIFIED;
return ERR_UNSPECIFIED;
} else {
if (ok != Q_NULLPTR) {
*ok = false;
}
return ErrorEntry::ERR_UNSPECIFIED;
return ERR_UNSPECIFIED;
}
}
......@@ -28,13 +28,15 @@
class QJsonValue; /* Forward declaration. */
/*!
namespace RecMgmt {
/*!
* @brief Encapsulates any error entry.
*/
class ErrorEntry {
class ErrorEntry {
Q_DECLARE_TR_FUNCTIONS(ErrorEntry)
public:
public:
/*!
* @brief Error codes.
*/
......@@ -65,9 +67,9 @@ public:
/*!
* @brief Copy constructor.
*
* @param[in] ee Error entry.
* @param[in] other Error entry.
*/
ErrorEntry(const ErrorEntry &ee);
ErrorEntry(const ErrorEntry &other);
/*!
* @brief Returns error code.
......@@ -111,7 +113,7 @@ public:
*/
QString trVerbose(void) const;
private:
private:
/*!
* @brief Converts error code into string as used in JSON.
*
......@@ -133,4 +135,6 @@ private:
enum Code m_code; /*!< Error code. */
QString m_description; /*!< Error description as obtained from JSON. */
};
};
}
......@@ -29,7 +29,8 @@
#include "src/datovka_shared/log/log.h"
#include "src/datovka_shared/records_management/json/helper.h"
bool JsonHelper::readRootObject(const QByteArray &json, QJsonObject &jsonObj)
bool RecMgmt::JsonHelper::readRootObject(const QByteArray &json,
QJsonObject &jsonObj)
{
QJsonDocument jsonDoc;
{
......@@ -56,8 +57,8 @@ bool JsonHelper::readRootObject(const QByteArray &json, QJsonObject &jsonObj)
return true;
}
bool JsonHelper::readValue(const QJsonObject &jsonObj, const QString &key,
QJsonValue &jsonVal)
bool RecMgmt::JsonHelper::readValue(const QJsonObject &jsonObj,
const QString &key, QJsonValue &jsonVal)
{
if (jsonObj.isEmpty() || key.isEmpty()) {
logErrorNL("%s", "JSON object or sought key is empty.");
......@@ -74,8 +75,8 @@ bool JsonHelper::readValue(const QJsonObject &jsonObj, const QString &key,
return true;
}
bool JsonHelper::readInt(const QJsonObject &jsonObj, const QString &key,
int &val, bool acceptNull)
bool RecMgmt::JsonHelper::readInt(const QJsonObject &jsonObj,
const QString &key, int &val, bool acceptNull)
{
QJsonValue jsonVal;
if (!readValue(jsonObj, key, jsonVal)) {
......@@ -96,8 +97,8 @@ bool JsonHelper::readInt(const QJsonObject &jsonObj, const QString &key,
return true;
}
bool JsonHelper::readString(const QJsonObject &jsonObj, const QString &key,
QString &val, bool acceptNull)
bool RecMgmt::JsonHelper::readString(const QJsonObject &jsonObj,
const QString &key, QString &val, bool acceptNull)
{
QJsonValue jsonVal;
if (!readValue(jsonObj, key, jsonVal)) {
......@@ -117,8 +118,8 @@ bool JsonHelper::readString(const QJsonObject &jsonObj, const QString &key,
return true;
}
bool JsonHelper::readArray(const QJsonObject &jsonObj, const QString &key,
QJsonArray &arr, bool acceptNull)
bool RecMgmt::JsonHelper::readArray(const QJsonObject &jsonObj,
const QString &key, QJsonArray &arr, bool acceptNull)
{
QJsonValue jsonVal;
if (!readValue(jsonObj, key, jsonVal)) {
......@@ -138,8 +139,8 @@ bool JsonHelper::readArray(const QJsonObject &jsonObj, const QString &key,
return true;
}
bool JsonHelper::readStringList(const QJsonObject &jsonObj, const QString &key,
QStringList &val, bool acceptNull)
bool RecMgmt::JsonHelper::readStringList(const QJsonObject &jsonObj,
const QString &key, QStringList &val, bool acceptNull)
{
QJsonArray jsonArr;
if (!readArray(jsonObj, key, jsonArr, acceptNull)) {
......@@ -165,7 +166,7 @@ bool JsonHelper::readStringList(const QJsonObject &jsonObj, const QString &key,
return true;
}
QString JsonHelper::toIndentedString(const QByteArray &json)
QString RecMgmt::JsonHelper::toIndentedString(const QByteArray &json)
{
if (json.isEmpty()) {
return QString();
......
......@@ -28,17 +28,19 @@
#include <QString>
#include <QStringList>
/*!
namespace RecMgmt {
/*!
* @brief JSON conversion helper functions.
*/
class JsonHelper {
private:
class JsonHelper {
private:
/*!
* @brief Private constructor.
*/
JsonHelper(void);
public:
public:
/*!
* @brief Reads a JSON object which comprises the document.
*
......@@ -47,7 +49,8 @@ public:
* @return True on success, false else.
*/
static
bool readRootObject(const QByteArray &json, QJsonObject &jsonObj);
bool readRootObject(const QByteArray &json,
QJsonObject &jsonObj);
/*!
* @brief Searches for a value on JSON object.
......@@ -88,7 +91,7 @@ public:
QString &val, bool acceptNull);
/*!
* @brief Reads an arry value from supplied JSON object.
* @brief Reads an array value from supplied JSON object.
*
* @param[in] jsonObj JSON object.
* @param[in] key Key identifying the string.
......@@ -121,4 +124,6 @@ public:
*/
static
QString toIndentedString(const QByteArray &json);
};
};
}
......@@ -35,49 +35,50 @@ const QString keyName("name");
static
const QString keyTokenName("token_name");
ServiceInfoResp::ServiceInfoResp(void)
RecMgmt::ServiceInfoResp::ServiceInfoResp(void)
: m_logoSvg(),
m_name(),
m_tokenName()
{
}
ServiceInfoResp::ServiceInfoResp(const QByteArray &logoSvg, const QString &name,
const QString &tokenName)
RecMgmt::ServiceInfoResp::ServiceInfoResp(const QByteArray &logoSvg,
const QString &name, const QString &tokenName)
: m_logoSvg(logoSvg),
m_name(name),
m_tokenName(tokenName)
{
}
ServiceInfoResp::ServiceInfoResp(const ServiceInfoResp &sir)
: m_logoSvg(sir.m_logoSvg),
m_name(sir.m_name),
m_tokenName(sir.m_tokenName)
RecMgmt::ServiceInfoResp::ServiceInfoResp(const ServiceInfoResp &other)
: m_logoSvg(other.m_logoSvg),
m_name(other.m_name),
m_tokenName(other.m_tokenName)
{
}
const QByteArray &ServiceInfoResp::logoSvg(void) const
const QByteArray &RecMgmt::ServiceInfoResp::logoSvg(void) const
{
return m_logoSvg;
}
const QString &ServiceInfoResp::name(void) const
const QString &RecMgmt::ServiceInfoResp::name(void) const
{
return m_name;
}
const QString &ServiceInfoResp::tokenName(void) const
const QString &RecMgmt::ServiceInfoResp::tokenName(void) const
{
return m_tokenName;