Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Services/FileManagement/handler_file_content.cpp
T

325 lines
12 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Handler for file content
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-04-03
*/
#include "handler_file_content.h"
#include "object_file_content.h"
#include "main_handler.h"
#include "flm_db.h"
#include "convert_db_to_dds.h"
#include <QtCore/QDir>
#include <QtCore/QFile>
//----------------------------------------------------------------------------------------------------------------------------
namespace FileManagement
{
HandlerFileContent::HandlerFileContent(MainHandler *mainHandler)
: Base(mainHandler, getLogger("HandlerFileContent"))
, Interface::Fts::FileContentModifyRequestHandler(fts())
, Interface::Fts::FileContentRemoveRequestHandler(fts())
, Interface::Fts::FileContentExportRequestHandler(fts())
, Interface::Fts::FileContentChangeStatusRequestHandler(fts())
, Interface::Fts::GetFileContentDataRequestHandler(fts())
, Interface::Fts::FileContentSetUsedRequestHandler(fts())
{
connect(db().get(), &DatabaseInterface::notifyDeleteFileContent, this, &HandlerFileContent::onDbDeletedFileContent);
connect(db().get(), &DatabaseInterface::notifyInsertFileContent, this, &HandlerFileContent::onDbInsertedFileContent);
connect(db().get(), &DatabaseInterface::notifyUpdateFileContent, this, &HandlerFileContent::onDbUpdatedFileContent);
}
//----------------------------------------------------------------------------------------------------------------------------
HandlerFileContent::~HandlerFileContent()
{
qDeleteAll(m_objectFileContentMap);
}
//----------------------------------------------------------------------------------------------------------------------------
bool HandlerFileContent::init()
{
// create file content objects
auto cb = [this] (const Database::FlmFileContent &data)
{
ObjectFileContent *ifs(new ObjectFileContent(convert(data), m_mainHandler));
// TODO: not a good idea to load the whole file content from database...
// load on demand and store data in temporary file (for filesize > 1MB or so)
//ifs->setContent(LtsUtils::convert<std::vector<uint8_t>>(data.content));
//DEBUG_LOG(m_logger) << "Content size for id = " << data.id << " : " << data.content.size();
m_objectFileContentMap.insert(ifs->getId(), ifs);
ifs->onPublishData();
};
if (!db()->select(cb))
{
ERROR_LOG(m_logger) << "Error reading data from database!";
return false;
}
INFO_LOG(m_logger) << "m_ObjectFileContentMap.size() = " << m_objectFileContentMap.size();
return true;
}
//----------------------------------------------------------------------------------------------------------------------------
void HandlerFileContent::onFileContentModifyRequest(const rti::core::SampleIdentity &cookie,
const FileManagement::FileContentModifyRequest &request)
{
auto ret = request.id > 0 ? fileContentModifyRequest(request) : fileContentCreateRequest(request);
if (ret.error())
WARNING_LOG(m_logger) << ret();
fts()->fileContentModifyReply(cookie, ret);
}
//----------------------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject HandlerFileContent::fileContentCreateRequest(const FileContentModifyRequest &request)
{
ObjectFileContent *ifs(new ObjectFileContent(m_mainHandler));
Core::FunctionReplyObject ret = ifs->createObject(request);
if (ret.error())
delete ifs;
else
m_objectFileContentMap.insert(ifs->getId(), ifs);
return ret;
}
//----------------------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject HandlerFileContent::fileContentModifyRequest(const FileManagement::FileContentModifyRequest &request)
{
ObjectFileContent *ifs = m_objectFileContentMap.value(request.id);
if (ifs == nullptr)
return Core::FunctionReplyObject(request.id, tr_lts("dds", "FileContent with id %1 not found")).arg(request.id);
return ifs->updateObject(request);
}
//----------------------------------------------------------------------------------------------------------------------------
void HandlerFileContent::onFileContentChangeStatusRequest(const rti::core::SampleIdentity &cookie,
const FileManagement::FileContentChangeStatusRequest &request)
{
ObjectFileContent *ifs = m_objectFileContentMap.value(request.id);
if (ifs == nullptr)
{
Core::FunctionReplyObject ret = Core::FunctionReplyObject(request.id, tr_lts("dds", "FileContent with id %1 not found")).arg(request.id);
fts()->fileContentChangeStatusReply(cookie, ret);
return;
}
Core::FunctionReplyObject ret = ifs->changeStatus(request);
if (ret.error())
ERROR_LOG(m_logger) << ret();
fts()->fileContentChangeStatusReply(cookie, ret);
}
//----------------------------------------------------------------------------------------------------------------------------
void HandlerFileContent::onFileContentRemoveRequest(const rti::core::SampleIdentity &cookie,
const Core::RemoveElementRequest &request)
{
auto ret = fileContentRemoveRequest(request);
if (ret.error())
WARNING_LOG(m_logger) << ret();
fts()->fileContentRemoveReply(cookie, ret);
}
Core::FunctionReplyObject HandlerFileContent::fileContentRemoveRequest(const Core::RemoveElementRequest &request)
{
ObjectFileContent *ifs = m_objectFileContentMap.value(request.id);
if (ifs == nullptr)
return Core::FunctionReplyObject(request.id, tr_lts("dds", "FileContent with id %1 not found")).arg(request.id);
if (m_mainHandler->dds()->topicLockMaster()->isLocked(ifs->getData(), m_mainHandler->exerciseId()))
return Core::FunctionReplyObject(request.id, tr_lts("dds", "FileContent '%1' is used by another user!")).arg(ifs->getName());
auto ret = ifs->removeObject();
if (!ret.error())
{
// delete ObjectFileContent
delete ifs;
m_objectFileContentMap.remove(request.id);
}
return ret;
}
//----------------------------------------------------------------------------------------------------------------------------
void HandlerFileContent::onFileContentExportRequest(const rti::core::SampleIdentity &cookie,
const FileManagement::FileContentExportRequest &request)
{
Core::FunctionReplyObject ret;
ObjectFileContent *ifs = m_objectFileContentMap.value(request.id);
if (ifs == nullptr)
{
ret = Core::FunctionReplyObject(request.id, tr_lts("dds", "FileContent with id %1 not found")).arg(request.id);
fts()->fileContentExportReply(cookie, ret);
return;
}
// get content on demand from DB
Database::FlmFileContent flmContent;
if (!db()->selectFlmFileContent(request.id, flmContent))
ret = Core::FunctionReplyObject(request.id, tr_lts("dds", "FileContent with id %1 not found in database")).arg(request.id);
QByteArray content = flmContent.content;
DEBUG_LOG(m_logger) << "Content size: " << content.size();
// creating an unique file name: temp path + folderId + file name + file extension (NN_FileName.FileExt)
QString fileName = QDir::tempPath() + QLatin1Char('/') + QString::number(ifs->getFolderId()) + QLatin1Char('-');
fileName += QString::fromStdString(ifs->getData().name).simplified().replace(QLatin1Char(' '), QLatin1Char('_'));
// add extension
FileType fileType = ifs->getData().fileType;
QString fileExt = m_mainHandler->getHandlerFileTypeInfo()->getFileExtension(fileType);
if (!fileExt.isEmpty())
fileName += QLatin1Char('.') + fileExt;
DEBUG_LOG(m_logger) << "Trying to export File Content to " << fileName;
// save content
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly))
{
ret = Core::FunctionReplyObject(request.id, tr_lts("dds", "Failed to write to %1")).arg(fileName);
fts()->fileContentExportReply(cookie, ret);
delete ifs;
return;
}
file.write(content);
file.close();
DEBUG_LOG(m_logger) << "Successfully exported File Content to " << fileName;
// update exportFileName
ifs->setExportFileName(fileName.toStdString());
// publish the modified object
ifs->onPublishData();
fts()->fileContentExportReply(cookie, ret);
return;
}
//----------------------------------------------------------------------------------------------------------------------------
void HandlerFileContent::onGetFileContentDataRequest(const rti::core::SampleIdentity &cookie,
const GetFileContentDataRequest &request)
{
Core::FunctionReplyObject fro;
GetFileContentDataReply reply;
ObjectFileContent *ifs = m_objectFileContentMap.value(request.fileContentId);
if (ifs)
{
reply.id = ifs->getId();
// get content on demand from DB
Database::FlmFileContent flmContent;
if (!db()->selectFlmFileContent(request.fileContentId, flmContent))
fro = Core::FunctionReplyObject(request.fileContentId, tr_lts("dds", "File content with id %1 not found in database")).arg(request.fileContentId);
/* no need to set content of object
else
ifs->setContent(LtsUtils::convert<std::vector<uint8_t>>(flmContent.content));
if (ifs->getContent().size() <= 0)
fro = Core::FunctionReplyObject(request.fileContentId(), tr_lts("dds", "No content available"));
else
reply.content(ifs->getContent());
*/
if (flmContent.content.size() <= 0)
fro = Core::FunctionReplyObject(request.fileContentId, tr_lts("dds", "No content available"));
else
reply.content = LtsUtils::convert<std::vector<uint8_t>>(flmContent.content);
}
else
fro = Core::FunctionReplyObject(request.fileContentId, tr_lts("dds", "No valid id = %1 for retrieving file content")).arg(request.fileContentId);
if (fro.error())
{
reply.id = fro.id();
reply.errorString = fro.str();
reply.errorParams = fro.args();
}
DEBUG_LOG(m_logger) << "Got content size: " << reply.content.size();
fts()->getFileContentDataReply(cookie, reply);
}
//----------------------------------------------------------------------------------------------------------------------------
void HandlerFileContent::onDbDeletedFileContent(const QVariant &id_)
{
int id = id_.toInt();
DEBUG_LOG(m_logger) << "DB deleted File Content with id: " << id;
if (!dts()->removeFileContentByKey(id))
ERROR_LOG(m_logger) << "FileContent can not be taken from DDS, id = " << id;
}
//----------------------------------------------------------------------------------------------------------------------------
void HandlerFileContent::onDbInsertedFileContent(const QVariant &id_)
{
int id = id_.toInt();
DEBUG_LOG(m_logger) << "DB inserted File Content with id: " << id;
if (!m_objectFileContentMap.contains(id))
initByDbId(id);
}
//----------------------------------------------------------------------------------------------------------------------------
void HandlerFileContent::onDbUpdatedFileContent(const QVariant &id_)
{
int id = id_.toInt();
DEBUG_LOG(m_logger) << "DB updated File Content with id: " << id;
initByDbId(id);
}
//----------------------------------------------------------------------------------------------------------------------------
bool HandlerFileContent::initByDbId(int dbId)
{
Database::FlmFileContent data;
DEBUG_LOG(m_logger) << "Reading FileContent from database!";
if (!db()->selectFlmFileContent(dbId, data))
{
ERROR_LOG(m_logger) << "Error reading data from database: id not found " << dbId;
return false;
}
// create file content object
if (data.id == dbId)
{
ObjectFileContent *ifs(new ObjectFileContent(convert(data), m_mainHandler));
//ifs->setContent(LtsUtils::convert<std::vector<uint8_t>>(data.content));
m_objectFileContentMap.insert(ifs->getId(), ifs);
ifs->onPublishData();
}
return true;
}
//----------------------------------------------------------------------------------------------------------------------------
void HandlerFileContent::onFileContentSetUsedRequest(const rti::core::SampleIdentity &cookie,
const FileManagement::FileContentSetUsedRequest &request)
{
ObjectFileContent *ifs = m_objectFileContentMap.value(request.id);
if (ifs == nullptr)
{
Core::FunctionReplyObject ret = Core::FunctionReplyObject(request.id, tr_lts("dds", "FileContent with id %1 not found")).arg(request.id);
fts()->fileContentSetUsedReply(cookie, ret);
return;
}
Core::FunctionReplyObject ret = ifs->setUsedBy(request);
if (ret.error())
ERROR_LOG(m_logger) << ret();
fts()->fileContentSetUsedReply(cookie, ret);
}
} // Namespace FileManagement