From a3a63450f6a9bbb348519d6029671d8c7926bef8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matej=20Dip=C4=8D=C3=A1r?= <492666@mail.muni.cz>
Date: Mon, 31 Jan 2022 12:50:58 +0100
Subject: [PATCH] Generalize task related models

---
 .../project/model/db/AbstractDataModel.java   | 43 +++++++++++
 .../pv168/project/model/db/CategoryModel.java | 77 -------------------
 .../pv168/project/model/db/SubTaskModel.java  | 51 +-----------
 .../project/model/db/TaskCategoryModel.java   | 51 +-----------
 .../project/model/db/TaskDependencyModel.java | 51 +-----------
 .../fi/pv168/project/model/db/TaskModel.java  | 74 ++----------------
 .../model/db/TaskPropertyListDataModel.java   | 24 ++++++
 .../project/model/db/UpdatableDataModel.java  | 39 ++++++++++
 .../main/view/CategoryAndStatisticsView.java  |  8 +-
 .../project/ui/main/view/CategoryView.java    |  4 +-
 .../project/ui/main/view/StatisticsView.java  |  5 +-
 11 files changed, 126 insertions(+), 301 deletions(-)
 create mode 100644 src/main/java/cz/muni/fi/pv168/project/model/db/AbstractDataModel.java
 delete mode 100644 src/main/java/cz/muni/fi/pv168/project/model/db/CategoryModel.java
 create mode 100644 src/main/java/cz/muni/fi/pv168/project/model/db/TaskPropertyListDataModel.java
 create mode 100644 src/main/java/cz/muni/fi/pv168/project/model/db/UpdatableDataModel.java

diff --git a/src/main/java/cz/muni/fi/pv168/project/model/db/AbstractDataModel.java b/src/main/java/cz/muni/fi/pv168/project/model/db/AbstractDataModel.java
new file mode 100644
index 00000000..3b9145d5
--- /dev/null
+++ b/src/main/java/cz/muni/fi/pv168/project/model/db/AbstractDataModel.java
@@ -0,0 +1,43 @@
+package cz.muni.fi.pv168.project.model.db;
+
+import cz.muni.fi.pv168.project.model.EditableModel;
+import cz.muni.fi.pv168.project.ui.dialog.error.ErrorDialog;
+
+import javax.swing.DefaultListModel;
+
+public abstract class AbstractDataModel<E> extends DefaultListModel<E> implements EditableModel<E> {
+
+    @Override
+    public void setElementAt(E element, int index) {
+        try {
+            update(element);
+        } catch (Exception e) {
+            e.printStackTrace();
+            ErrorDialog.show("Error when editing " + element, e);
+        }
+        super.setElementAt(element, index);
+    }
+
+    @Override
+    public void addElement(E element) {
+        try {
+            add(element);
+        } catch (Exception e) {
+            e.printStackTrace();
+            ErrorDialog.show("Error when adding " + element, e);
+        }
+
+        super.addElement(element);
+    }
+
+    @Override
+    public boolean removeElement(Object obj) {
+        try {
+            delete((E) obj);
+        } catch (Exception e) {
+            e.printStackTrace();
+            ErrorDialog.show("Error when removing " + obj, e);
+        }
+        return super.removeElement(obj);
+    }
+}
diff --git a/src/main/java/cz/muni/fi/pv168/project/model/db/CategoryModel.java b/src/main/java/cz/muni/fi/pv168/project/model/db/CategoryModel.java
deleted file mode 100644
index 181371ce..00000000
--- a/src/main/java/cz/muni/fi/pv168/project/model/db/CategoryModel.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package cz.muni.fi.pv168.project.model.db;
-
-import cz.muni.fi.pv168.project.data.category.Category;
-import cz.muni.fi.pv168.project.db.category.CategoryDao;
-import cz.muni.fi.pv168.project.model.EditableModel;
-import cz.muni.fi.pv168.project.ui.dialog.error.ErrorDialog;
-
-import javax.swing.DefaultListModel;
-
-public class CategoryModel extends DefaultListModel<Category> implements EditableModel<Category> {
-
-    private final CategoryDao dataAccessObject;
-
-    public CategoryModel(CategoryDao dao) {
-        this.dataAccessObject = dao;
-        updateAll();
-    }
-
-    @Override
-    public void delete(Category entity) {
-        dataAccessObject.delete(entity);
-    }
-
-    @Override
-    public void add(Category entity) {
-        dataAccessObject.add(entity);
-    }
-
-    @Override
-    public void update(Category entity) {
-        dataAccessObject.update(entity);
-    }
-
-    @Override
-    public void setElementAt(Category element, int index) {
-        try {
-            update(element);
-        } catch (Exception e) {
-            e.printStackTrace();
-            ErrorDialog.show("Error when editing " + element, e);
-        }
-        super.setElementAt(element, index);
-    }
-
-    @Override
-    public void addElement(Category element) {
-        try {
-            add(element);
-        } catch (Exception e) {
-            e.printStackTrace();
-            ErrorDialog.show("Error when adding " + element, e);
-        }
-        
-        super.addElement(element);
-    }
-
-    @Override
-    public boolean removeElement(Object obj) {
-        try {
-            delete((Category) obj);
-        } catch (Exception e) {
-            e.printStackTrace();
-            ErrorDialog.show("Error when removing " + obj, e);
-        }
-        return super.removeElement(obj);
-    }
-
-    public void updateAll() {
-        clear();
-        try {
-            addAll(dataAccessObject.getAll());
-        } catch (Exception e) {
-            e.printStackTrace();
-            ErrorDialog.show("Error when querying all elements.", e);
-        }
-    }
-}
diff --git a/src/main/java/cz/muni/fi/pv168/project/model/db/SubTaskModel.java b/src/main/java/cz/muni/fi/pv168/project/model/db/SubTaskModel.java
index bfbab38d..a799053e 100644
--- a/src/main/java/cz/muni/fi/pv168/project/model/db/SubTaskModel.java
+++ b/src/main/java/cz/muni/fi/pv168/project/model/db/SubTaskModel.java
@@ -3,24 +3,15 @@ package cz.muni.fi.pv168.project.model.db;
 import cz.muni.fi.pv168.project.data.task.SubTask;
 import cz.muni.fi.pv168.project.data.task.Task;
 import cz.muni.fi.pv168.project.db.subtask.SubTaskDao;
-import cz.muni.fi.pv168.project.model.EditableModel;
-import cz.muni.fi.pv168.project.ui.dialog.error.ErrorDialog;
 
-import javax.swing.DefaultListModel;
-import java.util.List;
-
-public class SubTaskModel extends DefaultListModel<SubTask> implements EditableModel<SubTask> {
+public class SubTaskModel extends TaskPropertyListDataModel<SubTask> {
 
     private final SubTaskDao dataAccessObject;
-    private Task parentTask;
 
     public SubTaskModel(SubTaskDao dao) {
+        super(Task::getSubTasks);
         this.dataAccessObject = dao;
     }
-    
-    public void setParentTask(Task task) {
-        this.parentTask = task;
-    }
 
     @Override
     public void delete(SubTask entity) {
@@ -38,42 +29,4 @@ public class SubTaskModel extends DefaultListModel<SubTask> implements EditableM
     public void update(SubTask entity) {
         dataAccessObject.update(entity);
     }
-    
-    public List<SubTask> fetchAll() {
-        return parentTask.getSubTasks();
-    }
-
-    @Override
-    public void setElementAt(SubTask element, int index) {
-        try {
-            update(element);
-        } catch (Exception e) {
-            e.printStackTrace();
-            ErrorDialog.show("Error when editing " + element, e);
-        }
-        super.setElementAt(element, index);
-    }
-
-    @Override
-    public void addElement(SubTask element) {
-        try {
-            add(element);
-        } catch (Exception e) {
-            e.printStackTrace();
-            ErrorDialog.show("Error when adding " + element, e);
-        }
-        
-        super.addElement(element);
-    }
-
-    @Override
-    public boolean removeElement(Object obj) {
-        try {
-            delete((SubTask) obj);
-        } catch (Exception e) {
-            e.printStackTrace();
-            ErrorDialog.show("Error when removing " + obj, e);
-        }
-        return super.removeElement(obj);
-    }
 }
diff --git a/src/main/java/cz/muni/fi/pv168/project/model/db/TaskCategoryModel.java b/src/main/java/cz/muni/fi/pv168/project/model/db/TaskCategoryModel.java
index 2f850860..aa4413cd 100644
--- a/src/main/java/cz/muni/fi/pv168/project/model/db/TaskCategoryModel.java
+++ b/src/main/java/cz/muni/fi/pv168/project/model/db/TaskCategoryModel.java
@@ -3,25 +3,16 @@ package cz.muni.fi.pv168.project.model.db;
 import cz.muni.fi.pv168.project.data.category.Category;
 import cz.muni.fi.pv168.project.data.task.Task;
 import cz.muni.fi.pv168.project.db.taskcategory.TaskCategoryDao;
-import cz.muni.fi.pv168.project.model.EditableModel;
-import cz.muni.fi.pv168.project.ui.dialog.error.ErrorDialog;
 
-import javax.swing.DefaultListModel;
-import java.util.List;
-
-public class TaskCategoryModel extends DefaultListModel<Category> implements EditableModel<Category> {
+public class TaskCategoryModel extends TaskPropertyListDataModel<Category> {
 
     private final TaskCategoryDao dataAccessObject;
-    private Task parentTask;
 
     public TaskCategoryModel(TaskCategoryDao dao) {
+        super(Task::getCategories);
         this.dataAccessObject = dao;
     }
 
-    public void setParentTask(Task task) {
-        this.parentTask = task;
-    }
-
     @Override
     public void delete(Category entity) {
         dataAccessObject.deleteAssociationFor(parentTask.getId(), entity.getId());
@@ -37,42 +28,4 @@ public class TaskCategoryModel extends DefaultListModel<Category> implements Edi
     @Override
     public void update(Category entity) {
     }
-
-    public List<Category> fetchAll() {
-        return parentTask.getCategories();
-    }
-
-    @Override
-    public void setElementAt(Category element, int index) {
-        try {
-            update(element);
-        } catch (Exception e) {
-            e.printStackTrace();
-            ErrorDialog.show("Error when editing " + element, e);
-        }
-        super.setElementAt(element, index);
-    }
-
-    @Override
-    public void addElement(Category element) {
-        try {
-            add(element);
-        } catch (Exception e) {
-            e.printStackTrace();
-            ErrorDialog.show("Error when adding " + element, e);
-        }
-
-        super.addElement(element);
-    }
-
-    @Override
-    public boolean removeElement(Object obj) {
-        try {
-            delete((Category) obj);
-        } catch (Exception e) {
-            e.printStackTrace();
-            ErrorDialog.show("Error when removing " + obj, e);
-        }
-        return super.removeElement(obj);
-    }
 }
diff --git a/src/main/java/cz/muni/fi/pv168/project/model/db/TaskDependencyModel.java b/src/main/java/cz/muni/fi/pv168/project/model/db/TaskDependencyModel.java
index 8a85a003..d15e88f8 100644
--- a/src/main/java/cz/muni/fi/pv168/project/model/db/TaskDependencyModel.java
+++ b/src/main/java/cz/muni/fi/pv168/project/model/db/TaskDependencyModel.java
@@ -2,25 +2,16 @@ package cz.muni.fi.pv168.project.model.db;
 
 import cz.muni.fi.pv168.project.data.task.Task;
 import cz.muni.fi.pv168.project.db.dependency.DependencyDao;
-import cz.muni.fi.pv168.project.model.EditableModel;
-import cz.muni.fi.pv168.project.ui.dialog.error.ErrorDialog;
 
-import javax.swing.DefaultListModel;
-import java.util.List;
-
-public class TaskDependencyModel extends DefaultListModel<Task> implements EditableModel<Task> {
+public class TaskDependencyModel extends TaskPropertyListDataModel<Task> {
 
     private final DependencyDao dataAccessObject;
-    private Task parentTask;
 
     public TaskDependencyModel(DependencyDao dao) {
+        super(Task::getDependencyTasks);
         this.dataAccessObject = dao;
     }
 
-    public void setParentTask(Task task) {
-        this.parentTask = task;
-    }
-
     @Override
     public void delete(Task entity) {
         dataAccessObject.deleteAssociationFor(parentTask.getId(), entity.getId());
@@ -36,42 +27,4 @@ public class TaskDependencyModel extends DefaultListModel<Task> implements Edita
     @Override
     public void update(Task entity) {
     }
-
-    public List<Task> fetchAll() {
-        return parentTask.getDependencyTasks();
-    }
-
-    @Override
-    public void setElementAt(Task element, int index) {
-        try {
-            update(element);
-        } catch (Exception e) {
-            e.printStackTrace();
-            ErrorDialog.show("Error when editing " + element, e);
-        }
-        super.setElementAt(element, index);
-    }
-
-    @Override
-    public void addElement(Task element) {
-        try {
-            add(element);
-        } catch (Exception e) {
-            e.printStackTrace();
-            ErrorDialog.show("Error when adding " + element, e);
-        }
-
-        super.addElement(element);
-    }
-
-    @Override
-    public boolean removeElement(Object obj) {
-        try {
-            delete((Task) obj);
-        } catch (Exception e) {
-            e.printStackTrace();
-            ErrorDialog.show("Error when removing " + obj, e);
-        }
-        return super.removeElement(obj);
-    }
 }
diff --git a/src/main/java/cz/muni/fi/pv168/project/model/db/TaskModel.java b/src/main/java/cz/muni/fi/pv168/project/model/db/TaskModel.java
index e689b00f..d3eda703 100644
--- a/src/main/java/cz/muni/fi/pv168/project/model/db/TaskModel.java
+++ b/src/main/java/cz/muni/fi/pv168/project/model/db/TaskModel.java
@@ -2,79 +2,15 @@ package cz.muni.fi.pv168.project.model.db;
 
 import cz.muni.fi.pv168.project.data.task.Task;
 import cz.muni.fi.pv168.project.db.DataAccessException;
-import cz.muni.fi.pv168.project.db.task.TaskDao;
-import cz.muni.fi.pv168.project.model.EditableModel;
+import cz.muni.fi.pv168.project.db.interfaces.DataAccessObject;
 import cz.muni.fi.pv168.project.ui.dialog.error.ErrorDialog;
 
-import javax.swing.DefaultListModel;
 import java.util.function.Predicate;
 
-public class TaskModel extends DefaultListModel<Task> implements EditableModel<Task> {
-
-    private final TaskDao dataAccessObject;
-
-    public TaskModel(TaskDao dao) {
-        this.dataAccessObject = dao;
-        updateAll();
-    }
-
-    @Override
-    public void delete(Task entity) {
-        dataAccessObject.delete(entity);
-    }
-
-    @Override
-    public void add(Task entity) {
-        dataAccessObject.add(entity);
-    }
-
-    @Override
-    public void update(Task entity) {
-        dataAccessObject.update(entity);
-    }
-
-    @Override
-    public void setElementAt(Task element, int index) {
-        try {
-            update(element);
-        } catch (Exception e) {
-            e.printStackTrace();
-            ErrorDialog.show("Error when editing " + element, e);
-        }
-        super.setElementAt(element, index);
-    }
-
-    @Override
-    public void addElement(Task element) {
-        try {
-            add(element);
-        } catch (Exception e) {
-            e.printStackTrace();
-            ErrorDialog.show("Error when adding " + element, e);
-        }
-
-        super.addElement(element);
-    }
-
-    @Override
-    public boolean removeElement(Object obj) {
-        try {
-            delete((Task) obj);
-        } catch (Exception e) {
-            e.printStackTrace();
-            ErrorDialog.show("Error when removing " + obj, e);
-        }
-        return super.removeElement(obj);
-    }
-
-    public void updateAll() {
-        clear();
-        try {
-            addAll(dataAccessObject.getAll());
-        } catch (Exception e) {
-            e.printStackTrace();
-            ErrorDialog.show("Error when querying all elements.", e);
-        }
+public class TaskModel extends UpdatableDataModel<Task> {
+    
+    public TaskModel(DataAccessObject<Task> dao) {
+        super(dao);
     }
 
     public void updateFiltered(Predicate<Task> predicate) {
diff --git a/src/main/java/cz/muni/fi/pv168/project/model/db/TaskPropertyListDataModel.java b/src/main/java/cz/muni/fi/pv168/project/model/db/TaskPropertyListDataModel.java
new file mode 100644
index 00000000..b66636e2
--- /dev/null
+++ b/src/main/java/cz/muni/fi/pv168/project/model/db/TaskPropertyListDataModel.java
@@ -0,0 +1,24 @@
+package cz.muni.fi.pv168.project.model.db;
+
+import cz.muni.fi.pv168.project.data.task.Task;
+
+import java.util.List;
+import java.util.function.Function;
+
+public abstract class TaskPropertyListDataModel<E> extends AbstractDataModel<E> {
+
+    protected Task parentTask;
+    private final Function<Task, List<E>> fetcher;
+    
+    public TaskPropertyListDataModel(Function<Task, List<E>> fetcher) {
+        this.fetcher = fetcher;
+    }
+
+    public void setParentTask(Task task) {
+        this.parentTask = task;
+    }
+
+    public List<E> fetchAll() {
+        return fetcher.apply(parentTask);
+    }
+}
diff --git a/src/main/java/cz/muni/fi/pv168/project/model/db/UpdatableDataModel.java b/src/main/java/cz/muni/fi/pv168/project/model/db/UpdatableDataModel.java
new file mode 100644
index 00000000..781a685a
--- /dev/null
+++ b/src/main/java/cz/muni/fi/pv168/project/model/db/UpdatableDataModel.java
@@ -0,0 +1,39 @@
+package cz.muni.fi.pv168.project.model.db;
+
+import cz.muni.fi.pv168.project.db.interfaces.DataAccessObject;
+import cz.muni.fi.pv168.project.ui.dialog.error.ErrorDialog;
+
+public class UpdatableDataModel<E> extends AbstractDataModel<E> {
+
+    protected final DataAccessObject<E> dataAccessObject;
+
+    public UpdatableDataModel(DataAccessObject<E> dao) {
+        this.dataAccessObject = dao;
+        updateAll();
+    }
+
+    @Override
+    public void delete(E entity) {
+        dataAccessObject.delete(entity);
+    }
+
+    @Override
+    public void add(E entity) {
+        dataAccessObject.add(entity);
+    }
+
+    @Override
+    public void update(E entity) {
+        dataAccessObject.update(entity);
+    }
+
+    public void updateAll() {
+        clear();
+        try {
+            addAll(dataAccessObject.getAll());
+        } catch (Exception e) {
+            e.printStackTrace();
+            ErrorDialog.show("Error when querying all elements.", e);
+        }
+    }
+}
diff --git a/src/main/java/cz/muni/fi/pv168/project/ui/main/view/CategoryAndStatisticsView.java b/src/main/java/cz/muni/fi/pv168/project/ui/main/view/CategoryAndStatisticsView.java
index 9362c316..a42585fc 100644
--- a/src/main/java/cz/muni/fi/pv168/project/ui/main/view/CategoryAndStatisticsView.java
+++ b/src/main/java/cz/muni/fi/pv168/project/ui/main/view/CategoryAndStatisticsView.java
@@ -2,7 +2,7 @@ package cz.muni.fi.pv168.project.ui.main.view;
 
 import cz.muni.fi.pv168.project.data.category.Category;
 import cz.muni.fi.pv168.project.db.DaoHolder;
-import cz.muni.fi.pv168.project.model.db.CategoryModel;
+import cz.muni.fi.pv168.project.model.db.UpdatableDataModel;
 import cz.muni.fi.pv168.project.ui.action.AddAction;
 import cz.muni.fi.pv168.project.ui.action.DeleteAction;
 import cz.muni.fi.pv168.project.ui.action.EditAction;
@@ -21,7 +21,7 @@ import javax.swing.JToolBar;
 
 public class CategoryAndStatisticsView implements Tab<Category> {
 
-    private final CategoryModel categoryModel;
+    private final UpdatableDataModel<Category> categoryModel;
 
     private final CategoriesStatisticsToolBar toolBar;
     private final TabActions tabActions;
@@ -32,7 +32,7 @@ public class CategoryAndStatisticsView implements Tab<Category> {
     private final StatisticsView statisticsView;
 
     public CategoryAndStatisticsView(DaoHolder daoHolder) {
-        categoryModel = new CategoryModel(daoHolder.getCategoryDao());
+        categoryModel = new UpdatableDataModel<>(daoHolder.getCategoryDao());
         splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
 
         this.categoryView = new CategoryView(categoryModel);
@@ -92,7 +92,7 @@ public class CategoryAndStatisticsView implements Tab<Category> {
     }
 
     @Override
-    public CategoryModel getModel() {
+    public UpdatableDataModel<Category> getModel() {
         return categoryModel;
     }
 }
diff --git a/src/main/java/cz/muni/fi/pv168/project/ui/main/view/CategoryView.java b/src/main/java/cz/muni/fi/pv168/project/ui/main/view/CategoryView.java
index ccb229f8..591b8612 100644
--- a/src/main/java/cz/muni/fi/pv168/project/ui/main/view/CategoryView.java
+++ b/src/main/java/cz/muni/fi/pv168/project/ui/main/view/CategoryView.java
@@ -1,7 +1,7 @@
 package cz.muni.fi.pv168.project.ui.main.view;
 
 import cz.muni.fi.pv168.project.data.category.Category;
-import cz.muni.fi.pv168.project.model.db.CategoryModel;
+import cz.muni.fi.pv168.project.model.db.UpdatableDataModel;
 import cz.muni.fi.pv168.project.ui.renderer.list.InnerColoredListRenderer;
 
 import javax.swing.JComponent;
@@ -18,7 +18,7 @@ public class CategoryView {
     private final JList<Category> categoryList;
     private final JPanel panel;
 
-    public CategoryView(CategoryModel categoryModel) {
+    public CategoryView(UpdatableDataModel<Category> categoryModel) {
         panel = new JPanel(new GridBagLayout());
 
         categoryList = new JList<>(categoryModel);
diff --git a/src/main/java/cz/muni/fi/pv168/project/ui/main/view/StatisticsView.java b/src/main/java/cz/muni/fi/pv168/project/ui/main/view/StatisticsView.java
index 1afed2af..3dda750a 100644
--- a/src/main/java/cz/muni/fi/pv168/project/ui/main/view/StatisticsView.java
+++ b/src/main/java/cz/muni/fi/pv168/project/ui/main/view/StatisticsView.java
@@ -1,7 +1,8 @@
 package cz.muni.fi.pv168.project.ui.main.view;
 
+import cz.muni.fi.pv168.project.data.category.Category;
 import cz.muni.fi.pv168.project.model.CategoryStatisticsTableModel;
-import cz.muni.fi.pv168.project.model.db.CategoryModel;
+import cz.muni.fi.pv168.project.model.db.UpdatableDataModel;
 import cz.muni.fi.pv168.project.ui.renderer.statistics.CategoryStatisticsRenderer;
 import cz.muni.fi.pv168.project.ui.renderer.statistics.TimeSpentStatisticsRenderer;
 
@@ -15,7 +16,7 @@ public class StatisticsView {
     private final JScrollPane scrollPane;
     private final CategoryStatisticsTableModel tableModel;
 
-    public StatisticsView(CategoryModel categoryModel) {
+    public StatisticsView(UpdatableDataModel<Category> categoryModel) {
         tableModel = new CategoryStatisticsTableModel(categoryModel);
         JTable statisticsTable = new JTable(tableModel);
 
-- 
GitLab