diff options
Diffstat (limited to 'app/source/Cplt/Model/Project.cpp')
-rw-r--r-- | app/source/Cplt/Model/Project.cpp | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/app/source/Cplt/Model/Project.cpp b/app/source/Cplt/Model/Project.cpp new file mode 100644 index 0000000..a1e9bab --- /dev/null +++ b/app/source/Cplt/Model/Project.cpp @@ -0,0 +1,168 @@ +#include "Project.hpp" + +#include <Cplt/Model/Workflow/Workflow.hpp> +#include <Cplt/Utils/Macros.hpp> + +#include <json/reader.h> +#include <json/value.h> +#include <json/writer.h> +#include <filesystem> +#include <fstream> +#include <stdexcept> +#include <utility> + +namespace fs = std::filesystem; + +template <class T> +static void ReadItemList(ItemList<T>& list, const fs::path& filePath) +{ + std::ifstream ifs(filePath); + if (ifs) { + Json::Value root; + ifs >> root; + + list = ItemList<T>(root); + } +} + +static void CreateProjectSubfolders(const Project& project) +{ + fs::create_directory(project.GetDatabasesDirectory()); + fs::create_directory(project.GetItemsDirectory()); + fs::create_directory(project.GetWorkflowsDirectory()); + fs::create_directory(project.GetTemplatesDirectory()); +} + +Project::Project(fs::path rootPath) + : mRootPath{ std::move(rootPath) } + , mRootPathString{ mRootPath.string() } + , Workflows(*this) + , Templates(*this) + , Database(*this) +{ + // TODO better diagnostic + const char* kInvalidFormatErr = "Failed to load project: invalid format."; + + std::ifstream ifs(mRootPath / "cplt_project.json"); + if (!ifs) { + std::string message; + message += "Failed to load project file at '"; + message += mRootPath.string(); + message += "'."; + throw std::runtime_error(message); + } + + { + Json::Value root; + ifs >> root; + + const auto& croot = root; // Use const reference so that accessors default to returning a null if not found, instead of silently creating new elements + if (!croot.isObject()) { + throw std::runtime_error(kInvalidFormatErr); + } + + if (auto& name = croot["Name"]; name.isString()) { + mName = name.asString(); + } else { + throw std::runtime_error(kInvalidFormatErr); + } + } + + CreateProjectSubfolders(*this); + + auto itemsDir = mRootPath / "items"; + ReadItemList(Products, itemsDir / "products.json"); + ReadItemList(Factories, itemsDir / "factories.json"); + ReadItemList(Customers, itemsDir / "customers.json"); + + Workflows.Reload(); + Templates.Reload(); +} + +Project::Project(fs::path rootPath, std::string name) + : mRootPath{ std::move(rootPath) } + , mRootPathString{ mRootPath.string() } + , mName{ std::move(name) } + , Workflows(*this) + , Templates(*this) + , Database(*this) +{ + CreateProjectSubfolders(*this); +} + +const fs::path& Project::GetPath() const +{ + return mRootPath; +} + +const std::string& Project::GetPathString() const +{ + return mRootPathString; +} + +fs::path Project::GetDatabasesDirectory() const +{ + return mRootPath / "databases"; +} + +fs::path Project::GetItemsDirectory() const +{ + return mRootPath / "items"; +} + +fs::path Project::GetWorkflowsDirectory() const +{ + return mRootPath / "workflows"; +} + +fs::path Project::GetWorkflowPath(std::string_view name) const +{ + return (mRootPath / "workflows" / name).concat(".cplt-workflow"); +} + +fs::path Project::GetTemplatesDirectory() const +{ + return mRootPath / "templates"; +} + +fs::path Project::GetTemplatePath(std::string_view name) const +{ + return (mRootPath / "templates" / name).concat(".cplt-template"); +} + +const std::string& Project::GetName() const +{ + return mName; +} + +void Project::SetName(std::string name) +{ + mName = std::move(name); +} + +Json::Value Project::Serialize() +{ + Json::Value root(Json::objectValue); + + root["Name"] = mName; + + return root; +} + +template <class T> +static void WriteItemList(ItemList<T>& list, const fs::path& filePath) +{ + std::ofstream ofs(filePath); + ofs << list.Serialize(); +} + +void Project::WriteToDisk() +{ + std::ofstream ofs(mRootPath / "cplt_project.json"); + ofs << this->Serialize(); + + auto itemsDir = GetItemsDirectory(); + WriteItemList(Products, itemsDir / "products.json"); + WriteItemList(Factories, itemsDir / "factories.json"); + WriteItemList(Customers, itemsDir / "customers.json"); +} |