diff --git a/src/main/java/Main.java b/src/main/java/Main.java index a2f2981..eb794c1 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -2,10 +2,11 @@ import screens.*; import screens.calendar_scheduler.*; import screens.course_progress.*; -import screens.courses_features.*; +import screens.course_features.*; import screens.login_registration.*; import screens.task_management.task_creation_screens.*; import use_cases.course_features.course_creation_use_case.*; +import use_cases.course_features.course_enrolment_use_case.*; import use_cases.course_tracker.progress_tracker_use_case.*; import screens.collaborative_task_scheduling.*; import use_cases.collaborative_task_scheduling.scheduling_ct_use_case.*; @@ -79,16 +80,18 @@ public static void main(String[] args) throws IOException, ClassNotFoundExceptio ScheduleCTInputBoundary scheduleCTInputBoundary = new ScheduleCTInteractor(scheduleCTOutputBoundary); ScheduleCTController scheduleCTController = new ScheduleCTController(scheduleCTInputBoundary, TaskMap.getTaskMap(), (StudentUser) user); - CourseCreationDsGateway course; - try { - course = new FileCourse("./src/main/java/data/courses.csv"); - } catch (IOException e) { - throw new RuntimeException("Could not create file."); - } - CourseCreationPresenter presenter = new CourseCreationResponseFormatter(); - CourseMap courseMap = new CourseMap(); - CourseCreationInputBoundary interactor = new CourseCreationInteractor(course, presenter, courseMap); - CourseCreationController courseCreationController = new CourseCreationController(interactor); + // Adding in course creation use case + CourseCreationDsGateway courseCreate = new FileCourse("src/main/java/data/courses.ser"); + CourseCreationOutputBoundary coursePresenter = new CourseCreationPresenter(); + CourseCreationInputBoundary courseInteractor = new CourseCreationInteractor(courseCreate, coursePresenter); + CourseCreationController courseController = new CourseCreationController(courseInteractor); + + // Adding in course enrolment use case + CourseEnrolmentDsGateway enrolCourse = new FileCourse("src/main/java/data/courses.ser"); + CourseTasksToStudentTodolistDsGateway tasksToTodolist = new FileUser("src/main/java/data/users.ser"); + CourseEnrolmentOutputBoundary enrolmentPresenter = new CourseEnrolmentPresenter(); + CourseEnrolmentInputBoundary enrolmentInteractor = new CourseEnrolmentInteractor(enrolCourse, tasksToTodolist, enrolmentPresenter); + CourseEnrolmentController enrolmentController = new CourseEnrolmentController(enrolmentInteractor); // Build the GUI StudentChooseTaskCreateScreen chooseStudentTask = new StudentChooseTaskCreateScreen(schedulerPresenter, scheduleConflictPresenter, @@ -107,8 +110,11 @@ public static void main(String[] args) throws IOException, ClassNotFoundExceptio ProgressTrackerScreen progressTrackerScreen = new ProgressTrackerScreen(trackerController); screens.add("tracker", progressTrackerScreen); - CourseCreationScreen courseCreationScreen = new CourseCreationScreen(courseCreationController, screens, cardLayout); - screens.add("course", courseCreationScreen); + CourseCreationScreen courseCreationScreen = new CourseCreationScreen(courseController, screens, cardLayout); + screens.add("courseCreate", courseCreationScreen); + + CourseEnrolmentScreen courseEnrolmentScreen = new CourseEnrolmentScreen(enrolmentController, screens, cardLayout); + screens.add("courseEnrol", courseEnrolmentScreen); StudentMainScreen studentMainScreen = new StudentMainScreen((StudentUser)user, screens, cardLayout); screens.add("StudentMain", studentMainScreen); diff --git a/src/main/java/data/TaskMap b/src/main/java/data/TaskMap new file mode 100644 index 0000000..fafc4f3 Binary files /dev/null and b/src/main/java/data/TaskMap differ diff --git a/src/main/java/data/TaskMap.txt b/src/main/java/data/TaskMap.txt deleted file mode 100644 index 4fbc56f..0000000 Binary files a/src/main/java/data/TaskMap.txt and /dev/null differ diff --git a/src/main/java/data/users.ser b/src/main/java/data/users.ser deleted file mode 100644 index 8ac12e8..0000000 Binary files a/src/main/java/data/users.ser and /dev/null differ diff --git a/src/main/java/entities/Course.java b/src/main/java/entities/Course.java index d8f0e57..714c7b0 100644 --- a/src/main/java/entities/Course.java +++ b/src/main/java/entities/Course.java @@ -1,12 +1,13 @@ package entities; +import java.io.Serializable; import java.util.ArrayList; /** * entity layer */ -public class Course { +public class Course implements Serializable { /** * class for Course entity with private instance variables * using StudentUser, InstructorUser, and Task entities @@ -16,7 +17,8 @@ public class Course { private String courseID; private ArrayList students; // stores the IDs of students enrolled in the course private ArrayList tasks; // stores the IDs of the course's tasks - private Boolean published; +// private Boolean published; + private boolean courseIsValid; // for unit testing /** * Creates a new Course with a course name, instructor name, and a list of tasks @@ -30,8 +32,8 @@ public Course(String courseName, String courseInstructor, ArrayList task this.courseInstructor = courseInstructor; this.courseID = courseName + courseInstructor; this.tasks = tasks; - this.students = new ArrayList(); - this.published = false; // course creation, default set to not yet published + this.students = new ArrayList<>(); +// this.published = false; // course creation, default set to not yet published } /* @@ -48,21 +50,31 @@ public String getCourseID() { } public ArrayList getStudents() { - return new ArrayList(this.students); + return new ArrayList<>(this.students); + } + /* add a new student id to the arraylist of student id strings, no return */ + public void addStudent(String studentID) { + this.students.add(studentID); } - /* - arraylist of all the task ids associated with a course - */ public ArrayList getTasks() { - return new ArrayList(this.tasks); + return new ArrayList<>(this.tasks); } - public Boolean getPublished() { - return published; + /* new task added to course (input from instructor user) */ + public void addTask(String taskID) { + this.tasks.add(taskID); + } + +// public Boolean getPublished() { +// return published; +// } + public boolean courseIsValid() { + return !(courseName.equals("") || courseInstructor.equals("") || tasks.isEmpty()); } /* setters + don't think any setters are needed... */ public void setCourseName(String courseName) { this.courseName = courseName; @@ -74,10 +86,10 @@ public void setCourseID(String courseID) { this.courseID = courseID; } public void setStudents(ArrayList students) { - this.students = new ArrayList(students); + this.students = new ArrayList<>(students); } public void setTasks(ArrayList tasks) { - this.tasks = new ArrayList(tasks); + this.tasks = new ArrayList<>(tasks); } /** @@ -87,7 +99,7 @@ public void setTasks(ArrayList tasks) { public void removeTask(Task task) { this.tasks.remove(task.getId()); } - public void setPublished(Boolean published) { - this.published = published; - } +// public void setPublished(Boolean published) { +// this.published = published; +// } } diff --git a/src/main/java/entities/CourseMap.java b/src/main/java/entities/CourseMap.java index eae4450..c834a0e 100644 --- a/src/main/java/entities/CourseMap.java +++ b/src/main/java/entities/CourseMap.java @@ -1,43 +1,44 @@ package entities; - -import java.io.Serializable; -import java.util.HashMap; - -/** - * A map of courseID to the Course - */ - -public class CourseMap implements Serializable { - private static HashMap courseMap; - - - /** - * Find a course using its unique ID - * @param id the unique ID of the course - * @return the Course object associated with the ID - */ - public static Course findCourse(String id) { - return courseMap.get(id); - } - - /** - * @param id the unique ID of the Course object - * @param course the course associated with Course - * @return if the course has been added - */ - public static boolean addCourse(String id, Course course) { - if (courseMap.containsKey(id)) { - return false; - } - courseMap.put(id, course); - return true; - } - - public void save() { - - } - - public void load() { - - } -} +// +//import java.io.Serializable; +//import java.util.HashMap; +// +///** +// * A map of courseID to the Course +// */ +// +//public class CourseMap implements Serializable { +// private static HashMap courseMap; +// +// +// /** +// * Find a course using its unique ID +// * @param id the unique ID of the course +// * @return the Course object associated with the ID +// */ +// public static Course findCourse(String id) { +// return courseMap.get(id); +// } +// +// /** +// * @param id the unique ID of the Course object +// * @param course the course associated with Course +// * @return if the course has been added +// */ +// public static boolean addCourse(String id, Course course) { +// // 2 courses have the same id +// if (courseMap.containsKey(id)) { +// return false; +// } +// courseMap.put(id, course); +// return true; +// } +// +// public void save() { +// +// } +// +// public void load() { +// +// } +//} diff --git a/src/main/java/screens/courses_features/CourseCreationController.java b/src/main/java/screens/course_features/CourseCreationController.java similarity index 96% rename from src/main/java/screens/courses_features/CourseCreationController.java rename to src/main/java/screens/course_features/CourseCreationController.java index f41d078..161ae82 100644 --- a/src/main/java/screens/courses_features/CourseCreationController.java +++ b/src/main/java/screens/course_features/CourseCreationController.java @@ -1,4 +1,4 @@ -package screens.courses_features; +package screens.course_features; import use_cases.course_features.course_creation_use_case.CourseCreationInputBoundary; import use_cases.course_features.course_creation_use_case.CourseCreationRequestModel; @@ -19,5 +19,4 @@ CourseCreationResponseModel create(String courseName, String courseInstructor, return courseInput.create(requestModel); } - } \ No newline at end of file diff --git a/src/main/java/screens/courses_features/CourseCreationFailed.java b/src/main/java/screens/course_features/CourseCreationFailed.java similarity index 80% rename from src/main/java/screens/courses_features/CourseCreationFailed.java rename to src/main/java/screens/course_features/CourseCreationFailed.java index 87a422c..b198745 100644 --- a/src/main/java/screens/courses_features/CourseCreationFailed.java +++ b/src/main/java/screens/course_features/CourseCreationFailed.java @@ -1,4 +1,4 @@ -package screens.courses_features; +package screens.course_features; public class CourseCreationFailed extends RuntimeException { public CourseCreationFailed(String error) { diff --git a/src/main/java/screens/courses_features/CourseCreationResponseFormatter.java b/src/main/java/screens/course_features/CourseCreationPresenter.java similarity index 85% rename from src/main/java/screens/courses_features/CourseCreationResponseFormatter.java rename to src/main/java/screens/course_features/CourseCreationPresenter.java index ea19ce8..2384b84 100644 --- a/src/main/java/screens/courses_features/CourseCreationResponseFormatter.java +++ b/src/main/java/screens/course_features/CourseCreationPresenter.java @@ -1,13 +1,13 @@ -package screens.courses_features; +package screens.course_features; // Interface adapters layer -import use_cases.course_features.course_creation_use_case.CourseCreationPresenter; +import use_cases.course_features.course_creation_use_case.CourseCreationOutputBoundary; import use_cases.course_features.course_creation_use_case.CourseCreationResponseModel; import javax.swing.*; -public class CourseCreationResponseFormatter implements CourseCreationPresenter { +public class CourseCreationPresenter implements CourseCreationOutputBoundary { /** * Alert user to course creation success @@ -15,7 +15,6 @@ public class CourseCreationResponseFormatter implements CourseCreationPresenter */ @Override public CourseCreationResponseModel prepareSuccessView(CourseCreationResponseModel response) { - JOptionPane.showMessageDialog(null, "New course created!"); return response; } diff --git a/src/main/java/screens/courses_features/CourseCreationScreen.java b/src/main/java/screens/course_features/CourseCreationScreen.java similarity index 71% rename from src/main/java/screens/courses_features/CourseCreationScreen.java rename to src/main/java/screens/course_features/CourseCreationScreen.java index 5829861..3f5b89f 100644 --- a/src/main/java/screens/courses_features/CourseCreationScreen.java +++ b/src/main/java/screens/course_features/CourseCreationScreen.java @@ -1,4 +1,4 @@ -package screens.courses_features; +package screens.course_features; // Framework / Drivers layer @@ -9,6 +9,8 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; public class CourseCreationScreen extends JPanel implements ActionListener { /** the course name chosen by InstructorUser */ @@ -18,7 +20,7 @@ public class CourseCreationScreen extends JPanel implements ActionListener { JTextField courseInstructor = new JTextField(15); /** title of task */ - JTextField taskName = new JTextField(15); + JTextField taskNames = new JTextField(15); /** the controller */ CourseCreationController courseCreationController; @@ -47,12 +49,7 @@ public CourseCreationScreen(CourseCreationController controller, JPanel screens, LabelTextPanel courseInstructorInfo = new LabelTextPanel( new JLabel("Enter instructor name"), courseInstructor); LabelTextPanel taskNameInfo = new LabelTextPanel( - new JLabel("Enter task title"), taskName); - - // to do: - // need the option to input more than one task at a time - // can just separate by commas (ie. user enters -- task 1, task 2, task 3) - // or can have a '+' button that creates a new text panel for a new task + new JLabel("Enter task title(s), separated by a comma"), taskNames); // buttons JButton cancel = new JButton("Cancel"); @@ -77,20 +74,31 @@ public CourseCreationScreen(CourseCreationController controller, JPanel screens, /** * React to a button click which triggers the corresponding use case + * have to keep try catch, or else error messages won't show up + * NEED TO FIX THIS!!! + * 1. loop through tasks + append */ @Override public void actionPerformed(ActionEvent evt) { // instructor decides to cancel the course creation process if (evt.getActionCommand().equals("Cancel")) { - screenLayout.show(screens, "StudentMain"); + screenLayout.show(screens, "InstructorMain"); } else if (evt.getActionCommand().equals("Save")) { try { - // initialize new Arraylist and add task - ArrayList tasks = new ArrayList<>(); - tasks.add(taskName.getText()); + // tasksNames right now is an arraylist of ONE string with the string being "task1, task2" + // split string so that each task is a string + String[] tasksSplit = taskNames.getText().split(","); + List taskArrayList; + taskArrayList = Arrays.asList(tasksSplit); + + // tasklist should be arraylist ["task1", "task2"] + // add all strings to arraylist 'tasks' + ArrayList tasks = new ArrayList<>(taskArrayList); + courseCreationController.create(courseName.getText(), courseInstructor.getText(), tasks); - JOptionPane.showMessageDialog(this, "Course successful created."); + JOptionPane.showMessageDialog( + this, "Course" + courseName.getText() + "and tasks" + tasks + "successfully created."); } catch (Exception e) { JOptionPane.showMessageDialog(this, e.getMessage()); } diff --git a/src/main/java/screens/courses_features/CourseEnrolmentController.java b/src/main/java/screens/course_features/CourseEnrolmentController.java similarity index 77% rename from src/main/java/screens/courses_features/CourseEnrolmentController.java rename to src/main/java/screens/course_features/CourseEnrolmentController.java index 124ce8b..421d5a6 100644 --- a/src/main/java/screens/courses_features/CourseEnrolmentController.java +++ b/src/main/java/screens/course_features/CourseEnrolmentController.java @@ -1,4 +1,4 @@ -package screens.courses_features; +package screens.course_features; import use_cases.course_features.course_enrolment_use_case.CourseEnrolmentInputBoundary; import use_cases.course_features.course_enrolment_use_case.CourseEnrolmentRequestModel; @@ -10,11 +10,10 @@ public CourseEnrolmentController(CourseEnrolmentInputBoundary enrolmentGateway) this.enrolmentInput = enrolmentGateway; } - CourseEnrolmentResponseModel create(String courseID, String instructorID, String studentID) { + CourseEnrolmentResponseModel enrol(String courseID, String instructorID, String studentID) { CourseEnrolmentRequestModel requestModel = new CourseEnrolmentRequestModel( courseID, instructorID, studentID); - return enrolmentInput.create(requestModel); + return enrolmentInput.enrol(requestModel); } - } diff --git a/src/main/java/screens/courses_features/CourseEnrolmentFailed.java b/src/main/java/screens/course_features/CourseEnrolmentFailed.java similarity index 80% rename from src/main/java/screens/courses_features/CourseEnrolmentFailed.java rename to src/main/java/screens/course_features/CourseEnrolmentFailed.java index 42b2f9d..1d13b2f 100644 --- a/src/main/java/screens/courses_features/CourseEnrolmentFailed.java +++ b/src/main/java/screens/course_features/CourseEnrolmentFailed.java @@ -1,4 +1,4 @@ -package screens.courses_features; +package screens.course_features; public class CourseEnrolmentFailed extends RuntimeException { public CourseEnrolmentFailed(String error) { diff --git a/src/main/java/screens/courses_features/CourseEnrolmentResponseFormatter.java b/src/main/java/screens/course_features/CourseEnrolmentPresenter.java similarity index 85% rename from src/main/java/screens/courses_features/CourseEnrolmentResponseFormatter.java rename to src/main/java/screens/course_features/CourseEnrolmentPresenter.java index 66fb903..9ac226a 100644 --- a/src/main/java/screens/courses_features/CourseEnrolmentResponseFormatter.java +++ b/src/main/java/screens/course_features/CourseEnrolmentPresenter.java @@ -1,13 +1,13 @@ -package screens.courses_features; +package screens.course_features; // Interfaces adapters layer -import use_cases.course_features.course_enrolment_use_case.CourseEnrolmentPresenter; +import use_cases.course_features.course_enrolment_use_case.CourseEnrolmentOutputBoundary; import use_cases.course_features.course_enrolment_use_case.CourseEnrolmentResponseModel; import javax.swing.*; -public class CourseEnrolmentResponseFormatter implements CourseEnrolmentPresenter { +public class CourseEnrolmentPresenter implements CourseEnrolmentOutputBoundary { /** * Alert student user about course enrolment success diff --git a/src/main/java/screens/courses_features/CourseEnrolmentScreen.java b/src/main/java/screens/course_features/CourseEnrolmentScreen.java similarity index 74% rename from src/main/java/screens/courses_features/CourseEnrolmentScreen.java rename to src/main/java/screens/course_features/CourseEnrolmentScreen.java index e3fd3c8..b78007b 100644 --- a/src/main/java/screens/courses_features/CourseEnrolmentScreen.java +++ b/src/main/java/screens/course_features/CourseEnrolmentScreen.java @@ -1,4 +1,4 @@ -package screens.courses_features; +package screens.course_features; // Framework/Drivers layer @@ -23,10 +23,18 @@ public class CourseEnrolmentScreen extends JPanel implements ActionListener { CourseEnrolmentController courseEnrolmentController; /** - * Window with title, texts to fill in, and JButtons + * Objects for connecting to the other screens */ - public CourseEnrolmentScreen(CourseEnrolmentController controller) { + JPanel screens; + CardLayout screenLayout; + + /** + * A window with title, text fields to fill in, and JButtons + */ + public CourseEnrolmentScreen(CourseEnrolmentController controller, JPanel screens, CardLayout screenLayout) { this.courseEnrolmentController = controller; + this.screens = screens; + this.screenLayout = screenLayout; // label for the title of the screen JLabel title = new JLabel("Course Enrolment Screen"); @@ -38,7 +46,7 @@ public CourseEnrolmentScreen(CourseEnrolmentController controller) { LabelTextPanel courseInstructorInfo = new LabelTextPanel( new JLabel("Enter instructor name"), courseInstructor); LabelTextPanel studentIDInfo = new LabelTextPanel( - new JLabel("Enter instructor name"), studentID); + new JLabel("Enter your username"), studentID); // buttons JButton cancel = new JButton("Cancel"); @@ -63,21 +71,21 @@ public CourseEnrolmentScreen(CourseEnrolmentController controller) { /** * React to a button click which triggers the corresponding use case + * this probably also needs to be fixed!!! */ @Override public void actionPerformed(ActionEvent evt) { // student user decides to cancel course enrolment process if (evt.getActionCommand().equals("Cancel")) { - try { - // do to - JOptionPane.showMessageDialog(this, "screen should close"); - } catch (Exception e) { - JOptionPane.showMessageDialog(this, e.getMessage()); - } + screenLayout.show(screens, "StudentMain"); } else if (evt.getActionCommand().equals("Search")) { try { - // to do: add studentID to course's task parameter - JOptionPane.showMessageDialog(this, "Successfully enrolled in course."); + // add student id to Course + // add course tasks to Student's todolist + // add course id to Student's courses list + + courseEnrolmentController.enrol(courseName.getText(), courseInstructor.getText(), studentID.getText()); + JOptionPane.showMessageDialog(this, "Successfully enrolled in course. tasks added."); } catch (Exception e) { JOptionPane.showMessageDialog(this, e.getMessage()); } diff --git a/src/main/java/screens/course_features/CourseFoundScreen.java b/src/main/java/screens/course_features/CourseFoundScreen.java new file mode 100644 index 0000000..2cdef8b --- /dev/null +++ b/src/main/java/screens/course_features/CourseFoundScreen.java @@ -0,0 +1,46 @@ +package screens.course_features; + +// Framework/Driver layer + +// Not needed, too much work :) +// usage: when student enters 'search' and searhc successful, this would pop up +// after student clicks 'enrol', then the enrolment process happens + +//import javax.swing.*; +//import java.awt.*; +//import java.awt.event.ActionEvent; +//import java.awt.event.ActionListener; +// +//public class CourseFoundScreen extends JFrame implements ActionListener { +// /** +// * Window with title and 2 JButtons. +// */ +// public CourseFoundScreen() { +// JLabel title = new JLabel("Course Found!"); +// title.setAlignmentX(Component.CENTER_ALIGNMENT); +// +// JButton cancel = new JButton("Cancel"); +// JButton enrol = new JButton("Enrol"); +// +// JPanel buttons = new JPanel(); +// buttons.add(cancel); +// buttons.add(enrol); +// +// cancel.addActionListener(this); +// enrol.addActionListener(this); +// +// JPanel main = new JPanel(); +// main.setLayout(new BoxLayout(main, BoxLayout.Y_AXIS)); +// +// main.add(title); +// main.add(buttons); +// this.setContentPane(main); +// this.pack(); +// } +// +// /** +// * react to button click that results in evt. */ +// public void actionPerformed(ActionEvent evt) { +// System.out.println("Click " + evt.getActionCommand()); +// } +//} diff --git a/src/main/java/screens/course_features/FileCourse.java b/src/main/java/screens/course_features/FileCourse.java new file mode 100644 index 0000000..bd0f4af --- /dev/null +++ b/src/main/java/screens/course_features/FileCourse.java @@ -0,0 +1,149 @@ +package screens.course_features; + +import entities.Course; +import use_cases.course_features.course_creation_use_case.CourseCreationDsGateway; +import use_cases.course_features.course_enrolment_use_case.CourseEnrolmentDsGateway; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +public class FileCourse implements CourseCreationDsGateway, CourseEnrolmentDsGateway { + /** + * is this supposed to be String to Request Model OR String to Course + * for clean architecture: + * private final HashMap courses; + */ + private final HashMap courses; + private final String filePath; + + /** + * reads the Course database file, stores its contents -- HashMap of course id to SaveRequest object + * reads the Course database file, stores its contents -- HashMap of course id to Course object + * @param path the path to the serializable file that will contain the map of course id to course object + */ + public FileCourse(String path) throws IOException, ClassNotFoundException { + this.filePath = path; + + // checks if path or file exists + if (Files.exists(Path.of(path))) { + // exists: read existing file, which is the hashmap of all course ids to course objects + this.courses = readFile(); + } else { + // dne: create and write empty map to new file + this.courses = new HashMap<>(); + saveCourse(); + } + } + + /** + * reads the file + * @return the read hashmap + * after in.close(): + * Remove this "close" call; closing the resource is handled automatically by the try-with-resources. + * fileReader.close(); + */ + public HashMap readFile() throws IOException, ClassNotFoundException { + HashMap f; + try (FileInputStream fileReader = new FileInputStream(this.filePath)) { + ObjectInputStream in = new ObjectInputStream(fileReader); + f = (HashMap) in.readObject(); + in.close(); + } + return f; + } + + /** + * COURSE CREATION GATEWAY + * adds the request model to database + * @param requestModel the course info that is being saved + */ + @Override + public void saveCourse(Course requestModel) throws IOException { + courses.put(requestModel.getCourseID(), requestModel); + this.saveCourse(); + } + + /** + * COURSE CREATION GATEWAY + * writes the map of course ids to course objects into the Course database file + * after out.close(): + * Remove this "close" call; closing the resource is handled automatically by the try-with-resources. + * fileWriter.close(); + */ + private void saveCourse() throws IOException { + try (FileOutputStream fileWriter = new FileOutputStream(filePath)) { + ObjectOutputStream out = new ObjectOutputStream(fileWriter); + out.writeObject(courses); + out.close(); + } + } + + /** + * COURSE CREATION AND ENROLMENT GATEWAY + * return whether a course exists with the course identifier + * @param courseIdentifier the course id to check + */ + @Override + public boolean existsByCourseID(String courseIdentifier) { + return courses.containsKey(courseIdentifier); + } + + public Map getCourses() { + return this.courses; + } + + @Override + /** + * COURSE ENROLMENT GATEWAY + * gets the course object associated with course id + * used to add student's id to students parameter + * and to copy the tasks + * @param courseIdentifier the course id of the course that the student wants to enrol in + */ + public Course searchForCourse(String courseIdentifier) { + return courses.get(courseIdentifier); + } + + /** + * COURSE ENROLMENT GATEWAY + * return whether the student username is already in students parameter + * return whether the student is already enrolled in the course + * @param studentIdentifier the student's username + */ + @Override + public boolean existsStudentInCourse(String courseID, String studentIdentifier) { + return courses.get(courseID).getStudents().contains(studentIdentifier); + } + + /** + * COURSE ENROLMENT GATEWAY + * adds the student's username to the course's students parameter + * @param courseID the course id associated to the course the student wants to enrol in + */ + @Override + public void saveStudentToCourse(String studentID, String courseID) throws IOException { + courses.get(courseID).getStudents().add(studentID); + saveCourse(); + + } + + /** + * COURSE ENROLMENT GATEWAY + * gets the task ids of the course the student wants to enrol in + * copy and change here as well? or toss to task creation request model + * @param requestModel the course we want tasks from + */ + @Override + public ArrayList courseTasks(Course requestModel) { + return requestModel.getTasks(); + } + +// public void add + + // add tasks to student's to do list + // sketchy clean architecture happens here +} \ No newline at end of file diff --git a/src/main/java/screens/course_features/InMemoryCourse.java b/src/main/java/screens/course_features/InMemoryCourse.java new file mode 100644 index 0000000..db59dd6 --- /dev/null +++ b/src/main/java/screens/course_features/InMemoryCourse.java @@ -0,0 +1,60 @@ +package screens.course_features; + +// not needed for functionality, only for testing + +import entities.Course; +import use_cases.course_features.course_creation_use_case.CourseCreationDsGateway; +import use_cases.course_features.course_creation_use_case.CourseCreationRequestModel; +import use_cases.course_features.course_enrolment_use_case.CourseEnrolmentDsGateway; + + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +public class InMemoryCourse implements CourseCreationDsGateway, CourseEnrolmentDsGateway { + private final Map courses = new HashMap<>(); + + // populate + + /** + * @param identifier the course's course id + * @return whether the course exists + */ + @Override + public boolean existsByCourseID(String identifier) { + return courses.containsKey(identifier); + } + + public Map getCourses() { + return this.courses; + } + @Override + public Course searchForCourse(String courseIdentifier) { + return courses.get(courseIdentifier); + } + + @Override + public boolean existsStudentInCourse(String courseID, String studentIdentifier) { + return courses.get(courseID).getStudents().contains(studentIdentifier); + } + + @Override + public void saveStudentToCourse(String studentID, String courseID) throws IOException { + courses.get(courseID).getStudents().add(studentID); + } + + @Override + public ArrayList courseTasks(Course requestModel) { + return requestModel.getTasks(); + } + + /** + * @param requestModel the data to save + */ + @Override + public void saveCourse(Course requestModel) { + System.out.println("Save " + requestModel.getCourseID()); + } +} diff --git a/src/main/java/screens/courses_features/CourseFoundScreen.java b/src/main/java/screens/courses_features/CourseFoundScreen.java deleted file mode 100644 index cf404b9..0000000 --- a/src/main/java/screens/courses_features/CourseFoundScreen.java +++ /dev/null @@ -1,42 +0,0 @@ -package screens.courses_features; - -// Framework/Driver layer - -import javax.swing.*; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -public class CourseFoundScreen extends JFrame implements ActionListener { - /** - * Window with title and 2 JButtons. - */ - public CourseFoundScreen() { - JLabel title = new JLabel("Course Found!"); - title.setAlignmentX(Component.CENTER_ALIGNMENT); - - JButton cancel = new JButton("Cancel"); - JButton enrol = new JButton("Enrol"); - - JPanel buttons = new JPanel(); - buttons.add(cancel); - buttons.add(enrol); - - cancel.addActionListener(this); - enrol.addActionListener(this); - - JPanel main = new JPanel(); - main.setLayout(new BoxLayout(main, BoxLayout.Y_AXIS)); - - main.add(title); - main.add(buttons); - this.setContentPane(main); - this.pack(); - } - - /** - * react to button click that results in evt. */ - public void actionPerformed(ActionEvent evt) { - System.out.println("Click " + evt.getActionCommand()); - } -} diff --git a/src/main/java/screens/courses_features/FileCourse.java b/src/main/java/screens/courses_features/FileCourse.java deleted file mode 100644 index b9436b2..0000000 --- a/src/main/java/screens/courses_features/FileCourse.java +++ /dev/null @@ -1,165 +0,0 @@ -package screens.courses_features; - -import use_cases.course_features.course_creation_use_case.CourseCreationDsGateway; -//import course_creation_use_case.courseCreationDsRequestModel; -import use_cases.course_features.course_creation_use_case.CourseCreationRequestModel; - -/* - * Notes: - * I think for csv file? so columns is what each course entity is? im assuming? idek man - */ -import java.io.*; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -public class FileCourse implements CourseCreationDsGateway { - private final File csvFile; - private final Map headers = new HashMap<>(); - private final Map courses = new HashMap<>(); - - public FileCourse(String csvPath) throws IOException { - csvFile = new File(csvPath); - - headers.put("course_name", 0); - headers.put("course_instructor", 1); - headers.put("tasks?", 2); - - if (csvFile.length() == 0) { - saveCourse(); - } else { - - BufferedReader reader = new BufferedReader(new FileReader(csvFile)); - reader.readLine(); // skip the header - - String row; - while ((row = reader.readLine()) != null) { - String[] col = row.split(","); - String courseName = String.valueOf(col[headers.get("courseName")]); - String courseInstructor = String.valueOf(col[headers.get("courseInstructor")]); - ArrayList tasks = new ArrayList(); // idk what im doing -// /* String.valueOf(col[headers.get("tasks?")]); */ - CourseCreationRequestModel course = new CourseCreationRequestModel(courseName, courseInstructor, tasks); - courses.put(courseName, course); - } - - reader.close(); - - } - - } - - /** - * Add requestModel to storage - * @param requestModel the user information to save - */ - @Override - public void saveCourse(CourseCreationRequestModel requestModel) { - courses.put(requestModel.getCourseName() ,requestModel); - this.saveCourse(); - } - - private void saveCourse() { - BufferedWriter writer; - try { - writer = new BufferedWriter(new FileWriter(csvFile)); - writer.write(String.join(",", headers.keySet())); - writer.newLine(); - - for (CourseCreationRequestModel course : courses.values()) { - String line = "%s,%s,%s".format( - course.getCourseName(), course.getCourseInstructor(), course.getTasks()); - writer.write(line); - writer.newLine(); - } - - writer.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - - } - - @Override - public boolean existsByCourseID(String identifier) { - return courses.containsKey(identifier); - } - -} - -/* - * with ds request but apparently not needed so - */ -//public class FileCourse implements courseCreationDsGateway { -// private final File csvFile; -// private final Map headers = new HashMap<>(); -// private final Map courses = new HashMap<>(); -// -// public FileCourse(String csvPath) throws IOException { -// csvFile = new File(csvPath); -// -// headers.put("courseName", 0); -// headers.put("course instructor", 1); -// headers.put("tasks?", 2); -// -// if (csvFile.length() == 0) { -// saveCourse(); -// } else { -// -// BufferedReader reader = new BufferedReader(new FileReader(csvFile)); -// reader.readLine(); // skip the header -// -// String row; -// while ((row = reader.readLine()) != null) { -// String[] col = row.split(","); -// String courseName = String.valueOf(col[headers.get("courseName")]); -// String courseInstructor = String.valueOf(col[headers.get("courseInstructor")]); -// ArrayList tasks = new ArrayList(); // idk what im doing -//// /* String.valueOf(col[headers.get("tasks?")]); */ -// courseCreationDsRequestModel course = new courseCreationDsRequestModel(courseName, courseInstructor, tasks); -// courses.put(courseName, course); -// } -// -// reader.close(); -// -// } -// -// } -// -// /** -// * Add requestModel to storage -// * @param requestModel the user information to save -// */ -// @Override -// public void saveCourse(courseCreationDsRequestModel requestModel) { -// courses.put(requestModel.getCourseName() ,requestModel); -// this.saveCourse(); -// } -// -// private void saveCourse() { -// BufferedWriter writer; -// try { -// writer = new BufferedWriter(new FileWriter(csvFile)); -// writer.write(String.join(",", headers.keySet())); -// writer.newLine(); -// -// for (courseCreationDsRequestModel course : courses.values()) { -// String line = "%s,%s,%s".format( -// course.getCourseName(), course.getCourseInstructor(), course.getTasks()); -// writer.write(line); -// writer.newLine(); -// } -// -// writer.close(); -// } catch (IOException e) { -// throw new RuntimeException(e); -// } -// -// } -// -// @Override -// public boolean existsByCourseID(String identifier) { -// return courses.containsKey(identifier); -// } -// -//} diff --git a/src/main/java/screens/courses_features/InMemoryCourse.java b/src/main/java/screens/courses_features/InMemoryCourse.java deleted file mode 100644 index 46b6b91..0000000 --- a/src/main/java/screens/courses_features/InMemoryCourse.java +++ /dev/null @@ -1,29 +0,0 @@ -package screens.courses_features; - -import use_cases.course_features.course_creation_use_case.CourseCreationDsGateway; -import use_cases.course_features.course_creation_use_case.CourseCreationRequestModel; - - -import java.util.HashMap; -import java.util.Map; - -public class InMemoryCourse implements CourseCreationDsGateway { - final private Map courses = new HashMap<>(); - - /** - * @param identifier the course's course id - * @return whether the course exists - */ - @Override - public boolean existsByCourseID(String identifier) { - return courses.containsKey(identifier); - } - - /** - * @param requestModel the data to save - */ - @Override - public void saveCourse(CourseCreationRequestModel requestModel) { - System.out.println("Save " + requestModel.getCourseID()); - } -} diff --git a/src/main/java/screens/login_registration/FileUser.java b/src/main/java/screens/login_registration/FileUser.java index ccc7661..b8b7cf2 100644 --- a/src/main/java/screens/login_registration/FileUser.java +++ b/src/main/java/screens/login_registration/FileUser.java @@ -1,16 +1,22 @@ package screens.login_registration; +import entities.Course; +import entities.StudentUser; +import use_cases.course_features.course_enrolment_use_case.CourseEnrolmentDsGateway; +import use_cases.course_features.course_enrolment_use_case.CourseTasksToStudentTodolistDsGateway; import use_cases.login_registration.login_usecase.LoginGateway; import use_cases.login_registration.logout_usecase.LogoutGateway; +import use_cases.login_registration.user_register_usecase.StudentSaveRequest; import use_cases.login_registration.user_register_usecase.UserRegGateway; import use_cases.login_registration.user_register_usecase.UserRegSaveRequest; import java.io.*; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.HashMap; import java.util.Map; -public class FileUser implements UserRegGateway, LoginGateway, LogoutGateway { +public class FileUser implements UserRegGateway, LoginGateway, LogoutGateway, CourseTasksToStudentTodolistDsGateway { // private final HashMap accounts; private static HashMap accounts; @@ -96,4 +102,32 @@ public Map getAccounts() { return accounts; } + /** + * For course enrolment use case (course tasks to do list gateway) + * Adds the course tasks to the student's to-do list + * + * @param studentID the username of the student whose parameters are being modified + * @param courseTasks the course task ids what will be added to the student's 'to do list' parameter + */ + @Override + public void addSaveTasksToTodolist(String studentID, ArrayList courseTasks) throws IOException { + UserRegSaveRequest username = getAccounts().get(studentID); + // casting to student save request + ((StudentSaveRequest) username).getToDoList().addAll(courseTasks); + this.save(); // saves the file with new changes + } + + /** + * For course enrolment use case (course tasks to do list gateway) + * Adds the course id to the student's 'courses' parameter + * @param studentCourse the course the student enrolled in + * @param studentID the username of student enrolled + */ + @Override + public void addCourseToStudent(String studentCourse, String studentID) throws IOException { + UserRegSaveRequest courseInStudent = getAccounts().get(studentID); + // casting to student save request + ((StudentSaveRequest) courseInStudent).getCourses().add(studentCourse); + this.save(); // saves the file with new changes + } } diff --git a/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationDsGateway.java b/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationDsGateway.java index 19200df..f7b5d1f 100644 --- a/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationDsGateway.java +++ b/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationDsGateway.java @@ -2,9 +2,18 @@ // Use case layer +import entities.Course; + +import java.io.IOException; + + +/** + * Gateway containing the following methods (override in FileCourse) + * existsByCourseID: takes course id and checks whether that is a key in the database's hashmap + * saveCourse: takes course id and created course object, and adds it to the course hashmap database + */ public interface CourseCreationDsGateway { - // checks if the course is already in the course map by its unique id boolean existsByCourseID(String courseIdentifier); - void saveCourse(CourseCreationRequestModel requestModel); + void saveCourse(Course requestModel) throws IOException; } diff --git a/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationInteractor.java b/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationInteractor.java index feedc76..71df195 100644 --- a/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationInteractor.java +++ b/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationInteractor.java @@ -4,16 +4,18 @@ import entities.*; +import java.io.IOException; + public class CourseCreationInteractor implements CourseCreationInputBoundary { final CourseCreationDsGateway courseCreationDSGateway; - final CourseCreationPresenter courseCreationPresenter; - final CourseMap courseMap; + // this is called in filecourse, where stuff is added / modified in the database + final CourseCreationOutputBoundary courseCreationOutputBoundary; + private Course course; // for response model - public CourseCreationInteractor(CourseCreationDsGateway courseCreationDSGateway, CourseCreationPresenter courseCreationPresenter, - CourseMap courseMap) { + public CourseCreationInteractor(CourseCreationDsGateway courseCreationDSGateway, + CourseCreationOutputBoundary courseCreationOutputBoundary) { this.courseCreationDSGateway = courseCreationDSGateway; - this.courseCreationPresenter = courseCreationPresenter; - this.courseMap = courseMap; + this.courseCreationOutputBoundary = courseCreationOutputBoundary; } /** @@ -25,29 +27,43 @@ public CourseCreationResponseModel create(CourseCreationRequestModel requestMode // At least one field left blank if (requestModel.getCourseName().equals("") || requestModel.getCourseInstructor().equals("") || requestModel.getTasks().isEmpty()) { - return courseCreationPresenter.prepareFailView("Please fill in all required information."); + return courseCreationOutputBoundary.prepareFailView("Please fill in all required information."); } - // Note: Jonathan - no need to check the type of User, students and instructors - // would have different views because they are in different use cases - // checks whether the course id is already in the CourseMap (course already exists) + // checks whether the course id is already in the database / hashmap if (courseCreationDSGateway.existsByCourseID(requestModel.getCourseID())) { - return courseCreationPresenter.prepareFailView("Course already exists."); + return courseCreationOutputBoundary.prepareFailView("Course already exists."); } + // checks whether the instructor's entered task ids correspond to a task in the taskmap + + /* + ArrayList courseTasks = requestModel.getTasks(); + for (String task : courseTasks) { + if (TaskMap.findTask(task) == null) { + return courseCreationOutputBoundary.prepareFailView("one of the IDs does not correspond with a task."); + } + } + */ + + // checks passed; course can be created // create a new course - Course course = new Course(requestModel.getCourseName(), requestModel.getCourseInstructor(), requestModel.getTasks()); - CourseMap.addCourse(requestModel.getCourseID(), course); - - // course successfully created and saved - CourseCreationRequestModel courseCreationModel = new CourseCreationRequestModel(course.getCourseName(), course.getCourseInstructor(), course.getTasks()); - courseCreationDSGateway.saveCourse(courseCreationModel); + Course courseModel = new Course(requestModel.getCourseName(), requestModel.getCourseInstructor(), requestModel.getTasks()); + try { + courseCreationDSGateway.saveCourse(courseModel); + } catch (IOException e) { + throw new RuntimeException(e); + } - // course sent to presenter + // create response model, sent to presenter CourseCreationResponseModel courseResponseModel = new CourseCreationResponseModel( - course.getCourseID(), course.getTasks()); - return courseCreationPresenter.prepareSuccessView(courseResponseModel); + courseModel.getCourseID(), courseModel.getTasks()); + return courseCreationOutputBoundary.prepareSuccessView(courseResponseModel); + } + + public Course getCourse() { + return this.course; } } diff --git a/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationPresenter.java b/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationOutputBoundary.java similarity index 91% rename from src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationPresenter.java rename to src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationOutputBoundary.java index d07fa5a..84881b0 100644 --- a/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationPresenter.java +++ b/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationOutputBoundary.java @@ -2,7 +2,7 @@ // Use case layer -public interface CourseCreationPresenter { +public interface CourseCreationOutputBoundary { /** * Alerts user that course creation is successful (no existing course) diff --git a/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationRequestModel.java b/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationRequestModel.java index da2a6dd..46b662b 100644 --- a/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationRequestModel.java +++ b/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationRequestModel.java @@ -12,16 +12,17 @@ import java.util.ArrayList; public class CourseCreationRequestModel { - private String courseName; - private String courseInstructor; + private final String courseName; + private final String courseInstructor; private final String courseID; - private ArrayList tasks; + private final ArrayList tasks; /** * Creates a request model with the given input - * @param courseName the name of the course + * + * @param courseName the name of the course * @param courseInstructor the instructor of the course - * @param tasks the task(s) associated with the course + * @param tasks the task(s) associated with the course */ public CourseCreationRequestModel(String courseName, String courseInstructor, ArrayList tasks) { this.courseName = courseName; @@ -34,30 +35,15 @@ public String getCourseName() { return courseName; } - public void setCourseName() { - - this.courseName = courseName; - } - public String getCourseInstructor() { return courseInstructor; } - public void setCourseInstructor() { - - this.courseInstructor = courseInstructor; - } - public String getCourseID() { return courseID; } public ArrayList getTasks() { - return tasks; } - - public void setTasks() { - this.tasks = tasks; - } -} +} \ No newline at end of file diff --git a/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationResponseModel.java b/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationResponseModel.java index a846056..c3bc802 100644 --- a/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationResponseModel.java +++ b/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationResponseModel.java @@ -26,16 +26,8 @@ public CourseCreationResponseModel(String courseID, ArrayList tasks) { public String getCourseID() { return courseID; } - public void setCourseID() { - this.courseID = courseID; - } public ArrayList getTasks() { return tasks; } - - // i don't think this is needed - public void setTasks() { - this.tasks = tasks; - } } diff --git a/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationSaveRequest.java b/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationSaveRequest.java new file mode 100644 index 0000000..1e29cca --- /dev/null +++ b/src/main/java/use_cases/course_features/course_creation_use_case/CourseCreationSaveRequest.java @@ -0,0 +1,7 @@ +//package use_cases.course_features.course_creation_use_case; +// +//import java.io.Serializable; +// +//public class CourseCreationSaveRequest implements Serializable { +// +//} diff --git a/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentDsGateway.java b/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentDsGateway.java index ee88654..eb1275e 100644 --- a/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentDsGateway.java +++ b/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentDsGateway.java @@ -2,10 +2,25 @@ // Use case layer +import entities.Course; + +import java.io.IOException; +import java.util.ArrayList; + +/** + * Gateway containing the following methods (override in FileCourse) + * NOTE: THIS INVOLVES ONLY METHODS REQUIRING ACCESS TO FILECOURSE + * existsByCourseID: need to check if the course student wants to enrol in actually exists + * existsByStudent: checks if student username exists in the course's 'students' parameter + * searchForCourse: find the course object associated with the course id if it exists + * saveStudentToCourse: takes student username and appends it to the Course's 'students' parameter + * courseTasks: the course's 'tasks' parameter; a list of task id strings + */ public interface CourseEnrolmentDsGateway { - // checks if student is in the course through the students argument of the Course - // object (value) from the course id (key) - boolean existsByStudent(String studentIdentifier); + boolean existsByCourseID(String courseIdentifier); // exact same name as CourseCreationDsGateway + public Course searchForCourse(String courseIdentifier); + boolean existsStudentInCourse(String courseID, String studentIdentifier); + void saveStudentToCourse(String studentID, String courseID) throws IOException; + public ArrayList courseTasks(Course requestModel); - void saveStudent(CourseEnrolmentRequestModel requestModel); } diff --git a/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentInputBoundary.java b/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentInputBoundary.java index b1d7980..711e32d 100644 --- a/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentInputBoundary.java +++ b/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentInputBoundary.java @@ -3,5 +3,5 @@ // Use case layer public interface CourseEnrolmentInputBoundary { - CourseEnrolmentResponseModel create(CourseEnrolmentRequestModel requestModel); + CourseEnrolmentResponseModel enrol(CourseEnrolmentRequestModel requestModel); } diff --git a/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentInteractor.java b/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentInteractor.java index 0c2fffc..9b90cb4 100644 --- a/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentInteractor.java +++ b/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentInteractor.java @@ -1,65 +1,137 @@ package use_cases.course_features.course_enrolment_use_case; - // Use case layer import entities.*; +import screens.login_registration.FileUser; +import use_cases.login_registration.user_register_usecase.UserRegGateway; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; public class CourseEnrolmentInteractor implements CourseEnrolmentInputBoundary { - final CourseEnrolmentDsGateway courseEnrolmentDsGateway; - final CourseEnrolmentPresenter courseEnrolmentPresenter; - final CourseMap courseMap; - final String studentID; - public CourseEnrolmentInteractor(CourseEnrolmentDsGateway courseEnrolmentDsGateway, CourseEnrolmentPresenter courseEnrolmentPresenter, - CourseMap courseMap, String studentID) { + final CourseEnrolmentDsGateway courseEnrolmentDsGateway; // the course +// final UserRegGateway userRegGateway; // the student + final CourseTasksToStudentTodolistDsGateway tasksToTodolistDsGateway; + final CourseEnrolmentOutputBoundary courseEnrolmentOutputBoundary; // the presenter + private StudentUser student; // for response model + private Course enrolledCourse; // for response model + + public CourseEnrolmentInteractor(CourseEnrolmentDsGateway courseEnrolmentDsGateway, + CourseTasksToStudentTodolistDsGateway tasksToDodolistDsGateway, + CourseEnrolmentOutputBoundary courseEnrolmentOutputBoundary) { this.courseEnrolmentDsGateway = courseEnrolmentDsGateway; - this.courseEnrolmentPresenter = courseEnrolmentPresenter; - this.courseMap = courseMap; - this.studentID = studentID; + this.tasksToTodolistDsGateway = tasksToDodolistDsGateway; +// this.userRegGateway = userRegGateway; + this.courseEnrolmentOutputBoundary = courseEnrolmentOutputBoundary; } /** - * Executes task in the request model and returns the corresponding response model + * Creates the task in the request model and returns the corresponding response model * @param requestModel the input from the student user */ @Override - public CourseEnrolmentResponseModel create(CourseEnrolmentRequestModel requestModel) { + public CourseEnrolmentResponseModel enrol(CourseEnrolmentRequestModel requestModel) { // At least one field left blank if (requestModel.getCourseName().equals("") || requestModel.getCourseInstructor().equals("") - || requestModel.getStudentID().equals("")) { - return courseEnrolmentPresenter.prepareFailView("Please fill in all required information." ); + || requestModel.getStudentID().equals("")) { + return courseEnrolmentOutputBoundary.prepareFailView("Please fill in all required information."); } // checks if given course id is in the map of existing courses - if (CourseMap.findCourse(requestModel.getCourseID()) == null) { - return courseEnrolmentPresenter.prepareFailView("Entered information does not correspond to an existing course."); + if (courseEnrolmentDsGateway.existsByCourseID(requestModel.getCourseID())) { + return courseEnrolmentOutputBoundary.prepareFailView("Entered information does not correspond to an existing course."); } // checks whether the student is already enrolled in the course - // CourseMap is courseid : Course object - // with course id, find its corresponding Course value, go to its students parameter, and search through that :) + if (courseEnrolmentDsGateway.existsStudentInCourse(requestModel.getCourseID(), requestModel.getStudentID())) { + return courseEnrolmentOutputBoundary.prepareFailView("Already enrolled in course."); + } + + // checks passed; student can be enrolled + alias of course's tasks created + // no need to import FileCourse because it implements the gateway + + // add student id to Course parameter 'students' + // saveStudentToCourse methods take care of saving the changes to the file? + try { + courseEnrolmentDsGateway.saveStudentToCourse(requestModel.getStudentID(), requestModel.getCourseID()); + } catch (IOException e) { + throw new RuntimeException(e); + } + + // clone course tasks and save to task map (with new student-related ids) + + // tasks should be properly initialized sent to student + + // get course's tasks by creating an alias of the Courses tasks parameter (needs to be referring to the same tasks) + ArrayList courseTaskTitlesCopy = courseEnrolmentDsGateway.courseTasks(courseEnrolmentDsGateway.searchForCourse(requestModel.getCourseID())); + + // below: more clearly shows aliasing but warning for redundant variables + // ArrayList courseTaskTitles = courseEnrolmentDsGateway.courseTasks(courseEnrolmentDsGateway.searchForCourse(requestModel.getCourseID())); + // ArrayList courseTaskTitlesCopy = courseTaskTitles; - // to do -// if (CourseMap.value(requestModel.getCourseID()).contains(courseEnrolmentDsGateway.existsByStudent(requestModel.getStudentID()))) { -// return courseEnrolmentPresenter.prepareFailView("Already enrolled in course."); -// } + // make courseTasks into proper id format: courseTasks_instructor_course, add to an arraylist of Tasks + String instructorName = requestModel.getCourseInstructor(); + String courseName = requestModel.getCourseName(); - // checks passed; student id can be added to course's students parameter + ArrayList courseTaskId = new ArrayList<>(); + for (String taskTitleToId : courseTaskTitlesCopy) { + taskTitleToId = taskTitleToId + "_" + instructorName + "_" + courseName; + courseTaskId.add(taskTitleToId); + } + + // get task id : task object pairs from taskmap, save to old task id map + HashMap oldTaskIdMap = new HashMap<>(); + for (String oldTaskId : courseTaskId) { + Task taskValue = TaskMap.findTask(oldTaskId); + oldTaskIdMap.put(oldTaskId, taskValue); + } - // get the student's id (their username) - String enrolledStudent = requestModel.getStudentID(); - // to do: add the student id to the associated courses' task parameter - // .getStudentId.add....... + // for each task id : Task pair, change the key name to courseTasks_student_course, add key-value pair to arraylist + // create new arraylist + HashMap newTaskIdMap = new HashMap<>(); + // iterate over original arraylist and put key-value pair into new arraylist with modified key + for (HashMap.Entry entry : oldTaskIdMap.entrySet()) { + // key has old format title_instructor_course + // want to title, so split by _ which gives 'title', 'instructor', 'course' + // take first index which is just 'title' + // concatenating everything gives title_student_course + newTaskIdMap.put(entry.getKey().split("_")[0] + "_" + requestModel.getStudentID() + "_" + courseName, + (Task) oldTaskIdMap.entrySet()); + } + + // add map with new task ids to TaskMap + // TODO: read file, make edits, then save changes + for (Map.Entry entry : newTaskIdMap.entrySet()) { + TaskMap.addTask(entry.getKey(), entry.getValue()); + } + + // take the keys of the key-value pair and add to student's to do list + // get the set of all keys of the new task id map and add to arraylist of strings + ArrayList newTaskIds = new ArrayList<>(newTaskIdMap.keySet()); + + // add new task ids to the student's task list + try { + tasksToTodolistDsGateway.addSaveTasksToTodolist(requestModel.getStudentID(), newTaskIds); + } catch (IOException e) { + throw new RuntimeException(e); + } + + // add course to student's 'courses' parameter + try { + tasksToTodolistDsGateway.addCourseToStudent(requestModel.getCourseID(), requestModel.getStudentID()); + } catch (IOException e) { + throw new RuntimeException(e); + } - // course edits updated - // to do: need a 'updateCourse' method? + // create response model, sent to presenter + CourseEnrolmentResponseModel enrolmentResponseModel = new CourseEnrolmentResponseModel( + student.getName(), enrolledCourse.getCourseID(), courseTaskTitlesCopy); - // sent to presenter - // to do: fix this - CourseEnrolmentResponseModel enrolmentResponseModel = - new CourseEnrolmentResponseModel(enrolledStudent.toLowerCase()); - return courseEnrolmentPresenter.prepareSuccessView(enrolmentResponseModel); + return courseEnrolmentOutputBoundary.prepareSuccessView(enrolmentResponseModel); } } diff --git a/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentPresenter.java b/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentOutputBoundary.java similarity index 91% rename from src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentPresenter.java rename to src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentOutputBoundary.java index 8b97fae..9693ffc 100644 --- a/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentPresenter.java +++ b/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentOutputBoundary.java @@ -3,7 +3,7 @@ // Use case layer -public interface CourseEnrolmentPresenter { +public interface CourseEnrolmentOutputBoundary { /** * Alerts student user that course enrolment is successful diff --git a/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentRequestModel.java b/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentRequestModel.java index 64bdcf2..3aa5ce9 100644 --- a/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentRequestModel.java +++ b/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentRequestModel.java @@ -2,12 +2,21 @@ // Use case layer +import java.util.ArrayList; + public class CourseEnrolmentRequestModel { - private String courseName; - private String courseInstructor; + private final String courseName; + private final String courseInstructor; private final String courseID; private final String studentID; +// private ArrayList tasks; + /** + * Creates a request model with the given input + * @param courseName the name of the course + * @param courseInstructor the instructor of the course + * @param studentID the student user's username (unique id) + */ public CourseEnrolmentRequestModel(String courseName, String courseInstructor, String studentID) { this.courseName = courseName; @@ -16,24 +25,14 @@ public CourseEnrolmentRequestModel(String courseName, String courseInstructor, this.studentID = studentID; } - /** - * Change getters to public? - */ public String getCourseName() { return courseName; } - public void setCourseName() { - this.courseName = courseName; - } - public String getCourseInstructor() { return courseInstructor; } - public void setCourseInstructor() { - this.courseInstructor = courseInstructor; - } public String getCourseID() { return courseID; @@ -42,4 +41,7 @@ public String getCourseID() { public String getStudentID() { return studentID; } +// public ArrayList getTasks() { +// return tasks; +// } } diff --git a/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentResponseModel.java b/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentResponseModel.java index a6826f5..c1d4c72 100644 --- a/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentResponseModel.java +++ b/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseEnrolmentResponseModel.java @@ -2,9 +2,12 @@ import java.util.ArrayList; +// Use case layer + public class CourseEnrolmentResponseModel { - String studentID; -// ArrayList tasks; // not sure if this goes here + String studentID; // part 1: adding student to course + String courseID; // part 1 + ArrayList tasks; // part 2: getting tasks from course /** @@ -12,16 +15,18 @@ public class CourseEnrolmentResponseModel { * The CourseMap will only be storing the IDs of enrolled StudentUsers * @param studentID the ID corresponding to the StudentUser */ - public CourseEnrolmentResponseModel(String studentID) { + public CourseEnrolmentResponseModel(String studentID, String courseID, ArrayList tasks) { this.studentID = studentID; -// this.tasks = tasks; + this.courseID = courseID; + this.tasks = tasks; } - public String getStudentID() { return studentID; } - -// public ArrayList getTasks() { -// return tasks; -// } + public String getCourseID() { + return courseID; + } + public ArrayList getTasks() { + return tasks; + } } diff --git a/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseTasksToStudentTodolistDsGateway.java b/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseTasksToStudentTodolistDsGateway.java new file mode 100644 index 0000000..6e0fe26 --- /dev/null +++ b/src/main/java/use_cases/course_features/course_enrolment_use_case/CourseTasksToStudentTodolistDsGateway.java @@ -0,0 +1,19 @@ +package use_cases.course_features.course_enrolment_use_case; + +// Use case layer + +import entities.StudentUser; + +import java.io.IOException; +import java.util.ArrayList; + +/** + * Gateway containing the following methods (override in FileUser) + * addSaveTasksToTodolist: takes tasks with new student username-curated ids + * and appends to Student's 'todolist' parameter + */ +public interface CourseTasksToStudentTodolistDsGateway { +// public StudentUser searchForStudent(String studentIdentifier); + public void addSaveTasksToTodolist(String studentID, ArrayList courseTasks) throws IOException; + public void addCourseToStudent(String studentCourse, String studentID) throws IOException; +} diff --git a/src/main/java/use_cases/login_registration/user_register_usecase/UserRegSaveRequest.java b/src/main/java/use_cases/login_registration/user_register_usecase/UserRegSaveRequest.java index ea0005d..a9e0efd 100644 --- a/src/main/java/use_cases/login_registration/user_register_usecase/UserRegSaveRequest.java +++ b/src/main/java/use_cases/login_registration/user_register_usecase/UserRegSaveRequest.java @@ -48,6 +48,7 @@ public LocalDateTime getCreationTime() { return creationTime; } + /** * @return a User based on the information stored in this UserRegSaveRequest object * Default is StudentUser diff --git a/src/main/java/users b/src/main/java/users new file mode 100644 index 0000000..e69de29 diff --git a/src/test/java/FileUserTest.java b/src/test/java/FileUserTest.java index f25e628..c2a019a 100644 --- a/src/test/java/FileUserTest.java +++ b/src/test/java/FileUserTest.java @@ -26,41 +26,41 @@ public class FileUserTest { public FileUserTest() throws IOException, ClassNotFoundException { } - @Test - void saveUsers() throws IOException, ClassNotFoundException { - FileUser f_u = new FileUser("src/test/java/data/userstest.ser"); - f_u.save(ssri); - assert f_u.existsByName("dhakaad"); - f_u.save(bruh); - assert f_u.existsByName("zinda"); - } +// @Test +// void saveUsers() throws IOException, ClassNotFoundException { +// FileUser f_u = new FileUser("src/test/java/data/userstest.ser"); +// f_u.save(ssri); +// assert f_u.existsByName("dhakaad"); +// f_u.save(bruh); +// assert f_u.existsByName("zinda"); +// } StudentSaveRequest ssri2 = new StudentSaveRequest("plant", "vanillawhey", student, LocalDateTime.now()); InstructorSaveRequest bruh2 = new InstructorSaveRequest("cacti", "waterbottle", instructor, LocalDateTime.now()); - @Test - void readUsers() throws IOException, ClassNotFoundException { - FileUser f_u2 = new FileUser("src/test/java/data/userstest.ser"); - f_u2.save(ssri2); - f_u2.save(bruh2); - Set s = f_u2.getAccounts().keySet(); - String[] names = {"zinda", "dhakaad", "plant", "cacti"}; - assert s.containsAll(List.of(names)); - } +// @Test +// void readUsers() throws IOException, ClassNotFoundException { +// FileUser f_u2 = new FileUser("src/test/java/data/userstest.ser"); +// f_u2.save(ssri2); +// f_u2.save(bruh2); +// Set s = f_u2.getAccounts().keySet(); +// String[] names = {"zinda", "dhakaad", "plant", "cacti"}; +// assert s.containsAll(List.of(names)); +// } StudentSaveRequest ssri3 = new StudentSaveRequest("plant", "changedPass", student, LocalDateTime.now()); - @Test - void updateUsers() throws IOException, ClassNotFoundException { - FileUser f_u3 = new FileUser("src/test/java/data/userstest.ser"); - f_u3.save(ssri3); - Map accounts = f_u3.getAccounts(); - StudentSaveRequest s = (StudentSaveRequest) accounts.get("plant"); - assert s.getPass().equals("changedPass"); - - } +// @Test +// void updateUsers() throws IOException, ClassNotFoundException { +// FileUser f_u3 = new FileUser("src/test/java/data/userstest.ser"); +// f_u3.save(ssri3); +// Map accounts = f_u3.getAccounts(); +// StudentSaveRequest s = (StudentSaveRequest) accounts.get("plant"); +// assert s.getPass().equals("changedPass"); +// +// } } diff --git a/src/test/java/data/userstest.ser b/src/test/java/data/userstest.ser deleted file mode 100644 index 4adea51..0000000 Binary files a/src/test/java/data/userstest.ser and /dev/null differ diff --git a/src/test/java/test_course_features/CourseCreationInteractorTest.java b/src/test/java/test_course_features/CourseCreationInteractorTest.java new file mode 100644 index 0000000..32cf242 --- /dev/null +++ b/src/test/java/test_course_features/CourseCreationInteractorTest.java @@ -0,0 +1,50 @@ +package test_course_features; + +import entities.Course; +import org.junit.Test; +import screens.course_features.CourseCreationPresenter; +import screens.course_features.InMemoryCourse; +import use_cases.course_features.course_creation_use_case.*; + +import java.io.IOException; +import java.util.ArrayList; + +//import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.*; + + +public class CourseCreationInteractorTest { + @Test + public void create() throws IOException { + CourseCreationDsGateway courseRepository = new InMemoryCourse(); + + CourseCreationOutputBoundary presenter = new CourseCreationPresenter() { + + @Override + public CourseCreationResponseModel prepareSuccessView(CourseCreationResponseModel newCourse) { + // 4. check output data and associated changes are correct + assertEquals("course1inst1", newCourse.getCourseID()); + assertNotNull(newCourse.getTasks()); + assertTrue(courseRepository.existsByCourseID("course1inst1")); + return null; + } + + @Override + public CourseCreationResponseModel prepareFailView(String error) { + fail("Use case failure is unexpected."); + return null; + } + }; + + ArrayList tasks = new ArrayList<>(); + tasks.add("task1"); + tasks.add("task2"); + Course course = new Course("course1", "inst1", tasks); + CourseCreationInputBoundary interactor = new CourseCreationInteractor(courseRepository, presenter); + + CourseCreationRequestModel inputData = new CourseCreationRequestModel( + "course1", "inst1", tasks); + + interactor.create(inputData); + } +} diff --git a/src/test/java/test_course_features/CourseEnrolmentInteractorTest.java b/src/test/java/test_course_features/CourseEnrolmentInteractorTest.java new file mode 100644 index 0000000..bb3e940 --- /dev/null +++ b/src/test/java/test_course_features/CourseEnrolmentInteractorTest.java @@ -0,0 +1,64 @@ +package test_course_features; + +//import entities.Course; +//import entities.StudentUser; +//import org.junit.jupiter.api.Assertions; +//import org.junit.jupiter.api.Test; +//import screens.course_features.InMemoryCourse; +//import screens.login_registration.InMemoryUser; +//import use_cases.course_features.course_creation_use_case.CourseCreationDsGateway; +//import use_cases.login_registration.user_register_usecase.UserRegGateway; +// +//import use_cases.course_features.course_enrolment_use_case.*; +// +//import java.util.ArrayList; +// +//import static org.junit.Assert.*; +// +///** +// * TODO: NEED TO ADD THE TASK PART +// */ +//class CourseEnrolmentInteractorTest { +// +// @Test +// public void enrol() { +// // well technically interactor not done so ...... +// +// CourseEnrolmentDsGateway courseGateway = new InMemoryCourse(); +// CourseCreationDsGateway courseRepository = new InMemoryCourse(); +// UserRegGateway userRepository = new InMemoryUser(); +// +// CourseEnrolmentOutputBoundary outputBoundary = new CourseEnrolmentOutputBoundary() { +// @Override +// public CourseEnrolmentResponseModel prepareSuccessView(CourseEnrolmentResponseModel newStudent) { +// Assertions.assertEquals("course1inst1", newStudent.getCourseID()); +// Assertions.assertEquals("user1", newStudent.getStudentID()); +// Assertions.assertTrue(courseRepository.existsByCourseID("course1inst1")); +// Assertions.assertTrue(userRepository.existsByName("user1")); +// return null; +// } +// +// @Override +// public CourseEnrolmentResponseModel prepareFailView(String error) { +// fail("Use case failure is unexpected."); +// return null; +// } +// }; +// +// // make course +// ArrayList tasks = new ArrayList<>(); +// tasks.add("task1"); +// tasks.add("task2"); +// Course course = new Course("course1", "inst1", tasks); +// +// // make student +// StudentUser student = new StudentUser("user1", "pass1"); +// +// CourseEnrolmentInputBoundary interactor = new CourseEnrolmentInteractor(courseGateway, outputBoundary); +// +// CourseEnrolmentRequestModel inputData = new CourseEnrolmentRequestModel( +// "course1", "inst1", "user1"); +// +// interactor.enrol(inputData); +// } +//} \ No newline at end of file diff --git a/src/test/java/test_entities/CourseUnitTest.java b/src/test/java/test_entities/CourseUnitTest.java new file mode 100644 index 0000000..647fee8 --- /dev/null +++ b/src/test/java/test_entities/CourseUnitTest.java @@ -0,0 +1,65 @@ +package test_entities; + +import entities.Course; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Unit tests for the Course entity + * Assertion tests for whether all required fields are filled. + */ +class CourseUnitTest { + @Test + void course_allFieldsEmpty_thenIsFalse() { + ArrayList emptyArrayList = new ArrayList<>(); + Course course = new Course("", "", emptyArrayList); + + assertFalse(course.courseIsValid()); + } + + @Test + void course_StrFilled_thenIsFalse() { + ArrayList emptyArrayList = new ArrayList<>(); + Course course = new Course("course1", "", emptyArrayList); + + assertFalse(course.courseIsValid()); + } + @Test + void course_taskFilled_thenIsFalse() { + ArrayList task = new ArrayList<>(); + task.add("task1"); + Course course = new Course("", "", task); + + assertFalse(course.courseIsValid()); + } + + @Test + void course_taskAndStrFilled_thenIsFalse() { + ArrayList task = new ArrayList<>(); + task.add("task1"); + Course course = new Course("", "inst1", task); + + assertFalse(course.courseIsValid()); + } + + @Test + void course_taskEmpty_thenIsFalse() { + ArrayList noTask = new ArrayList<>(); + Course course = new Course("course1", "inst1", noTask); + + assertFalse(course.courseIsValid()); + } + + @Test + void course_allFieldsFilled_thenIsTrue() { + ArrayList task = new ArrayList<>(); + task.add("task1"); + Course course = new Course("course1", "inst1", task); + + assertTrue(course.courseIsValid()); + } +}