#include "Manager.h" #include #include "DataType.h" #include "Error.h" using err::Error; using util::DataType; namespace util { Manager::Manager() : users({}), tasks({}), assignments({}), user_id_index(0), task_id_index(0), filename("tasks") { // Open File ifstream in = ifstream(this->filename, ios_base::in); if (!in) { this->save(); in.clear(); in.open(this->filename, ios_base::in); if (!in) throw Error(601, "Datei kann nicht geöffnet werden."); } map> buffer; DataType current_type = DataType::INIT; string d; // dump string line, section; // Parse all Lines until EOF while (getline(in, line)) { // Check if the line starts with '[' if (!line.empty() && line[0] == '[') { if (line == "[tasks]") current_type = DataType::TASK; else if (line == "[users]") current_type = DataType::USER; else if (line == "[assignments]") current_type = DataType::ASSIGNMENT; else throw Error(602, "Datei hat ein unbekanntes Format."); continue; } // Lehre Zeilen überspringen. if (line.empty()) continue; // Speichern im Buffer buffer[current_type].push_back(line); } // Data is parsed in.close(); // Reihenfolge der Verabeitung vector sections = {DataType::USER, DataType::TASK, DataType::ASSIGNMENT}; for (DataType type: sections) { // Keine Data -> Continue if (buffer.find(type) == buffer.end()) continue; const vector &lines = buffer[type]; // Iteriere über die Gebufferten Strings. for (const string &buffered_line: lines) { stringstream string_stream(buffered_line); switch (type) { case DataType::TASK: { Task task; string_stream >> task; this->tasks[task.get_id()] = new Task(task); } break; case DataType::USER: { User user; string_stream >> user; this->users[user.get_id()] = new User(user); } break; case DataType::ASSIGNMENT: { Assignment assignment; string_stream >> assignment; this->assignments.push_back(new Assignment(assignment)); } break; default: break; } } } this->update_indexes(); } void Manager::update_user_id_index() { int i = 0; for (const auto &user_pair: this->users) if (user_pair.second && user_pair.second->get_id() >= i) i = user_pair.second->get_id() + 1; this->user_id_index = i; } void Manager::update_task_id_index() { int i = 0; for (const auto &task_pair: this->tasks) if (task_pair.second && task_pair.second->get_id() >= i) i = task_pair.second->get_id() + 1; this->task_id_index = i; } void Manager::update_indexes() { this->update_user_id_index(); this->update_task_id_index(); } int Manager::get_user_id() { const int value = this->user_id_index; ++this->user_id_index; return value; } int Manager::get_task_id() { const int value = this->task_id_index; ++this->task_id_index; return value; } Manager *Manager::INSTANCE = nullptr; Manager *Manager::get_instance() { if (INSTANCE == nullptr) INSTANCE = new Manager(); return INSTANCE; } vector Manager::get_users() const { vector user_vector; for (const auto &pair: this->users) if (pair.second) // Ensure it's not a nullptr user_vector.push_back(pair.second); return user_vector; } vector Manager::get_tasks() const { vector task_vector; for (const auto &pair: this->tasks) if (pair.second) // Ensure it's not a nullptr task_vector.push_back(pair.second); return task_vector; } vector Manager::get_assignments() { return this->assignments; } User *Manager::get_user(const int id) { if (this->users.count(id) == 0) return nullptr; return this->users[id]; } Task *Manager::get_task(const int id) { if (this->tasks.count(id) == 0) return nullptr; return this->tasks[id]; } Vector Manager::get_assignments_for_user(const int user_id) { Vector user_assignments; if (this->get_user(user_id) == nullptr) throw Error(401, "Eine solche BenutzerIn existiert nicht."); for (Assignment *as: this->assignments) if (as->get_user_id() == user_id) user_assignments.push_back(as); return user_assignments; } Vector Manager::get_assignments_for_task(const int task_id) { Vector task_assignments; if (this->get_task(task_id) == nullptr) throw Error(401, "Eine solche BenutzerIn existiert nicht."); for (Assignment *as: this->assignments) if (as->get_task_id() == task_id) task_assignments.push_back(as); return task_assignments; } bool Manager::assignment_exists(const int user_id, const int task_id) const { for (Assignment const *as: this->assignments) { if (as->get_user_id() == user_id && as->get_task_id() == task_id) return true; } return false; } void Manager::add_user(User *user) { if (this->users.count(user->get_id()) == 1) return; this->users[user->get_id()] = user; } void Manager::add_task(Task *task) { if (this->tasks.count(task->get_id()) == 1) return; this->tasks[task->get_id()] = task; } void Manager::add_assignment(Assignment *as) { if (this->get_user(as->get_user_id()) == nullptr) throw Error(401, "Eine solche BenutzerIn existiert nicht."); if (this->get_task(as->get_task_id()) == nullptr) throw Error(402, "Eine solche Aufgabe existiert nicht."); this->assignments.push_back(as); } void Manager::del_user(const int id) { if (this->users.count(id) == 0) throw Error(401, "Eine solche BenutzerIn existiert nicht."); // Assigment if (!this->get_assignments_for_user(id).empty()) { throw Error(201, "Benutzer kann nicht gelöscht werden."); } this->users.erase(id); } void Manager::del_task(const int id) { if (this->tasks.count(id) == 0) throw Error(402, "Eine solche Aufgabe existiert nicht."); if (!this->get_assignments_for_task(id).empty()) { throw Error(202, "Aufgabe kann nicht gelöscht werden."); } // TODO: Zudem kann eine Aufgabe nur gelöscht werden, wenn Sie nicht Nachfolgerin einer anderen Aufgabe ist -> // Ensure its no Child /*for (Task* task : this->get_tasks()) { for (int child_id : task->get_children()) { if (id == child_id) { throw Error(202, "Aufgabe kann nicht gelöscht werden."); } } }*/ if (!this->get_task(id)->is_active()) { throw Error(202, "Aufgabe kann nicht gelöscht werden."); } this->tasks.erase(id); } void Manager::del_assignment(Assignment const &as) { if (!this->assignment_exists(as.get_user_id(), as.get_task_id())) throw Error(301, "Eine solche Zuordnung existiert nicht."); int assignment_nr = 0; for (int i = 0; i < this->assignments.size(); ++i) { if (this->assignments[i]->get_user_id() == as.get_user_id() && this->assignments[i]->get_task_id() == as.get_task_id()) { assignment_nr = i; break; } } this->assignments.erase(this->assignments.begin() + assignment_nr); }; void Manager::save() { ofstream out = ofstream(this->filename, ios_base::trunc); if (!out) throw Error(603, "Datei kann nicht geschrieben werden."); out << "[tasks]\n"; for (const auto &task_pair: this->tasks) { if (task_pair.second) task_pair.second->write(out); } out << "\n[users]\n"; for (const auto &user_pair: this->users) { if (user_pair.second) user_pair.second->write(out); } out << "\n[assignments]\n"; for (Assignment *assignment: this->assignments) { if (assignment) assignment->write(out); } out.close(); } } // namespace util