325 lines
13 KiB
C++
Executable File
325 lines
13 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 <QDir>
|
|
#include <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().underlying();
|
|
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
|