forked from University/epr24pr5-ojanssen2
300 lines
9.2 KiB
C++
300 lines
9.2 KiB
C++
#include "Manager.h"
|
|
#include "Error.h"
|
|
#include <fstream>
|
|
#include "DataType.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<DataType, vector<string>> 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<DataType> sections = { DataType::USER, DataType::TASK, DataType::ASSIGNMENT };
|
|
for (DataType type : sections)
|
|
{
|
|
// Keine Data -> Continue
|
|
if (buffer.find(type) == buffer.end())
|
|
continue;
|
|
const vector<string>& 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<User*> Manager::get_users() const
|
|
{
|
|
vector<User*> 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<Task*> Manager::get_tasks() const
|
|
{
|
|
vector<Task*> 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<Assignment*> 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<Assignment*> Manager::get_assignments_for_user(const int user_id)
|
|
{
|
|
Vector<Assignment*> 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<Assignment*> Manager::get_assignments_for_task(const int task_id)
|
|
{
|
|
Vector<Assignment*> 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(int user_id, int task_id) {
|
|
|
|
for ( Assignment* 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.");
|
|
}
|
|
}
|
|
}
|
|
this->tasks.erase(id);
|
|
}
|
|
|
|
void Manager::del_assignment(Assignment& 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() - 1; ++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();
|
|
}
|
|
} // util
|