diff --git a/build.gradle b/build.gradle index 6a4f51c..8de8038 100644 --- a/build.gradle +++ b/build.gradle @@ -9,6 +9,7 @@ repositories { dependencies { implementation 'junit:junit:4.13.1' testImplementation('org.junit.jupiter:junit-jupiter:5.6.0') + testImplementation 'org.testng:testng:7.1.0' } test { diff --git a/src/main/java/course_creation_use_case/CourseCreationDsGateway.java b/src/main/java/course_creation_use_case/CourseCreationDsGateway.java new file mode 100644 index 0000000..7aa2e4e --- /dev/null +++ b/src/main/java/course_creation_use_case/CourseCreationDsGateway.java @@ -0,0 +1,15 @@ +package course_creation_use_case; + +// Use case layer + +/* +Notes: +- the methods the repo needs to implement for the interactor to do its job + */ + +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); +} diff --git a/src/main/java/course_creation_use_case/CourseCreationInputBoundary.java b/src/main/java/course_creation_use_case/CourseCreationInputBoundary.java new file mode 100644 index 0000000..95d4426 --- /dev/null +++ b/src/main/java/course_creation_use_case/CourseCreationInputBoundary.java @@ -0,0 +1,15 @@ +package course_creation_use_case; + +// Use case layer + + +/* +Notes: +- the public interface for calling the use case +- boundaries are interfaces +- input boundary is between the controller and use case + */ + +public interface CourseCreationInputBoundary { + CourseCreationResponseModel create(CourseCreationRequestModel requestModel); +} diff --git a/src/main/java/course_creation_use_case/CourseCreationInteractor.java b/src/main/java/course_creation_use_case/CourseCreationInteractor.java new file mode 100644 index 0000000..34f37fb --- /dev/null +++ b/src/main/java/course_creation_use_case/CourseCreationInteractor.java @@ -0,0 +1,53 @@ +package course_creation_use_case; + +// Use case layer + +import entities.*; + +public class CourseCreationInteractor implements CourseCreationInputBoundary { + final CourseCreationDsGateway courseCreationDSGateway; + final CourseCreationPresenter courseCreationPresenter; + final CourseMap courseMap; + + public CourseCreationInteractor(CourseCreationDsGateway courseCreationDSGateway, CourseCreationPresenter courseCreationPresenter, + CourseMap courseMap) { + this.courseCreationDSGateway = courseCreationDSGateway; + this.courseCreationPresenter = courseCreationPresenter; + this.courseMap = courseMap; + } + + /** + * Creates the task in the request model and returns the corresponding response model + * @param requestModel the input from the instructor + */ + @Override + public CourseCreationResponseModel create(CourseCreationRequestModel requestModel) { + + // 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."); + } + + // 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) + if (courseCreationDSGateway.existsByCourseID(requestModel.getCourseID())) { + return courseCreationPresenter.prepareFailView("Course already exists."); + } + + // 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 sent to presenter + CourseCreationResponseModel courseResponseModel = new CourseCreationResponseModel( + course.getCourseID(), course.getTasks()); + return courseCreationPresenter.prepareSuccessView(courseResponseModel); + } +} diff --git a/src/main/java/course_creation_use_case/CourseCreationPresenter.java b/src/main/java/course_creation_use_case/CourseCreationPresenter.java new file mode 100644 index 0000000..4f35bb8 --- /dev/null +++ b/src/main/java/course_creation_use_case/CourseCreationPresenter.java @@ -0,0 +1,18 @@ +package course_creation_use_case; + +// Use case layer + +public interface CourseCreationPresenter { + + /** + * Alerts user that course creation is successful (no existing course) + * @param newCourse the output from the program + */ + CourseCreationResponseModel prepareSuccessView(CourseCreationResponseModel newCourse); + + /** + * Alerts user that course creation attempted failed + * @param error the output from the program + */ + CourseCreationResponseModel prepareFailView(String error); +} diff --git a/src/main/java/course_creation_use_case/CourseCreationRequestModel.java b/src/main/java/course_creation_use_case/CourseCreationRequestModel.java new file mode 100644 index 0000000..80341f5 --- /dev/null +++ b/src/main/java/course_creation_use_case/CourseCreationRequestModel.java @@ -0,0 +1,63 @@ +package course_creation_use_case; + +// Use case layer + +/* + Notes: +- requests what is needed for its input data (what person in front of computer enters) +- do NOT depend on anything NOR have any references to Entity objects: violates SRP + */ + + +import java.util.ArrayList; + +public class CourseCreationRequestModel { + private String courseName; + private String courseInstructor; + private final String courseID; + 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 tasks the task(s) associated with the course + */ + public CourseCreationRequestModel(String courseName, String courseInstructor, ArrayList tasks) { + this.courseName = courseName; + this.courseInstructor = courseInstructor; + this.courseID = courseName + courseInstructor; + this.tasks = tasks; + } + + 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; + } +} diff --git a/src/main/java/course_creation_use_case/CourseCreationResponseModel.java b/src/main/java/course_creation_use_case/CourseCreationResponseModel.java new file mode 100644 index 0000000..68708ab --- /dev/null +++ b/src/main/java/course_creation_use_case/CourseCreationResponseModel.java @@ -0,0 +1,41 @@ +package course_creation_use_case; + +import java.util.ArrayList; + +// Use case layer + +/* +Notes: +- the output data produced; returns the response as the output +- does NOT depend on anything NOR should have any references to Entity objects: violates SRP + */ + +public class CourseCreationResponseModel { + String courseID; + ArrayList tasks; + + /** + * Creates a response model for course creation use case + * @param courseID the unique id of the course being created + * @param tasks the task(s) associated with the course being created + */ + public CourseCreationResponseModel(String courseID, ArrayList tasks) { + this.courseID = courseID; + this.tasks = 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/course_enrolment_use_case/CourseEnrolmentDsGateway.java b/src/main/java/course_enrolment_use_case/CourseEnrolmentDsGateway.java new file mode 100644 index 0000000..b728cbe --- /dev/null +++ b/src/main/java/course_enrolment_use_case/CourseEnrolmentDsGateway.java @@ -0,0 +1,11 @@ +package course_enrolment_use_case; + +// Use case layer + +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); + + void saveStudent(CourseEnrolmentRequestModel requestModel); +} diff --git a/src/main/java/course_enrolment_use_case/CourseEnrolmentInputBoundary.java b/src/main/java/course_enrolment_use_case/CourseEnrolmentInputBoundary.java new file mode 100644 index 0000000..f99d3c8 --- /dev/null +++ b/src/main/java/course_enrolment_use_case/CourseEnrolmentInputBoundary.java @@ -0,0 +1,7 @@ +package course_enrolment_use_case; + +// Use case layer + +public interface CourseEnrolmentInputBoundary { + CourseEnrolmentResponseModel create(CourseEnrolmentRequestModel requestModel); +} diff --git a/src/main/java/course_enrolment_use_case/CourseEnrolmentInteractor.java b/src/main/java/course_enrolment_use_case/CourseEnrolmentInteractor.java new file mode 100644 index 0000000..718a23a --- /dev/null +++ b/src/main/java/course_enrolment_use_case/CourseEnrolmentInteractor.java @@ -0,0 +1,65 @@ +package course_enrolment_use_case; + + +// Use case layer + +import entities.*; + +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) { + this.courseEnrolmentDsGateway = courseEnrolmentDsGateway; + this.courseEnrolmentPresenter = courseEnrolmentPresenter; + this.courseMap = courseMap; + this.studentID = studentID; + } + + /** + * Executes 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) { + + // 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." ); + } + + // 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."); + } + + // 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 :) + + // to do +// if (CourseMap.value(requestModel.getCourseID()).contains(courseEnrolmentDsGateway.existsByStudent(requestModel.getStudentID()))) { +// return courseEnrolmentPresenter.prepareFailView("Already enrolled in course."); +// } + + // checks passed; student id can be added to course's students parameter + + // 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....... + + // course edits updated + // to do: need a 'updateCourse' method? + + // sent to presenter + // to do: fix this + CourseEnrolmentResponseModel enrolmentResponseModel = + new CourseEnrolmentResponseModel(enrolledStudent.toLowerCase()); + return courseEnrolmentPresenter.prepareSuccessView(enrolmentResponseModel); + } +} diff --git a/src/main/java/course_enrolment_use_case/CourseEnrolmentPresenter.java b/src/main/java/course_enrolment_use_case/CourseEnrolmentPresenter.java new file mode 100644 index 0000000..dd06239 --- /dev/null +++ b/src/main/java/course_enrolment_use_case/CourseEnrolmentPresenter.java @@ -0,0 +1,19 @@ +package course_enrolment_use_case; + +// Use case layer + + +public interface CourseEnrolmentPresenter { + + /** + * Alerts student user that course enrolment is successful + * @param newStudent output from the program (the student user that is enrolled in the course) + */ + CourseEnrolmentResponseModel prepareSuccessView(CourseEnrolmentResponseModel newStudent); + + /** + * Alerts student user that course enrolment attempt failed + * @param error the output from the program + */ + CourseEnrolmentResponseModel prepareFailView(String error); +} diff --git a/src/main/java/course_enrolment_use_case/CourseEnrolmentRequestModel.java b/src/main/java/course_enrolment_use_case/CourseEnrolmentRequestModel.java new file mode 100644 index 0000000..1eeae6d --- /dev/null +++ b/src/main/java/course_enrolment_use_case/CourseEnrolmentRequestModel.java @@ -0,0 +1,45 @@ +package course_enrolment_use_case; + +// Use case layer + +public class CourseEnrolmentRequestModel { + private String courseName; + private String courseInstructor; + private final String courseID; + private final String studentID; + + public CourseEnrolmentRequestModel(String courseName, String courseInstructor, + String studentID) { + this.courseName = courseName; + this.courseInstructor = courseInstructor; + this.courseID = courseName + 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; + } + + public String getStudentID() { + return studentID; + } +} diff --git a/src/main/java/course_enrolment_use_case/CourseEnrolmentResponseModel.java b/src/main/java/course_enrolment_use_case/CourseEnrolmentResponseModel.java new file mode 100644 index 0000000..ac8dea6 --- /dev/null +++ b/src/main/java/course_enrolment_use_case/CourseEnrolmentResponseModel.java @@ -0,0 +1,27 @@ +package course_enrolment_use_case; + +import java.util.ArrayList; + +public class CourseEnrolmentResponseModel { + String studentID; +// ArrayList tasks; // not sure if this goes here + + + /** + * The info that is stored in the database + * The CourseMap will only be storing the IDs of enrolled StudentUsers + * @param studentID the ID corresponding to the StudentUser + */ + public CourseEnrolmentResponseModel(String studentID) { + this.studentID = studentID; +// this.tasks = tasks; + } + + public String getStudentID() { + return studentID; + } + +// public ArrayList getTasks() { +// return tasks; +// } +} diff --git a/src/main/java/Entities/Assignment.java b/src/main/java/entities/Assignment.java similarity index 99% rename from src/main/java/Entities/Assignment.java rename to src/main/java/entities/Assignment.java index 8a7b4d7..460621b 100644 --- a/src/main/java/Entities/Assignment.java +++ b/src/main/java/entities/Assignment.java @@ -1,4 +1,4 @@ -package Entities; +package entities; import java.time.LocalDateTime; public class Assignment extends Task implements Gradable { diff --git a/src/main/java/Entities/Course.java b/src/main/java/entities/Course.java similarity index 99% rename from src/main/java/Entities/Course.java rename to src/main/java/entities/Course.java index a68ec2b..a04034b 100644 --- a/src/main/java/Entities/Course.java +++ b/src/main/java/entities/Course.java @@ -1,4 +1,4 @@ -package Entities; +package entities; import java.util.ArrayList; diff --git a/src/main/java/entities/CourseMap.java b/src/main/java/entities/CourseMap.java new file mode 100644 index 0000000..eae4450 --- /dev/null +++ b/src/main/java/entities/CourseMap.java @@ -0,0 +1,43 @@ +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() { + + } +} diff --git a/src/main/java/Entities/Event.java b/src/main/java/entities/Event.java similarity index 99% rename from src/main/java/Entities/Event.java rename to src/main/java/entities/Event.java index c4d1d8e..408545b 100644 --- a/src/main/java/Entities/Event.java +++ b/src/main/java/entities/Event.java @@ -1,4 +1,4 @@ -package Entities; +package entities; import java.time.LocalDateTime; public class Event extends Task implements Timeblockable { diff --git a/src/main/java/Entities/Gradable.java b/src/main/java/entities/Gradable.java similarity index 94% rename from src/main/java/Entities/Gradable.java rename to src/main/java/entities/Gradable.java index 7c686e3..97cd78c 100644 --- a/src/main/java/Entities/Gradable.java +++ b/src/main/java/entities/Gradable.java @@ -1,4 +1,4 @@ -package Entities; +package entities; public interface Gradable { /** diff --git a/src/main/java/entities/InstructorUser.java b/src/main/java/entities/InstructorUser.java index 3096ae2..d386c15 100644 --- a/src/main/java/entities/InstructorUser.java +++ b/src/main/java/entities/InstructorUser.java @@ -1,7 +1,6 @@ package entities; import java.util.ArrayList; -import java.util.List; public class InstructorUser extends User { diff --git a/src/main/java/Entities/Task.java b/src/main/java/entities/Task.java similarity index 99% rename from src/main/java/Entities/Task.java rename to src/main/java/entities/Task.java index cd6606f..7d271e2 100644 --- a/src/main/java/Entities/Task.java +++ b/src/main/java/entities/Task.java @@ -1,4 +1,4 @@ -package Entities; +package entities; public abstract class Task { private String title; diff --git a/src/main/java/Entities/Test.java b/src/main/java/entities/Test.java similarity index 99% rename from src/main/java/Entities/Test.java rename to src/main/java/entities/Test.java index 05698fd..e8f8535 100644 --- a/src/main/java/Entities/Test.java +++ b/src/main/java/entities/Test.java @@ -1,4 +1,4 @@ -package Entities; +package entities; import java.time.LocalDateTime; diff --git a/src/main/java/Entities/Timeblockable.java b/src/main/java/entities/Timeblockable.java similarity index 97% rename from src/main/java/Entities/Timeblockable.java rename to src/main/java/entities/Timeblockable.java index 1e0d0e7..193664b 100644 --- a/src/main/java/Entities/Timeblockable.java +++ b/src/main/java/entities/Timeblockable.java @@ -1,4 +1,4 @@ -package Entities; +package entities; import java.time.LocalDateTime; public interface Timeblockable { /** diff --git a/src/main/java/entities/UserWhisperer.java b/src/main/java/entities/UserWhisperer.java deleted file mode 100644 index ef96570..0000000 --- a/src/main/java/entities/UserWhisperer.java +++ /dev/null @@ -1,22 +0,0 @@ -package entities; - -// Entity - -public class UserWhisperer { - - /** Entity Layer - * What this class does */ - - public StudentUser createStudent(String name, String password) { - return new StudentUser(name, password); - } - - public InstructorUser createInstructor(String name, String password) { - return null; - } - - - public String SearchUser(String name) { - return null; - } -} diff --git a/src/main/java/entities/internalUserList.java b/src/main/java/entities/internalUserList.java deleted file mode 100644 index 962010d..0000000 --- a/src/main/java/entities/internalUserList.java +++ /dev/null @@ -1,17 +0,0 @@ -package entities; - -import java.util.ArrayList; - -public class internalUserList { - - /** Entity Layer - * An internal list of all Users of this program */ - - private ArrayList UserList; - - public String getUser(String userid) { - return null; - } - - public void addUser() {} -} diff --git a/src/main/java/screens/CourseCreationController.java b/src/main/java/screens/CourseCreationController.java new file mode 100644 index 0000000..7c5efd8 --- /dev/null +++ b/src/main/java/screens/CourseCreationController.java @@ -0,0 +1,23 @@ +package screens; + +import course_creation_use_case.CourseCreationInputBoundary; +import course_creation_use_case.CourseCreationRequestModel; +import course_creation_use_case.CourseCreationResponseModel; + +import java.util.ArrayList; + +public class CourseCreationController { + final CourseCreationInputBoundary courseInput; + public CourseCreationController(CourseCreationInputBoundary courseGateway) { + this.courseInput = courseGateway; + } + + CourseCreationResponseModel create(String courseName, String courseInstructor, + ArrayList tasks) { + CourseCreationRequestModel requestModel = new CourseCreationRequestModel( + courseName, courseInstructor, tasks); + + return courseInput.create(requestModel); + } + +} \ No newline at end of file diff --git a/src/main/java/screens/CourseCreationFailed.java b/src/main/java/screens/CourseCreationFailed.java new file mode 100644 index 0000000..319602a --- /dev/null +++ b/src/main/java/screens/CourseCreationFailed.java @@ -0,0 +1,7 @@ +package screens; + +public class CourseCreationFailed extends RuntimeException { + public CourseCreationFailed(String error) { + super(error); + } +} diff --git a/src/main/java/screens/CourseCreationResponseFormatter.java b/src/main/java/screens/CourseCreationResponseFormatter.java new file mode 100644 index 0000000..55b7e1f --- /dev/null +++ b/src/main/java/screens/CourseCreationResponseFormatter.java @@ -0,0 +1,31 @@ +package screens; + +// Interface adapters layer + +import course_creation_use_case.CourseCreationPresenter; +import course_creation_use_case.CourseCreationResponseModel; + +import javax.swing.*; + +public class CourseCreationResponseFormatter implements CourseCreationPresenter { + + /** + * Alert user to course creation success + * @param response the output from the program + */ + @Override + public CourseCreationResponseModel prepareSuccessView(CourseCreationResponseModel response) { + + JOptionPane.showMessageDialog(null, "New course created!"); + return response; + } + + /** + * Alert user to course creation failure + * @param error the output from the program + */ + @Override + public CourseCreationResponseModel prepareFailView(String error) { + throw new CourseCreationFailed(error); + } +} diff --git a/src/main/java/screens/CourseCreationScreen.java b/src/main/java/screens/CourseCreationScreen.java new file mode 100644 index 0000000..14f6c7b --- /dev/null +++ b/src/main/java/screens/CourseCreationScreen.java @@ -0,0 +1,94 @@ +package screens; + +// Framework / Drivers layer + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; + +public class CourseCreationScreen extends JPanel implements ActionListener { + /** the course name chosen by InstructorUser */ + JTextField courseName = new JTextField(15); + + /** the course instructor */ + JTextField courseInstructor = new JTextField(15); + + /** title of task */ + JTextField taskName = new JTextField(15); + + /** the controller */ + CourseCreationController courseCreationController; + + /** + * A window with a title, texts to fill in, and JButtons + */ + public CourseCreationScreen(CourseCreationController controller) { + this.courseCreationController = controller; + + // label for the title of the screen + JLabel title = new JLabel("Course Creation Screen"); + title.setAlignmentX(Component.CENTER_ALIGNMENT); + + // text fields for instructor to enter in required course info + LabelTextPanel courseNameInfo = new LabelTextPanel( + new JLabel("Enter course name"), courseName); + 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 + + // buttons + JButton cancel = new JButton("Cancel"); + JButton save = new JButton("Save"); + + JPanel buttons = new JPanel(); + buttons.add(cancel); + buttons.add(save); + + cancel.addActionListener(this); + save.addActionListener(this); + + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + // create the new panel + this.add(title); + this.add(courseNameInfo); + this.add(courseInstructorInfo); + this.add(taskNameInfo); + this.add(buttons); + } + + /** + * React to a button click which triggers the corresponding use case + */ + @Override + public void actionPerformed(ActionEvent evt) { + // instructor decides to cancel the course creation process + if (evt.getActionCommand().equals("Cancel")) { + try { + // to do + JOptionPane.showMessageDialog(this, "screen should close"); + } catch (Exception e) { + JOptionPane.showMessageDialog(this, e.getMessage()); + } + } else if (evt.getActionCommand().equals("Save")) { + try { + // initialize new Arraylist and add task + ArrayList tasks = new ArrayList(); + tasks.add(taskName.getText()); + courseCreationController.create(courseName.getText(), courseInstructor.getText(), + tasks); + JOptionPane.showMessageDialog(this, "Course successful created."); + } catch (Exception e) { + JOptionPane.showMessageDialog(this, e.getMessage()); + } + } + } +} diff --git a/src/main/java/screens/CourseEnrolmentController.java b/src/main/java/screens/CourseEnrolmentController.java new file mode 100644 index 0000000..a1583cb --- /dev/null +++ b/src/main/java/screens/CourseEnrolmentController.java @@ -0,0 +1,20 @@ +package screens; + +import course_enrolment_use_case.CourseEnrolmentInputBoundary; +import course_enrolment_use_case.CourseEnrolmentRequestModel; +import course_enrolment_use_case.CourseEnrolmentResponseModel; + +public class CourseEnrolmentController { + final CourseEnrolmentInputBoundary enrolmentInput; + public CourseEnrolmentController(CourseEnrolmentInputBoundary enrolmentGateway) { + this.enrolmentInput = enrolmentGateway; + } + + CourseEnrolmentResponseModel create(String courseID, String instructorID, String studentID) { + CourseEnrolmentRequestModel requestModel = new CourseEnrolmentRequestModel( + courseID, instructorID, studentID); + + return enrolmentInput.create(requestModel); + } + +} diff --git a/src/main/java/screens/CourseEnrolmentFailed.java b/src/main/java/screens/CourseEnrolmentFailed.java new file mode 100644 index 0000000..c42ca10 --- /dev/null +++ b/src/main/java/screens/CourseEnrolmentFailed.java @@ -0,0 +1,7 @@ +package screens; + +public class CourseEnrolmentFailed extends RuntimeException { + public CourseEnrolmentFailed(String error) { + super(error); + } +} diff --git a/src/main/java/screens/CourseEnrolmentResponseFormatter.java b/src/main/java/screens/CourseEnrolmentResponseFormatter.java new file mode 100644 index 0000000..a7fa05d --- /dev/null +++ b/src/main/java/screens/CourseEnrolmentResponseFormatter.java @@ -0,0 +1,30 @@ +package screens; + +// Interfaces adapters layer + +import course_enrolment_use_case.CourseEnrolmentPresenter; +import course_enrolment_use_case.CourseEnrolmentResponseModel; + +import javax.swing.*; + +public class CourseEnrolmentResponseFormatter implements CourseEnrolmentPresenter { + + /** + * Alert student user about course enrolment success + * @param response output from the program (the student user that is enrolled in the course) + */ + @Override + public CourseEnrolmentResponseModel prepareSuccessView(CourseEnrolmentResponseModel response) { + JOptionPane.showMessageDialog(null, "Successfully enrolled!"); + return response; + } + + /** + * Alert student user about course enrolment failure + * @param error the output from the program + */ + @Override + public CourseEnrolmentResponseModel prepareFailView(String error) { + throw new CourseEnrolmentFailed(error); + } +} diff --git a/src/main/java/screens/CourseEnrolmentScreen.java b/src/main/java/screens/CourseEnrolmentScreen.java new file mode 100644 index 0000000..5c3dc59 --- /dev/null +++ b/src/main/java/screens/CourseEnrolmentScreen.java @@ -0,0 +1,84 @@ +package screens; + +// Framework/Drivers layer + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class CourseEnrolmentScreen extends JPanel implements ActionListener { + /** student enters course name */ + JTextField courseName = new JTextField(15); + + /** student enters course instructor */ + JTextField courseInstructor = new JTextField(15); + + /** student enters their username (aka student id) */ + JTextField studentID = new JTextField(15); + + /** the controller */ + CourseEnrolmentController courseEnrolmentController; + + /** + * Window with title, texts to fill in, and JButtons + */ + public CourseEnrolmentScreen(CourseEnrolmentController controller) { + this.courseEnrolmentController = controller; + + // label for the title of the screen + JLabel title = new JLabel("Course Enrolment Screen"); + title.setAlignmentX(Component.CENTER_ALIGNMENT); + + // text fields for student user to enter in required info + LabelTextPanel courseNameInfo = new LabelTextPanel( + new JLabel("Enter course name"), courseName); + LabelTextPanel courseInstructorInfo = new LabelTextPanel( + new JLabel("Enter instructor name"), courseInstructor); + LabelTextPanel studentIDInfo = new LabelTextPanel( + new JLabel("Enter instructor name"), studentID); + + // buttons + JButton cancel = new JButton("Cancel"); + JButton search = new JButton("Search"); + + JPanel buttons = new JPanel(); + buttons.add(cancel); + buttons.add(search); + + cancel.addActionListener(this); + search.addActionListener(this); + + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + // create the new panel + this.add(title); + this.add(courseNameInfo); + this.add(courseInstructorInfo); + this.add(studentIDInfo); + this.add(buttons); + } + + /** + * React to a button click which triggers the corresponding use case + */ + @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()); + } + } else if (evt.getActionCommand().equals("Search")) { + try { + // to do: add studentID to course's task parameter + JOptionPane.showMessageDialog(this, "Successfully enrolled in course."); + } catch (Exception e) { + JOptionPane.showMessageDialog(this, e.getMessage()); + } + } + } +} diff --git a/src/main/java/screens/CourseFoundScreen.java b/src/main/java/screens/CourseFoundScreen.java new file mode 100644 index 0000000..369c132 --- /dev/null +++ b/src/main/java/screens/CourseFoundScreen.java @@ -0,0 +1,42 @@ +package screens; + +// 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/FileCourse.java b/src/main/java/screens/FileCourse.java new file mode 100644 index 0000000..858b0ac --- /dev/null +++ b/src/main/java/screens/FileCourse.java @@ -0,0 +1,165 @@ +package screens; + +import course_creation_use_case.CourseCreationDsGateway; +//import course_creation_use_case.courseCreationDsRequestModel; +import 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/InMemoryCourse.java b/src/main/java/screens/InMemoryCourse.java new file mode 100644 index 0000000..70f14b2 --- /dev/null +++ b/src/main/java/screens/InMemoryCourse.java @@ -0,0 +1,29 @@ +package screens; + +import course_creation_use_case.CourseCreationDsGateway; +import 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/LabelTextPanel.java b/src/main/java/screens/LabelTextPanel.java new file mode 100644 index 0000000..ec714a4 --- /dev/null +++ b/src/main/java/screens/LabelTextPanel.java @@ -0,0 +1,10 @@ +package screens; + +import javax.swing.*; + +public class LabelTextPanel extends JPanel { + public LabelTextPanel(JLabel label, JTextField textField) { + this.add(label); + this.add(textField); + } +} diff --git a/src/main/java/tasks_to_student_tasklist_use_case/TaskToTasklistInteractor.java b/src/main/java/tasks_to_student_tasklist_use_case/TaskToTasklistInteractor.java new file mode 100644 index 0000000..de154a0 --- /dev/null +++ b/src/main/java/tasks_to_student_tasklist_use_case/TaskToTasklistInteractor.java @@ -0,0 +1,6 @@ +package tasks_to_student_tasklist_use_case; + +public class TaskToTasklistInteractor { + // request model is the student's id and the course id + // i can do this in the course enrolment use case ..... +} diff --git a/src/main/java/tasks_to_student_tasklist_use_case/TaskToTasklistPresenter.java b/src/main/java/tasks_to_student_tasklist_use_case/TaskToTasklistPresenter.java new file mode 100644 index 0000000..66f3c46 --- /dev/null +++ b/src/main/java/tasks_to_student_tasklist_use_case/TaskToTasklistPresenter.java @@ -0,0 +1,4 @@ +package tasks_to_student_tasklist_use_case; + +public interface TaskToTasklistPresenter { +} diff --git a/test/CourseUnitTest.java b/test/CourseUnitTest.java new file mode 100644 index 0000000..357cdf1 --- /dev/null +++ b/test/CourseUnitTest.java @@ -0,0 +1,14 @@ +//import org.junit.jupiter.api.Test; +// +//import static org.junit.jupiter.api.Assertions.assertFalse; +// +//import entities.Course; +//public class CourseUnitTest { +// +// @Test +// void givenCourse_whenCourseExists_thenIsFalse() { +// Course course = new Course("csc207", "abc", "tasks idk"); +// +// assertFalse(course.courseExists); +// } +//} diff --git a/test/course_creation_use_case/CourseCreationInteractorTest.java b/test/course_creation_use_case/CourseCreationInteractorTest.java new file mode 100644 index 0000000..24e2d21 --- /dev/null +++ b/test/course_creation_use_case/CourseCreationInteractorTest.java @@ -0,0 +1,4 @@ +package course_creation_use_case; + +public class CourseCreationInteractorTest { +}