aboutsummaryrefslogtreecommitdiff
path: root/app/source/Cplt/Model/Project.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'app/source/Cplt/Model/Project.cpp')
-rw-r--r--app/source/Cplt/Model/Project.cpp168
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");
+}