/** * @RDE_HEADER@ * Handler for folders * $Id$ * $HeadURL$ * $Author$ * Created by Iuliana Ojog, SLSE, 2017-04-03 */ #include "handler_folder.h" #include "object_folder.h" #include "handler_file_content.h" #include "object_file_content.h" #include "main_handler.h" #include "convert_db_to_dds.h" #include "flm_db.h" #include namespace FileManagement { HandlerFolder::HandlerFolder(MainHandler *mainHandler) : Base(mainHandler, getLogger("HandlerFolder")) , Interface::Fts::FolderModifyRequestHandler(fts()) , Interface::Fts::FolderRemoveRequestHandler(fts()) , Interface::Fts::PathCreateRequestHandler(fts()) , Interface::Fts::FileContentRemoveRequestHandler(fts()) { connect(db().get(), &DatabaseInterface::notifyDeleteFolder, this, &HandlerFolder::onDbDeletedFolder); connect(db().get(), &DatabaseInterface::notifyInsertFolder, this, &HandlerFolder::onDbInsertedFolder); connect(db().get(), &DatabaseInterface::notifyUpdateFolder, this, &HandlerFolder::onDbUpdatedFolder); } HandlerFolder::~HandlerFolder() { qDeleteAll(m_objectFolderMap); } bool HandlerFolder::init() { bool bRet = true; // create file type objects auto cb = [this, &bRet] (const Database::FlmFolder &data) { ObjectFolder *ifs(new ObjectFolder(m_mainHandler)); Core::FunctionReplyObject ret = ifs->createObject(convert(data)); if (ret.error()) { delete ifs; ERROR_LOG(m_logger) << ret(); bRet = false; return; } m_objectFolderMap.insert(ifs->getId(), ifs); }; if (!db()->select(cb) || !bRet) { ERROR_LOG(m_logger) << "Error reading data from database!"; return false; } DEBUG_LOG(m_logger) << "m_objectFolderMap.size() = " << m_objectFolderMap.size(); return true; } //--------------------------------------------------- void HandlerFolder::onFolderModifyRequest(const rti::core::SampleIdentity &cookie, const FileManagement::FolderModifyRequest &request) { auto ret = request.id() > 0 ? folderModifyRequest(request) : folderCreateRequest(request); if (ret.error()) WARNING_LOG(m_logger) << ret(); fts()->folderModifyReply(cookie, ret); } //--------------------------------------------------- Core::FunctionReplyObject HandlerFolder::folderCreateRequest(const FileManagement::FolderModifyRequest &request) { DEBUG_LOG(m_logger) << "Creating folder with name = " << request.name() << " under parent folder " << request.parentId(); Core::FunctionReplyObject ret; Folder data; std::vector parentPath; if (request.parentId() > 0 && m_objectFolderMap.contains(request.parentId())) parentPath = m_objectFolderMap.value(request.parentId())->getPath(); if (parentPath.size() == 0) return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting Folder on root level")); std::vector path = parentPath; path.push_back(9999); // dummy id, only needed to retrieve later the proper id data.name(request.name()); data.path(path); data.isEditable(request.isEditable()); data.isHidden(request.isHidden()); data.parentId(request.parentId()); data.operatorId(request.operatorId()); data.lastModified(QDateTime::currentMSecsSinceEpoch()); ObjectFolder *ifs(new ObjectFolder(m_mainHandler)); ret = ifs->createObject(data); if (ret.error()) { delete ifs; ifs = nullptr; ERROR_LOG(m_logger) << ret(); } else { data.id(ifs->getId()); // update path with the real id path = parentPath; path.resize(parentPath.size() + 1, ifs->getId()); data.path(path); data.lastModified(QDateTime::currentMSecsSinceEpoch()); ret = ifs->updateObject(data); if (ret.error()) { delete ifs; ifs = nullptr; ERROR_LOG(m_logger) << ret(); } else { m_objectFolderMap.insert(ifs->getId(), ifs); ret.setId(ifs->getId()); } } return ret; } //------------------------------------------------------------------------------------------------------------- Core::FunctionReplyObject HandlerFolder::folderModifyRequest(const FileManagement::FolderModifyRequest &request) { ObjectFolder *ifs = m_objectFolderMap.value(request.id()); if (ifs == nullptr) return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Folder with id %1 not found")).arg(request.id()); Folder newData; newData.id(request.id()); newData.name(request.name()); newData.path(request.path()); newData.isEditable(request.isEditable()); newData.parentId(request.parentId()); newData.operatorId(request.operatorId()); newData.lastModified(QDateTime::currentMSecsSinceEpoch()); newData.isHidden(request.isHidden()); return ifs->updateObject(newData); } //------------------------------------------------------------------------------------------ void HandlerFolder::onPathCreateRequest(const rti::core::SampleIdentity &cookie, const FileManagement::PathCreateRequest &request) { Core::FunctionReplyObject ret; int parentFolderId = request.parentId(); DEBUG_LOG(m_logger) << "parentFolderId: " << parentFolderId; for (const std::string &folderName : request.path()) { int folderId = dtc()->findFolder(parentFolderId, QString::fromStdString(folderName)); DEBUG_LOG(m_logger) << "folderId: " << folderId << ", folderName: " << folderName; ObjectFolder *ifs = m_objectFolderMap.value(parentFolderId); if (ifs == nullptr) { ret = Core::FunctionReplyObject(parentFolderId, tr_lts("dds", "Folder with id %1 not found")).arg(parentFolderId); break; } if (folderId <= 0) { DEBUG_LOG(m_logger) << "Folder " << folderName << " does not exist => creating ..."; // Folder does not exist => create folder FolderModifyRequest folderRequest; folderRequest.name(folderName); folderRequest.parentId(parentFolderId); folderRequest.path(ifs->getPath()); folderRequest.isEditable(request.isEditable()); folderRequest.isHidden(request.isHidden()); folderRequest.operatorId(request.operatorId()); ret = folderCreateRequest(folderRequest); if (ret.error()) break; parentFolderId = ret.id(); DEBUG_LOG(m_logger) << "parentFolderId: " << parentFolderId; } else parentFolderId = folderId; } fts()->pathCreateReply(cookie, ret); } //------------------------------------------------------------------------------------------ void HandlerFolder::onFolderRemoveRequest(const rti::core::SampleIdentity &cookie, const Core::RemoveElementRequest &request) { Core::FunctionReplyObject ret; ObjectFolder *ifs = m_objectFolderMap.value(request.id()); if (ifs == nullptr) { ret = Core::FunctionReplyObject(request.id(), tr_lts("dds", "Folder with id %1 not found")).arg(request.id()); fts()->folderRemoveReply(cookie, ret); return; } if (m_mainHandler->dds()->topicLockMaster()->isLocked(ifs->getData(), m_mainHandler->exerciseId())) { ret = Core::FunctionReplyObject(request.id(), tr_lts("dds", "Folder '%1' is used by another user!")).arg(ifs->getName()); fts()->folderRemoveReply(cookie, ret); return; } ret = removeFolder(request.id()); delete ifs; fts()->folderRemoveReply(cookie, ret); return; } //--------------------------------------------------- Core::FunctionReplyObject HandlerFolder::removeFolder(int folderId) { Core::FunctionReplyObject ret; DBTransaction trans(m_mainHandler->db()->database()); // remove object and all children for (auto it = m_objectFolderMap.begin(); it != m_objectFolderMap.end();) { DEBUG_LOG(m_logger) << "Checking ObjectFolder with id " << it.value()->getId() << " and parent id " << it.value()->getParentId(); if (it.value()->pathContains(folderId)) { DEBUG_LOG(m_logger) << "Removing ObjectFolder with id " << it.value()->getId(); ret = it.value()->removeObject(); if (!ret.error()) { removeFilesForFolder(it.value()->getId()); it = m_objectFolderMap.erase(it); } else { ERROR_LOG(m_logger) << ret(); ++it; } } else ++it; } if (!ret.error()) trans.commit(); return ret; } //--------------------------------------------------- void HandlerFolder::onFileContentRemoveRequest(const rti::core::SampleIdentity &cookie, const Core::RemoveElementRequest &request) { Core::FunctionReplyObject ret; ObjectFileContent *ifs = m_mainHandler->getHandlerFileContent()->getObjectFileContentMap().value(request.id()); if (ifs == nullptr) { ret = Core::FunctionReplyObject(request.id(), tr_lts("dds", "FileContent with id %1 not found")).arg(request.id()); fts()->fileContentRemoveReply(cookie, ret); return; } if (m_mainHandler->dds()->topicLockMaster()->isLocked(ifs->getData(), m_mainHandler->exerciseId())) { ret = Core::FunctionReplyObject(request.id(), tr_lts("dds", "FileContent '%1' is used by another user!")).arg(ifs->getName()); fts()->folderRemoveReply(cookie, ret); return; } ret = ifs->removeObject(); if (ret.error()) ERROR_LOG(m_logger) << ret(); else { // delete ObjectFileContent delete ifs; m_mainHandler->getHandlerFileContent()->getObjectFileContentMap().remove(request.id()); } fts()->fileContentRemoveReply(cookie, ret); return; } //--------------------------------------------------- void HandlerFolder::removeFilesForFolder(int folderId) { DEBUG_LOG(m_logger) << "Removing Files for Folder id " << folderId; Core::RemoveElementRequest request; const auto files = m_mainHandler->getHandlerFileContent()->getObjectFileContentMap(); for (auto file : files) { if (file->getFolderId() == folderId) { request.id(file->getId()); auto ret = m_mainHandler->getHandlerFileContent()->fileContentRemoveRequest(request); if (ret.error()) WARNING_LOG(m_logger) << ret(); } } } //---------------------------------------------------------------------------------------------------------------------------- void HandlerFolder::onDbDeletedFolder(const QVariant &id_) { int id = id_.toInt(); DEBUG_LOG(m_logger) << "DB deleted Folder with id: " << id; Core::FunctionReplyObject ret = removeFolder(id); if (ret.error()) ERROR_LOG(m_logger) << ret(); if (!dts()->removeFolderByKey(id)) ERROR_LOG(m_logger) << "Folder can not be taken from DDS, id = " << id; } //---------------------------------------------------------------------------------------------------------------------------- void HandlerFolder::onDbInsertedFolder(const QVariant &id_) { int id = id_.toInt(); DEBUG_LOG(m_logger) << "DB inserted Folder with id: " << id; if (!m_objectFolderMap.contains(id)) initByDbId(id); } //---------------------------------------------------------------------------------------------------------------------------- void HandlerFolder::onDbUpdatedFolder(const QVariant &id_) { int id = id_.toInt(); DEBUG_LOG(m_logger) << "DB updated Folder with id: " << id; initByDbId(id); } //---------------------------------------------------------------------------------------------------------------------------- bool HandlerFolder::initByDbId(int dbId) { Database::FlmFolder data; DEBUG_LOG(m_logger) << "Reading Folder from database!"; if (!db()->selectFlmFolder(dbId, data)) { ERROR_LOG(m_logger) << "Error reading data from database: id not found " << dbId; return false; } // create folder object if (data.id == dbId) { ObjectFolder *ifs(new ObjectFolder(m_mainHandler)); Core::FunctionReplyObject ret = ifs->createObject(convert(data)); if (ret.error()) { delete ifs; ERROR_LOG(m_logger) << ret(); return false; } m_objectFolderMap.insert(ifs->getId(), ifs); ifs->onPublishData(); } return true; } } // Namespace FileManagement