From 7dff57ac98c1ec8b6f481c08b0afd6c0b9fa4595 Mon Sep 17 00:00:00 2001
From: Andrew Lalis
Date: Wed, 17 Apr 2019 22:16:05 +0200
Subject: [PATCH 01/12] Got CSV reading to work properly.
---
pom.xml | 6 +
...TeachingAssistantAssistantApplication.java | 7 +-
.../controllers/Courses.java | 1 -
.../controllers/courses/ImportStudents.java | 61 ++++++++
.../model/Course.java | 8 +-
.../model/people/Person.java | 41 +++++-
.../model/people/Student.java | 44 +++++-
.../model/people/TeachingAssistant.java | 4 +-
.../util/sample_data/CourseGenerator.java | 4 +-
.../util/sample_data/StudentGenerator.java | 2 +-
.../TeachingAssistantGenerator.java | 2 +-
.../team_importing/StudentRecordEntry.java | 44 ++++++
.../team_importing/StudentTeamImporter.java | 136 ++++++++++++++++++
.../resources/templates/courses/entity.html | 2 +-
.../templates/courses/import_students.html | 26 ++++
.../courses/import_teaching_assistants.html | 10 ++
16 files changed, 381 insertions(+), 17 deletions(-)
create mode 100644 src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/ImportStudents.java
create mode 100644 src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/team_importing/StudentRecordEntry.java
create mode 100644 src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/team_importing/StudentTeamImporter.java
create mode 100644 src/main/resources/templates/courses/import_students.html
create mode 100644 src/main/resources/templates/courses/import_teaching_assistants.html
diff --git a/pom.xml b/pom.xml
index 086d14c..640ee77 100644
--- a/pom.xml
+++ b/pom.xml
@@ -79,6 +79,12 @@
mysql-connector-java
8.0.15
+
+
+ org.apache.commons
+ commons-csv
+ 1.5
+
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/TeachingAssistantAssistantApplication.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/TeachingAssistantAssistantApplication.java
index 984e6f9..22d7739 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/TeachingAssistantAssistantApplication.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/TeachingAssistantAssistantApplication.java
@@ -27,6 +27,11 @@ public class TeachingAssistantAssistantApplication implements CommandLineRunner
@Override
public void run(String... args) throws Exception {
System.out.println("Running startup...");
-
+//
+// String exampleDate = "2019/04/15 4:13:41 PM GMT+2 ";
+// // Parse the timestamp.
+// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd h:mm:ss a O ");
+// ZonedDateTime dateTime = ZonedDateTime.parse(exampleDate, formatter);
+// System.out.println("Read time: " + dateTime.toString());
}
}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/Courses.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/Courses.java
index 6935735..ea5df0e 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/Courses.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/Courses.java
@@ -41,7 +41,6 @@ public class Courses {
consumes = "application/x-www-form-urlencoded"
)
public String post(@ModelAttribute Course course) {
- System.out.println("Object submitted: " + course);
this.courseRepository.save(course);
return "courses/entity";
}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/ImportStudents.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/ImportStudents.java
new file mode 100644
index 0000000..02819db
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/ImportStudents.java
@@ -0,0 +1,61 @@
+package nl.andrewlalis.teaching_assistant_assistant.controllers.courses;
+
+import nl.andrewlalis.teaching_assistant_assistant.model.Course;
+import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
+import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
+import nl.andrewlalis.teaching_assistant_assistant.model.repositories.TeamRepository;
+import nl.andrewlalis.teaching_assistant_assistant.util.team_importing.StudentTeamImporter;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Controller for importing students from a CSV sheet.
+ */
+@Controller
+public class ImportStudents {
+
+ private CourseRepository courseRepository;
+
+ private TeamRepository teamRepository;
+
+ protected ImportStudents(CourseRepository courseRepository, TeamRepository teamRepository) {
+ this.courseRepository = courseRepository;
+ this.teamRepository = teamRepository;
+ }
+
+ @GetMapping("/courses/{code}/import_students")
+ public String get(@PathVariable String code, Model model) {
+ Optional optionalCourse = this.courseRepository.findByCode(code);
+ optionalCourse.ifPresent(course -> model.addAttribute("course", course));
+ return "courses/import_students";
+ }
+
+ @PostMapping(
+ value = "/courses/{code}/import_students"
+ )
+ public String post(@PathVariable String code, @RequestParam MultipartFile file) {
+ Optional optionalCourse = this.courseRepository.findByCode(code);
+
+ if (!optionalCourse.isPresent()) {
+ System.out.println("No course found.");
+ return "redirect:/courses";
+ }
+
+ try {
+ List studentTeams = StudentTeamImporter.importFromCSV(file.getInputStream(), optionalCourse.get());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return "redirect:/courses/{code}";
+ }
+}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/Course.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/Course.java
index 25d41db..483b294 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/Course.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/Course.java
@@ -77,12 +77,12 @@ public class Course extends BasicEntity {
this.code = code;
}
- public void addStudentGroup(StudentTeam group) {
- this.studentTeams.add(group);
+ public void addStudentTeam(StudentTeam team) {
+ this.studentTeams.add(team);
}
- public void addTeachingAssistantGroup(TeachingAssistantTeam group) {
- this.teachingAssistantTeams.add(group);
+ public void addTeachingAssistantTeam(TeachingAssistantTeam team) {
+ this.teachingAssistantTeams.add(team);
}
/*
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/Person.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/Person.java
index 47cef1d..1029403 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/Person.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/Person.java
@@ -26,6 +26,9 @@ public abstract class Person extends BasicEntity {
@Column
private String emailAddress;
+ @Column
+ private String githubUsername;
+
/**
* The list of teams that this person belongs to. Because a person can belong to more than one team, it is implied
* that each person exists in only one location in the database. Therefore, if one person is enrolled in two courses
@@ -50,12 +53,14 @@ public abstract class Person extends BasicEntity {
* @param firstName The person's first name.
* @param lastName The person's last name.
* @param emailAddress The person's email address.
+ * @param githubUsername The person's github username;
*/
- public Person(String firstName, String lastName, String emailAddress) {
+ public Person(String firstName, String lastName, String emailAddress, String githubUsername) {
this();
this.firstName = firstName;
this.lastName = lastName;
this.emailAddress = emailAddress;
+ this.githubUsername = githubUsername;
}
public void assignToTeam(Team team) {
@@ -82,8 +87,40 @@ public abstract class Person extends BasicEntity {
return this.emailAddress;
}
+ public String getGithubUsername() {
+ return this.githubUsername;
+ }
+
+ /**
+ * Determines if two Persons are equal. They are considered equal when all of the basic identifying information
+ * about the person is the same, regardless of case.
+ * @param o The other object.
+ * @return True if the other object is the same person, or false if not.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (o == null) {
+ return false;
+ }
+
+ if (o instanceof Person) {
+ Person p = (Person) o;
+ return (
+ this.getFirstName().equalsIgnoreCase(p.getFirstName())
+ && this.getLastName().equalsIgnoreCase(p.getLastName())
+ && this.getEmailAddress().equalsIgnoreCase(p.getEmailAddress())
+ && this.getGithubUsername().equalsIgnoreCase(p.getGithubUsername())
+ );
+ }
+
+ return false;
+ }
+
@Override
public String toString() {
- return this.getFirstName() + ' ' + this.getLastName() + '[' + this.getId() + ']';
+ return "First Name: " + this.getFirstName()
+ + ", Last Name: " + this.getLastName()
+ + ", Email: " + this.getEmailAddress()
+ + ", Github Username: " + this.getGithubUsername();
}
}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/Student.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/Student.java
index e61216f..26963bf 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/Student.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/Student.java
@@ -1,5 +1,6 @@
package nl.andrewlalis.teaching_assistant_assistant.model.people;
+import javax.persistence.Column;
import javax.persistence.Entity;
/**
@@ -8,13 +9,52 @@ import javax.persistence.Entity;
@Entity
public class Student extends Person {
+ /**
+ * The student's unique student number, as given by the university.
+ */
+ @Column(unique = true, nullable = false)
+ private int studentNumber;
+
/**
* Default constructor for JPA.
*/
protected Student() {}
- public Student(String firstName, String lastName, String emailAddress) {
- super(firstName, lastName, emailAddress);
+ /**
+ * Constructs a new student with all the properties of a Person, and any extra properties.
+ * @param firstName The student's first name.
+ * @param lastName The student's last name.
+ * @param emailAddress The student's email address.
+ * @param githubUsername The student's Github username.
+ * @param studentNumber The student's unique student number.
+ */
+ public Student(String firstName, String lastName, String emailAddress, String githubUsername, int studentNumber) {
+ super(firstName, lastName, emailAddress, githubUsername);
+
+ this.studentNumber = studentNumber;
}
+ public int getStudentNumber() {
+ return studentNumber;
+ }
+
+ public void setStudentNumber(int studentNumber) {
+ this.studentNumber = studentNumber;
+ }
+
+ /**
+ * Determines if two students are equal. They are considered equal if their person attributes are the same, or
+ * their student-specific attributes are equal.
+ * @param o The other object.
+ * @return True if the other object is the same student.
+ */
+ @Override
+ public boolean equals(Object o) {
+ return super.equals(o) || this.getStudentNumber() == ((Student) o).getStudentNumber();
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + ", Student Number: " + this.getStudentNumber();
+ }
}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/TeachingAssistant.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/TeachingAssistant.java
index 19dfcf8..dee492b 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/TeachingAssistant.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/TeachingAssistant.java
@@ -15,7 +15,7 @@ public class TeachingAssistant extends Person {
}
- public TeachingAssistant(String firstName, String lastName, String emailAddress) {
- super(firstName, lastName, emailAddress);
+ public TeachingAssistant(String firstName, String lastName, String githubUsername, String emailAddress) {
+ super(firstName, lastName, emailAddress, githubUsername);
}
}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/sample_data/CourseGenerator.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/sample_data/CourseGenerator.java
index eecf759..0273c0d 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/sample_data/CourseGenerator.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/sample_data/CourseGenerator.java
@@ -56,11 +56,11 @@ public class CourseGenerator extends TestDataGenerator {
List studentTeams = this.generateStudentTeams();
List teachingAssistantTeams = this.generateTeachingAssistantTeams();
for (StudentTeam team : studentTeams) {
- course.addStudentGroup(team);
+ course.addStudentTeam(team);
team.setCourse(course);
}
for (TeachingAssistantTeam team : teachingAssistantTeams) {
- course.addTeachingAssistantGroup(team);
+ course.addTeachingAssistantTeam(team);
team.setCourse(course);
}
return course;
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/sample_data/StudentGenerator.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/sample_data/StudentGenerator.java
index 23240c4..01945b5 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/sample_data/StudentGenerator.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/sample_data/StudentGenerator.java
@@ -12,6 +12,6 @@ public class StudentGenerator extends PersonGenerator {
public Student generate() {
String firstName = this.getRandomFirstName();
String lastName = this.getRandomLastName();
- return new Student(firstName, lastName, this.getRandomEmailAddress(firstName, lastName));
+ return new Student(firstName, lastName, this.getRandomEmailAddress(firstName, lastName), null, this.getRandomInteger(0, 100000000));
}
}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/sample_data/TeachingAssistantGenerator.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/sample_data/TeachingAssistantGenerator.java
index e4c9a89..8b2c8d4 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/sample_data/TeachingAssistantGenerator.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/sample_data/TeachingAssistantGenerator.java
@@ -12,6 +12,6 @@ public class TeachingAssistantGenerator extends PersonGenerator importFromCSV(InputStream fileInputStream, Course course) throws IOException {
+ Iterable records = CSVFormat.DEFAULT
+ .withSkipHeaderRecord()
+ .withHeader("timestamp", "email", "name", "number", "github_username", "has_partner", "partner_name", "partner_number", "partner_email", "partner_github_username")
+ .parse(new InputStreamReader(fileInputStream));
+
+ List studentEntries = extractStudentsFromRecords(records);
+
+ for (StudentRecordEntry entry : studentEntries) {
+ System.out.println(entry.toString());
+ }
+
+ return new ArrayList<>();
+
+ }
+
+ /**
+ * Extracts all student data from a list of records, and automatically discards outdated responses (those where the
+ * same student submitted more than once).
+ * @param records The list of records in the CSV file.
+ * @return A mapping for each timestamp to
+ */
+ private static List extractStudentsFromRecords(Iterable records) {
+ List studentEntries = new ArrayList<>();
+
+ for (CSVRecord record : records) {
+ // Parse the actual student.
+ Student s = parseStudentRecordData(record.get("name"), record.get("email"), record.get("github_username"), record.get("number"));
+
+ // Parse the student's preferred partner, if they exist.
+ Student preferredPartner = null;
+ if (record.get("has_partner").equalsIgnoreCase("yes")) {
+ preferredPartner = parseStudentRecordData(record.get("partner_name"), record.get("partner_email"), record.get("partner_github_username"), record.get("partner_number"));
+ }
+
+ // Parse the timestamp.
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd h:mm:ss a O ");
+ ZonedDateTime dateTime = ZonedDateTime.parse(record.get("timestamp") + ' ', formatter);
+ // A space is added because of a java bug: https://stackoverflow.com/questions/37287103/why-does-gmt8-fail-to-parse-with-pattern-o-despite-being-copied-straight-ou
+
+ studentEntries.add(new StudentRecordEntry(dateTime, s, preferredPartner));
+ }
+
+ studentEntries = removeDuplicateEntries(studentEntries);
+
+ return studentEntries;
+ }
+
+
+ private static List removeDuplicateEntries(List studentEntries) {
+ List uniqueStudentEntries = new ArrayList<>();
+
+ for (StudentRecordEntry entry : studentEntries) {
+ // Check for if the current entry's student already exists.
+ boolean duplicateFound = false;
+ for (StudentRecordEntry existingEntry : uniqueStudentEntries) {
+ if (entry.getStudent().equals(existingEntry.getStudent())) {
+ duplicateFound = true;
+ // Check if the existing entry is older than the new one; it should be overwritten.
+ if (existingEntry.getDateTime().isBefore(entry.getDateTime())) {
+ uniqueStudentEntries.remove(existingEntry);
+ uniqueStudentEntries.add(entry);
+ break;
+ }
+ }
+ }
+
+ if (!duplicateFound) {
+ uniqueStudentEntries.add(entry);
+ }
+ }
+
+ return uniqueStudentEntries;
+ }
+
+ /**
+ * Creates a student object from given entries in a record obtained from a CSV file.
+ * @param name The name value.
+ * @param email The email value.
+ * @param githubUsername The github_username value.
+ * @param studentNumber The number value.
+ * @return A student object constructed from the given data.
+ */
+ private static Student parseStudentRecordData(String name, String email, String githubUsername, String studentNumber) {
+ // Extract a sensible first and last name.
+ String[] nameSegments = name.split(" ");
+ String firstName = "No First Name Given";
+ String lastName = "No Last Name Given";
+
+ if (nameSegments.length > 0) {
+ firstName = nameSegments[0];
+ }
+
+ if (nameSegments.length > 1) {
+ lastName = String.join(" ", Arrays.copyOfRange(nameSegments, 1, nameSegments.length));
+ }
+
+ // Extract a sensible github username.
+ String githubURL = "https://github.com/";
+
+ if (githubUsername.startsWith(githubURL)) {
+ githubUsername = githubUsername.substring(githubURL.length());
+ }
+
+ // Create the student.
+ return new Student(firstName, lastName, email, githubUsername, Integer.parseInt(studentNumber));
+ }
+
+}
diff --git a/src/main/resources/templates/courses/entity.html b/src/main/resources/templates/courses/entity.html
index 7355aa8..511b5b4 100644
--- a/src/main/resources/templates/courses/entity.html
+++ b/src/main/resources/templates/courses/entity.html
@@ -48,7 +48,7 @@
Import students from CSV
diff --git a/src/main/resources/templates/courses/import_students.html b/src/main/resources/templates/courses/import_students.html
new file mode 100644
index 0000000..f825b6b
--- /dev/null
+++ b/src/main/resources/templates/courses/import_students.html
@@ -0,0 +1,26 @@
+
+
+
+ Import Students via CSV
+
+
+
+
+
+ Please select a CSV file to import.
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/courses/import_teaching_assistants.html b/src/main/resources/templates/courses/import_teaching_assistants.html
new file mode 100644
index 0000000..d538fea
--- /dev/null
+++ b/src/main/resources/templates/courses/import_teaching_assistants.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
From df92a2c2d50fb20da732ed20ad3bf9365774e099 Mon Sep 17 00:00:00 2001
From: Andrew Lalis
Date: Wed, 17 Apr 2019 23:42:37 +0200
Subject: [PATCH 02/12] Added correct algorithm! Yay!
---
.../model/people/teams/Team.java | 2 +-
.../team_importing/StudentTeamImporter.java | 103 +++++++++++++++++-
2 files changed, 101 insertions(+), 4 deletions(-)
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/Team.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/Team.java
index 255883f..82a43f7 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/Team.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/Team.java
@@ -91,7 +91,7 @@ public abstract class Team extends BasicEntity {
public String toString() {
StringBuilder sb = new StringBuilder();
for (P p : this.getMembers()) {
- sb.append(p.toString()).append(", ");
+ sb.append(p.getFullName()).append(", ");
}
return sb.toString();
}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/team_importing/StudentTeamImporter.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/team_importing/StudentTeamImporter.java
index 0723148..774991d 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/team_importing/StudentTeamImporter.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/team_importing/StudentTeamImporter.java
@@ -11,7 +11,10 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
/**
* Provides some methods to streamline the process of transforming a CSV file of student data into a list of valid teams
@@ -33,19 +36,27 @@ public class StudentTeamImporter {
List studentEntries = extractStudentsFromRecords(records);
+ System.out.println("<<< Entries (" + studentEntries.size() + ") >>>");
for (StudentRecordEntry entry : studentEntries) {
System.out.println(entry.toString());
}
- return new ArrayList<>();
+ List studentTeams = generateTeamsFromStudentEntries(studentEntries, 0);
+ System.out.println("<<< Teams (" + studentTeams.size() + ") >>>");
+ for (StudentTeam team : studentTeams) {
+ System.out.println("Team: " + team);
+ }
+
+ return studentTeams;
}
/**
* Extracts all student data from a list of records, and automatically discards outdated responses (those where the
* same student submitted more than once).
* @param records The list of records in the CSV file.
- * @return A mapping for each timestamp to
+ * @return A list of all student entries. A student entry is an intermediate object used to organize the parsed data
+ * from each record in the CSV file.
*/
private static List extractStudentsFromRecords(Iterable records) {
List studentEntries = new ArrayList<>();
@@ -73,7 +84,93 @@ public class StudentTeamImporter {
return studentEntries;
}
+ /**
+ * Generates a list of teams from a list of unique student entries. The algorithm is described as follows:
+ *
+ * 1. Select the next student from the list of entries.
+ * 2. If the student (A) has specified a partner (B), search for that partner (B) in the list of entries.
+ * 3. If the partner (B) also specified the student (A) as their preferred partner, a team is created from the two.
+ * a. Pop both student entries from the list of entries.
+ * 4. Else, place student (A) in a queue of single students.
+ * a. Pop student (A) from the list of entries.
+ * 5. If the list of entries is not empty, go to 1.
+ * 6. The list of entries is now empty, and zero or more entries exist in a queue of single students.
+ * 7. Pop two (or as many as possible) students randomly from the queue, and form a team from them.
+ * 8. Repeat until the queue of single students is empty.
+ * 9. There is now a list of student teams and no student should remain unprocessed.
+ *
+ * @param entries A list of record entries.
+ * @param seed A seed to use for randomization of single student teams.
+ * @return A list of student teams.
+ */
+ private static List generateTeamsFromStudentEntries(List entries, long seed) {
+ List teams = new ArrayList<>();
+ List singleStudentsEntryQueue = new ArrayList<>();
+ Random random = new Random(seed);
+ // Realize step 5. Loop until there are no more processed entries.
+ while (!entries.isEmpty()) {
+ // Step 1. Select the next student from the list of entries.
+ StudentRecordEntry entry = entries.remove(0);
+
+ // Step 2. If the student has a partner, search for that partner.
+ if (entry.hasPartner()) {
+ boolean partnerFound = false; // Use this to keep track of if a partner is actually found.
+ for (int i = 0; i < entries.size(); i++) {
+ StudentRecordEntry secondEntry = entries.get(i);
+ // Step 3. If the partner specifies their partner as the student (both want each other), then create a team.
+ if (
+ entry.getPartnerStudent().equals(secondEntry.getStudent())
+ && secondEntry.hasPartner()
+ && secondEntry.getPartnerStudent().equals(entry.getStudent())
+ ) {
+ partnerFound = true;
+
+ entries.remove(i); // Step 3a. The first student has been popped, so pop this one.
+
+ StudentTeam team = new StudentTeam();
+ team.addMember(entry.getStudent());
+ team.addMember(secondEntry.getStudent());
+ teams.add(team);
+
+ break;
+ }
+ }
+
+ // Step 4. If no partner was found, then add this entry to the queue of single students.
+ if (!partnerFound) {
+ singleStudentsEntryQueue.add(entry);
+ }
+ } else {
+ // Also Step 4. The student chose to have no partner, so add this entry to the queue of single students.
+ singleStudentsEntryQueue.add(entry);
+ }
+ }
+
+ // We are now at step 6.
+ while (!singleStudentsEntryQueue.isEmpty()) {
+ StudentTeam team = new StudentTeam();
+ StudentRecordEntry firstRandomEntry = singleStudentsEntryQueue.remove(random.nextInt(singleStudentsEntryQueue.size()));
+ team.addMember(firstRandomEntry.getStudent());
+
+ // Check if there's another student in the queue.
+ if (!singleStudentsEntryQueue.isEmpty()) {
+ StudentRecordEntry secondRandomEntry = singleStudentsEntryQueue.remove(random.nextInt(singleStudentsEntryQueue.size()));
+ team.addMember(secondRandomEntry.getStudent());
+ }
+
+ teams.add(team);
+ }
+
+ return teams;
+ }
+
+ /**
+ * Scans a list of student entries and removes entries which are outdated by newer entries by the same student, such
+ * that the resulting list contains only one unique entry per student.
+ * @param studentEntries The list of student entries, possibly containing duplicates.
+ * @return A list of student entries in which all outdated duplicates have been removed.
+ */
private static List removeDuplicateEntries(List studentEntries) {
List uniqueStudentEntries = new ArrayList<>();
From d9d9a51707cc7e2ca1364dad14fad053322d0744 Mon Sep 17 00:00:00 2001
From: Andrew Lalis
Date: Fri, 19 Apr 2019 16:17:09 +0200
Subject: [PATCH 03/12] Switched to mysql implementation and added persistence
for students.
---
.../config/DataSourceConfig.java | 34 -----------------
.../controllers/courses/ImportStudents.java | 37 +++++++++++++++++--
.../model/Course.java | 32 ++++++++++++++++
.../model/people/Person.java | 25 ++++++++++++-
.../model/people/teams/StudentTeam.java | 15 ++++++--
.../people/teams/TeachingAssistantTeam.java | 12 ++++--
.../model/people/teams/Team.java | 18 ++++-----
.../model/repositories/StudentRepository.java | 17 +++++++++
.../repositories/StudentTeamRepository.java | 7 ++++
src/main/resources/application.properties | 11 ++++--
src/main/resources/templates/courses.html | 2 +
.../resources/templates/courses/entity.html | 16 ++++++++
12 files changed, 166 insertions(+), 60 deletions(-)
delete mode 100644 src/main/java/nl/andrewlalis/teaching_assistant_assistant/config/DataSourceConfig.java
create mode 100644 src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/repositories/StudentRepository.java
create mode 100644 src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/repositories/StudentTeamRepository.java
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/config/DataSourceConfig.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/config/DataSourceConfig.java
deleted file mode 100644
index f6b0a94..0000000
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/config/DataSourceConfig.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package nl.andrewlalis.teaching_assistant_assistant.config;
-
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.boot.jdbc.DataSourceBuilder;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Primary;
-
-import javax.sql.DataSource;
-
-/**
- * Configures the data source for this application.
- */
-@Configuration
-public class DataSourceConfig {
-
- private static final String USERNAME = "root";
- private static final String PASSWORD = "root";
- private static final String DB_HOST = "localhost";
- private static final String DB_NAME = "teaching_assistant_assistant";
-
- @ConfigurationProperties(prefix = "spring.datasource")
- @Bean
- @Primary
- public DataSource getDataSource() {
- return DataSourceBuilder
- .create()
- .url("jdbc:h2:~/" + DB_NAME)
- .username(USERNAME)
- .password(PASSWORD)
- .build();
- }
-
-}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/ImportStudents.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/ImportStudents.java
index 02819db..b858d4c 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/ImportStudents.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/ImportStudents.java
@@ -3,7 +3,8 @@ package nl.andrewlalis.teaching_assistant_assistant.controllers.courses;
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
-import nl.andrewlalis.teaching_assistant_assistant.model.repositories.TeamRepository;
+import nl.andrewlalis.teaching_assistant_assistant.model.repositories.StudentRepository;
+import nl.andrewlalis.teaching_assistant_assistant.model.repositories.StudentTeamRepository;
import nl.andrewlalis.teaching_assistant_assistant.util.team_importing.StudentTeamImporter;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
@@ -25,11 +26,14 @@ public class ImportStudents {
private CourseRepository courseRepository;
- private TeamRepository teamRepository;
+ private StudentTeamRepository studentTeamRepository;
- protected ImportStudents(CourseRepository courseRepository, TeamRepository teamRepository) {
+ private StudentRepository studentRepository;
+
+ protected ImportStudents(CourseRepository courseRepository, StudentTeamRepository studentTeamRepository, StudentRepository studentRepository) {
this.courseRepository = courseRepository;
- this.teamRepository = teamRepository;
+ this.studentTeamRepository = studentTeamRepository;
+ this.studentRepository = studentRepository;
}
@GetMapping("/courses/{code}/import_students")
@@ -50,8 +54,33 @@ public class ImportStudents {
return "redirect:/courses";
}
+ Course course = optionalCourse.get();
+
try {
List studentTeams = StudentTeamImporter.importFromCSV(file.getInputStream(), optionalCourse.get());
+
+ // Save all the new students first, then save all the teams they belong to.
+ for (StudentTeam team : studentTeams) {
+ team.getMembers().forEach(student -> student.assignToCourse(course));
+ this.studentRepository.saveAll(team.getStudents());
+ team.setCourse(course);
+ }
+
+ studentTeams.forEach(team -> {
+ team.getMembers().forEach(student -> {
+ student.assignToCourse(course);
+ course.addParticipant(student);
+ });
+ team.setCourse(course);
+ course.addStudentTeam(team);
+
+ //this.studentRepository.saveAll((team.getMembers()));
+ });
+
+ //this.studentTeamRepository.saveAll(studentTeams);
+
+ this.courseRepository.save(course);
+
} catch (IOException e) {
e.printStackTrace();
}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/Course.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/Course.java
index 483b294..fd1879d 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/Course.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/Course.java
@@ -1,6 +1,8 @@
package nl.andrewlalis.teaching_assistant_assistant.model;
import nl.andrewlalis.teaching_assistant_assistant.model.assignments.Assignment;
+import nl.andrewlalis.teaching_assistant_assistant.model.people.Person;
+import nl.andrewlalis.teaching_assistant_assistant.model.people.Student;
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.TeachingAssistantTeam;
@@ -57,6 +59,19 @@ public class Course extends BasicEntity {
)
private List teachingAssistantTeams;
+ /**
+ * The list of all participants in this course, both teaching assistants and students.
+ */
+ @ManyToMany(
+ cascade = CascadeType.ALL
+ )
+ @JoinTable(
+ name = "course_participants",
+ joinColumns = @JoinColumn(name = "course_id"),
+ inverseJoinColumns = @JoinColumn(name = "person_id")
+ )
+ private List participants;
+
/**
* Default constructor for JPA.
*/
@@ -64,6 +79,7 @@ public class Course extends BasicEntity {
this.assignments = new ArrayList<>();
this.studentTeams = new ArrayList<>();
this.teachingAssistantTeams = new ArrayList<>();
+ this.participants = new ArrayList<>();
}
/**
@@ -85,6 +101,12 @@ public class Course extends BasicEntity {
this.teachingAssistantTeams.add(team);
}
+ public void addParticipant(Person person) {
+ if (!this.participants.contains(person)) {
+ this.participants.add(person);
+ }
+ }
+
/*
Getters and Setters
*/
@@ -109,6 +131,16 @@ public class Course extends BasicEntity {
return teachingAssistantTeams;
}
+ public List getStudents() {
+ List students = new ArrayList<>();
+ this.participants.forEach(participant -> {
+ if (participant instanceof Student) {
+ students.add((Student) participant);
+ }
+ });
+ return students;
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder(this.getName()).append('\n');
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/Person.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/Person.java
index 1029403..7909a7f 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/Person.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/Person.java
@@ -1,6 +1,7 @@
package nl.andrewlalis.teaching_assistant_assistant.model.people;
import nl.andrewlalis.teaching_assistant_assistant.model.BasicEntity;
+import nl.andrewlalis.teaching_assistant_assistant.model.Course;
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.Team;
import javax.persistence.*;
@@ -41,11 +42,21 @@ public abstract class Person extends BasicEntity {
)
private List teams;
+ /**
+ * The list of courses that this person belongs to.
+ */
+ @ManyToMany(
+ fetch = FetchType.LAZY,
+ mappedBy = "participants"
+ )
+ private List courses;
+
/**
* Default constructor for JPA.
*/
protected Person () {
this.teams = new ArrayList<>();
+ this.courses = new ArrayList<>();
}
/**
@@ -64,7 +75,15 @@ public abstract class Person extends BasicEntity {
}
public void assignToTeam(Team team) {
- this.teams.add(team);
+ if (!this.teams.contains(team)) {
+ this.teams.add(team);
+ }
+ }
+
+ public void assignToCourse(Course course) {
+ if (!this.courses.contains(course)) {
+ this.courses.add(course);
+ }
}
/*
@@ -91,6 +110,10 @@ public abstract class Person extends BasicEntity {
return this.githubUsername;
}
+ public List getCourses() {
+ return this.courses;
+ }
+
/**
* Determines if two Persons are equal. They are considered equal when all of the basic identifying information
* about the person is the same, regardless of case.
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/StudentTeam.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/StudentTeam.java
index 70fddce..f4be0fc 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/StudentTeam.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/StudentTeam.java
@@ -1,18 +1,20 @@
package nl.andrewlalis.teaching_assistant_assistant.model.people.teams;
import nl.andrewlalis.teaching_assistant_assistant.model.assignments.grades.AssignmentGrade;
+import nl.andrewlalis.teaching_assistant_assistant.model.people.Person;
import nl.andrewlalis.teaching_assistant_assistant.model.people.Student;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
+import java.util.ArrayList;
import java.util.List;
/**
* A group of students.
*/
@Entity
-public class StudentTeam extends Team {
+public class StudentTeam extends Team {
/**
* The list of assignment grades which this student group has received.
@@ -27,8 +29,13 @@ public class StudentTeam extends Team {
*/
public StudentTeam() {}
- @Override
- public void addMember(Student person) {
- this.getMembers().add(person);
+ public List getStudents() {
+ List people = super.getMembers();
+ List students = new ArrayList<>();
+ people.forEach(person -> {
+ students.add((Student) person);
+ });
+ return students;
}
+
}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/TeachingAssistantTeam.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/TeachingAssistantTeam.java
index 5361bc1..830a89f 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/TeachingAssistantTeam.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/TeachingAssistantTeam.java
@@ -1,6 +1,7 @@
package nl.andrewlalis.teaching_assistant_assistant.model.people.teams;
import nl.andrewlalis.teaching_assistant_assistant.model.assignments.grades.SectionGrade;
+import nl.andrewlalis.teaching_assistant_assistant.model.people.Person;
import nl.andrewlalis.teaching_assistant_assistant.model.people.TeachingAssistant;
import nl.andrewlalis.teaching_assistant_assistant.model.people.TeachingAssistantRole;
@@ -8,13 +9,14 @@ import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
+import java.util.ArrayList;
import java.util.List;
/**
* A group of teaching assistants.
*/
@Entity
-public class TeachingAssistantTeam extends Team {
+public class TeachingAssistantTeam extends Team {
/**
* The role that this teaching assistant team plays.
@@ -33,8 +35,10 @@ public class TeachingAssistantTeam extends Team {
*/
public TeachingAssistantTeam() {}
- @Override
- public void addMember(TeachingAssistant person) {
- this.getMembers().add(person);
+ public List getTeachingAssistants() {
+ List people = super.getMembers();
+ List teachingAssistants = new ArrayList<>(people.size());
+ people.forEach(person -> teachingAssistants.add((TeachingAssistant) person));
+ return teachingAssistants;
}
}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/Team.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/Team.java
index 82a43f7..0e81635 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/Team.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/Team.java
@@ -17,7 +17,7 @@ import java.util.List;
@Inheritance(
strategy = InheritanceType.JOINED
)
-public abstract class Team extends BasicEntity {
+public abstract class Team extends BasicEntity {
/**
* The list of members in this group.
@@ -30,7 +30,7 @@ public abstract class Team
extends BasicEntity {
joinColumns = @JoinColumn(name = "team_id"),
inverseJoinColumns = @JoinColumn(name = "person_id")
)
- protected List
members;
+ protected List members;
/**
* The course that this team belongs to. A team cannot exist on its own, it must belong to a course.
@@ -47,23 +47,23 @@ public abstract class Team extends BasicEntity {
this.members = new ArrayList<>();
}
- public void addMember(P person) {
+ public void addMember(Person person) {
if (!this.containsMember(person)) {
this.members.add(person);
}
}
- public void addMembers(List
people) {
- for (P person : people) {
+ public void addMembers(List people) {
+ for (Person person : people) {
this.addMember(person);
}
}
- public boolean containsMember(P person) {
+ public boolean containsMember(Person person) {
return this.members.contains(person);
}
- public void removeMember(P person) {
+ public void removeMember(Person person) {
this.members.remove(person);
}
@@ -79,7 +79,7 @@ public abstract class Team extends BasicEntity {
* Gets a list of all members of this team.
* @return A list of all the members in this team.
*/
- public List
getMembers() {
+ public List getMembers() {
return this.members;
}
@@ -90,7 +90,7 @@ public abstract class Team extends BasicEntity {
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
- for (P p : this.getMembers()) {
+ for (Person p : this.getMembers()) {
sb.append(p.getFullName()).append(", ");
}
return sb.toString();
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/repositories/StudentRepository.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/repositories/StudentRepository.java
new file mode 100644
index 0000000..3f86bb7
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/repositories/StudentRepository.java
@@ -0,0 +1,17 @@
+package nl.andrewlalis.teaching_assistant_assistant.model.repositories;
+
+import nl.andrewlalis.teaching_assistant_assistant.model.people.Student;
+import org.springframework.data.repository.CrudRepository;
+
+import java.util.Optional;
+
+public interface StudentRepository extends CrudRepository {
+
+ /**
+ * Tries to find a student by its unique student number.
+ * @param studentNumber The student number to search for.
+ * @return An optional Student object.
+ */
+ public Optional findByStudentNumber(int studentNumber);
+
+}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/repositories/StudentTeamRepository.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/repositories/StudentTeamRepository.java
new file mode 100644
index 0000000..f0b5250
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/repositories/StudentTeamRepository.java
@@ -0,0 +1,7 @@
+package nl.andrewlalis.teaching_assistant_assistant.model.repositories;
+
+import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
+import org.springframework.data.repository.CrudRepository;
+
+public interface StudentTeamRepository extends CrudRepository {
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index e12669e..57daaf2 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,7 +1,10 @@
-spring.jpa.hibernate.ddl-auto=create
-#spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
-
-#spring.jpa.properties.hibernate.show_sql=true
+spring.jpa.hibernate.ddl-auto=create-drop
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
+spring.datasource.username=root
+spring.datasource.password=root
+spring.datasource.url=jdbc:mysql://localhost:3306/teaching_assistant_assistant?serverTimezone=UTC
+#
+#spring.jpa.properties.hibernate.show_sql=false
#spring.jpa.properties.hibernate.use_sql_comments=true
#spring.jpa.properties.hibernate.format_sql=true
#spring.jpa.properties.hibernate.type=trace
diff --git a/src/main/resources/templates/courses.html b/src/main/resources/templates/courses.html
index d6f8562..42b41e7 100644
--- a/src/main/resources/templates/courses.html
+++ b/src/main/resources/templates/courses.html
@@ -11,6 +11,7 @@
Name |
Code |
Created at |
+ Students |
@@ -18,6 +19,7 @@
|
|
|
+ |
diff --git a/src/main/resources/templates/courses/entity.html b/src/main/resources/templates/courses/entity.html
index 511b5b4..4933903 100644
--- a/src/main/resources/templates/courses/entity.html
+++ b/src/main/resources/templates/courses/entity.html
@@ -41,6 +41,22 @@
+
+ All Students ():
+
diff --git a/src/main/resources/templates/courses/entity.html b/src/main/resources/templates/courses/entity.html
index 4933903..fb2c3e2 100644
--- a/src/main/resources/templates/courses/entity.html
+++ b/src/main/resources/templates/courses/entity.html
@@ -10,53 +10,20 @@
(Code: )
- Teaching Assistant Groups ():
-
-
- Student Groups ():
-
-
- All Students ():
-
+
diff --git a/src/main/resources/templates/courses/entity/teaching_assistant_teams.html b/src/main/resources/templates/courses/entity/teaching_assistant_teams.html
index 894b13a..07123a5 100644
--- a/src/main/resources/templates/courses/entity/teaching_assistant_teams.html
+++ b/src/main/resources/templates/courses/entity/teaching_assistant_teams.html
@@ -9,8 +9,23 @@
Teaching Assistant Teams for
+
+
No teaching assistant teams.
+
diff --git a/src/main/resources/templates/courses/entity/teaching_assistants.html b/src/main/resources/templates/courses/entity/teaching_assistants.html
new file mode 100644
index 0000000..9ca9361
--- /dev/null
+++ b/src/main/resources/templates/courses/entity/teaching_assistants.html
@@ -0,0 +1,26 @@
+
+
+
+ Teaching Assistants
+
+
+
+
+
Teaching Assistants for
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/fragments/header.html b/src/main/resources/templates/fragments/header.html
index 2cd3521..1e60e1d 100644
--- a/src/main/resources/templates/fragments/header.html
+++ b/src/main/resources/templates/fragments/header.html
@@ -13,6 +13,7 @@
From f1add7dc846fe525e987b3e806f3945f8b781e79 Mon Sep 17 00:00:00 2001
From: Andrew Lalis
Date: Sat, 20 Apr 2019 15:40:28 +0200
Subject: [PATCH 06/12] Fixed errors in ta teams listing for course.
---
.../templates/courses/entity/teaching_assistant_teams.html | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/resources/templates/courses/entity/teaching_assistant_teams.html b/src/main/resources/templates/courses/entity/teaching_assistant_teams.html
index 07123a5..aefe237 100644
--- a/src/main/resources/templates/courses/entity/teaching_assistant_teams.html
+++ b/src/main/resources/templates/courses/entity/teaching_assistant_teams.html
@@ -21,10 +21,10 @@
Teaching Assistant Team
-
+ |
|
- |
+ |
From 8aeb445a7ceb2d1bf98587280ae45f03ff9dd281 Mon Sep 17 00:00:00 2001
From: Andrew Lalis
Date: Sat, 20 Apr 2019 23:32:32 +0200
Subject: [PATCH 07/12] Added team manipulation
---
.../controllers/TeachingAssistants.java | 53 +++++++++++++
.../{Create.java => CreateCourse.java} | 4 +-
.../controllers/courses/Generate.java | 2 +-
.../CreateTeachingAssistantTeam.java | 75 +++++++++++++++++++
.../TeachingAssistantTeamEntity.java | 55 ++++++++++++++
.../TeachingAssistantEntity.java | 41 ++++++++++
.../model/Course.java | 8 ++
.../model/people/Person.java | 4 +
.../TeachingAssistantRepository.java | 7 ++
.../TeachingAssistantTeamRepository.java | 7 ++
.../util/github/GithubManager.java | 3 +
.../entity/teaching_assistant_teams.html | 10 ++-
.../teaching_assistant_teams/create.html | 37 +++++++++
.../teaching_assistant_teams/entity.html | 33 ++++++++
.../courses/entity/teaching_assistants.html | 5 +-
.../entity/teaching_assistants/create.html | 36 +++++++++
.../resources/templates/fragments/header.html | 1 +
.../templates/teaching_assistants.html | 32 ++++++++
.../templates/teaching_assistants/entity.html | 34 +++++++++
19 files changed, 442 insertions(+), 5 deletions(-)
create mode 100644 src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/TeachingAssistants.java
rename src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/{Create.java => CreateCourse.java} (88%)
create mode 100644 src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/entity/teaching_assistant_teams/CreateTeachingAssistantTeam.java
create mode 100644 src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/entity/teaching_assistant_teams/TeachingAssistantTeamEntity.java
create mode 100644 src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/teaching_assistants/TeachingAssistantEntity.java
create mode 100644 src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/repositories/TeachingAssistantRepository.java
create mode 100644 src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/repositories/TeachingAssistantTeamRepository.java
create mode 100644 src/main/resources/templates/courses/entity/teaching_assistant_teams/create.html
create mode 100644 src/main/resources/templates/courses/entity/teaching_assistant_teams/entity.html
create mode 100644 src/main/resources/templates/courses/entity/teaching_assistants/create.html
create mode 100644 src/main/resources/templates/teaching_assistants.html
create mode 100644 src/main/resources/templates/teaching_assistants/entity.html
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/TeachingAssistants.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/TeachingAssistants.java
new file mode 100644
index 0000000..821ad41
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/TeachingAssistants.java
@@ -0,0 +1,53 @@
+package nl.andrewlalis.teaching_assistant_assistant.controllers;
+
+import nl.andrewlalis.teaching_assistant_assistant.model.Course;
+import nl.andrewlalis.teaching_assistant_assistant.model.people.TeachingAssistant;
+import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
+import nl.andrewlalis.teaching_assistant_assistant.model.repositories.TeachingAssistantRepository;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+
+import java.util.Optional;
+
+@Controller
+public class TeachingAssistants {
+
+ private TeachingAssistantRepository teachingAssistantRepository;
+ private CourseRepository courseRepository;
+
+ protected TeachingAssistants(TeachingAssistantRepository teachingAssistantRepository, CourseRepository courseRepository) {
+ this.teachingAssistantRepository = teachingAssistantRepository;
+ this.courseRepository = courseRepository;
+ }
+
+ @GetMapping("/teaching_assistants")
+ public String get(Model model) {
+ model.addAttribute("teaching_assistants", teachingAssistantRepository.findAll());
+ return "teaching_assistants";
+ }
+
+ @GetMapping("/courses/{code}/teaching_assistants/create")
+ public String getCreate(@PathVariable String code, Model model) {
+ model.addAttribute("teachingAssistant", new TeachingAssistant("First Name", "Last Name", "github Username", "me@example.com"));
+ Optional optionalCourse = this.courseRepository.findByCode(code);
+ optionalCourse.ifPresent(course -> model.addAttribute("course", course));
+ return "courses/entity/teaching_assistants/create";
+ }
+
+ @PostMapping(
+ value = "/courses/{code}/teaching_assistants",
+ consumes = "application/x-www-form-urlencoded"
+ )
+ public String post(@PathVariable String code, @ModelAttribute("teachingAssistant") TeachingAssistant teachingAssistant) {
+ Optional optionalCourse = this.courseRepository.findByCode(code);
+ optionalCourse.ifPresent(course -> {
+ course.addParticipant(teachingAssistant);
+ this.courseRepository.save(course);
+ });
+ return "teaching_assistants/entity";
+ }
+}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/Create.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/CreateCourse.java
similarity index 88%
rename from src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/Create.java
rename to src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/CreateCourse.java
index 08376e2..7d8cd0d 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/Create.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/CreateCourse.java
@@ -7,11 +7,11 @@ import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
-public class Create {
+public class CreateCourse {
private CourseRepository courseRepository;
- protected Create(CourseRepository courseRepository) {
+ protected CreateCourse(CourseRepository courseRepository) {
this.courseRepository = courseRepository;
}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/Generate.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/Generate.java
index c7f8ae5..2d5227b 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/Generate.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/Generate.java
@@ -26,7 +26,7 @@ public class Generate {
this.courseRepository.saveAll(courses);
model.addAttribute("courses", courseRepository.findAll());
- return "courses";
+ return "redirect:/courses";
}
}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/entity/teaching_assistant_teams/CreateTeachingAssistantTeam.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/entity/teaching_assistant_teams/CreateTeachingAssistantTeam.java
new file mode 100644
index 0000000..542528d
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/entity/teaching_assistant_teams/CreateTeachingAssistantTeam.java
@@ -0,0 +1,75 @@
+package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.teaching_assistant_teams;
+
+import nl.andrewlalis.teaching_assistant_assistant.model.Course;
+import nl.andrewlalis.teaching_assistant_assistant.model.people.TeachingAssistant;
+import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.TeachingAssistantTeam;
+import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
+import nl.andrewlalis.teaching_assistant_assistant.model.repositories.TeachingAssistantRepository;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.Optional;
+
+@Controller
+public class CreateTeachingAssistantTeam {
+
+ private CourseRepository courseRepository;
+ private TeachingAssistantRepository teachingAssistantRepository;
+
+ protected CreateTeachingAssistantTeam(CourseRepository courseRepository, TeachingAssistantRepository teachingAssistantRepository) {
+ this.courseRepository = courseRepository;
+ this.teachingAssistantRepository = teachingAssistantRepository;
+ }
+
+ @GetMapping("/courses/{code}/teaching_assistant_teams/create")
+ public String get(@PathVariable String code, Model model) {
+ Optional optionalCourse = this.courseRepository.findByCode(code);
+ optionalCourse.ifPresent(course -> model.addAttribute("course", course));
+ return "courses/entity/teaching_assistant_teams/create";
+ }
+
+ @PostMapping(
+ value = "/courses/{code}/teaching_assistant_teams",
+ consumes = "application/x-www-form-urlencoded"
+ )
+ public String post(
+ @PathVariable String code,
+ @RequestParam(value = "github_team_name") String githubTeamName,
+ @RequestParam(value = "id_1") long id1,
+ @RequestParam(value = "id_2") long id2,
+ Model model
+ ) {
+ TeachingAssistantTeam team = new TeachingAssistantTeam();
+ team.setGithubTeamName(githubTeamName);
+
+ Optional optionalCourse = this.courseRepository.findByCode(code);
+ Optional optionalTeachingAssistant1 = this.teachingAssistantRepository.findById(id1);
+ Optional optionalTeachingAssistant2 = this.teachingAssistantRepository.findById(id2);
+
+ System.out.println("Course code: " + code + ", Team name: " + githubTeamName + ", TA 1: " + id1 + ", TA 2: " + id2);
+
+ if (optionalCourse.isPresent() && optionalTeachingAssistant1.isPresent() && optionalTeachingAssistant2.isPresent()) {
+ System.out.println("All data available.");
+ Course course = optionalCourse.get();
+ team.setCourse(course);
+
+ team.addMember(optionalTeachingAssistant1.get());
+ team.addMember(optionalTeachingAssistant2.get());
+
+ course.addTeachingAssistantTeam(team);
+ this.courseRepository.save(course);
+
+ model.addAttribute("course", course);
+
+ return "courses/entity/teaching_assistant_teams";
+ } else {
+ System.out.println("Missing data!");
+ }
+
+ return "redirect:/courses/entity";
+ }
+}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/entity/teaching_assistant_teams/TeachingAssistantTeamEntity.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/entity/teaching_assistant_teams/TeachingAssistantTeamEntity.java
new file mode 100644
index 0000000..5923980
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/entity/teaching_assistant_teams/TeachingAssistantTeamEntity.java
@@ -0,0 +1,55 @@
+package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.teaching_assistant_teams;
+
+import nl.andrewlalis.teaching_assistant_assistant.model.Course;
+import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.TeachingAssistantTeam;
+import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
+import nl.andrewlalis.teaching_assistant_assistant.model.repositories.TeachingAssistantTeamRepository;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+
+import java.util.Optional;
+
+@Controller
+public class TeachingAssistantTeamEntity {
+
+ private CourseRepository courseRepository;
+ private TeachingAssistantTeamRepository teachingAssistantTeamRepository;
+
+ protected TeachingAssistantTeamEntity(CourseRepository courseRepository, TeachingAssistantTeamRepository teachingAssistantTeamRepository) {
+ this.courseRepository = courseRepository;
+ this.teachingAssistantTeamRepository = teachingAssistantTeamRepository;
+ }
+
+ @GetMapping("/courses/{courseCode}/teaching_assistant_teams/{teamId}")
+ public String get(@PathVariable String courseCode, @PathVariable long teamId, Model model) {
+ Optional optionalCourse = this.courseRepository.findByCode(courseCode);
+ Optional optionalTeachingAssistantTeam = this.teachingAssistantTeamRepository.findById(teamId);
+
+ if (optionalCourse.isPresent() && optionalTeachingAssistantTeam.isPresent()) {
+ model.addAttribute("course", optionalCourse.get());
+ model.addAttribute("teachingAssistantTeam", optionalTeachingAssistantTeam.get());
+ }
+
+ return "courses/entity/teaching_assistant_teams/entity";
+ }
+
+ @GetMapping("/courses/{courseCode}/teaching_assistant_teams/{teamId}/delete")
+ public String delete(@PathVariable String courseCode, @PathVariable long teamId) {
+ Optional optionalCourse = this.courseRepository.findByCode(courseCode);
+ Optional optionalTeachingAssistantTeam = this.teachingAssistantTeamRepository.findById(teamId);
+
+ if (optionalCourse.isPresent() && optionalTeachingAssistantTeam.isPresent()) {
+ Course course = optionalCourse.get();
+ TeachingAssistantTeam team = optionalTeachingAssistantTeam.get();
+ course.removeTeachingAssistantTeam(team);
+
+ this.teachingAssistantTeamRepository.delete(team);
+ this.courseRepository.save(course);
+ }
+
+ return "redirect:/courses/entity/teaching_assistants";
+ }
+
+}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/teaching_assistants/TeachingAssistantEntity.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/teaching_assistants/TeachingAssistantEntity.java
new file mode 100644
index 0000000..99991b3
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/teaching_assistants/TeachingAssistantEntity.java
@@ -0,0 +1,41 @@
+package nl.andrewlalis.teaching_assistant_assistant.controllers.teaching_assistants;
+
+import nl.andrewlalis.teaching_assistant_assistant.model.people.TeachingAssistant;
+import nl.andrewlalis.teaching_assistant_assistant.model.repositories.TeachingAssistantRepository;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+
+import java.util.Optional;
+
+@Controller
+public class TeachingAssistantEntity {
+
+ private TeachingAssistantRepository teachingAssistantRepository;
+
+ protected TeachingAssistantEntity(TeachingAssistantRepository teachingAssistantRepository) {
+ this.teachingAssistantRepository = teachingAssistantRepository;
+ }
+
+ @GetMapping("/teaching_assistants/{id}")
+ public String get(@PathVariable long id, Model model) {
+ Optional optionalTeachingAssistant = this.teachingAssistantRepository.findById(id);
+ optionalTeachingAssistant.ifPresent(teachingAssistant -> model.addAttribute("teachingAssistant", teachingAssistant));
+ return "teaching_assistants/entity";
+ }
+
+ @GetMapping("/teaching_assistants/{id}/delete")
+ public String delete(@PathVariable long id) {
+ Optional optionalTeachingAssistant = this.teachingAssistantRepository.findById(id);
+ optionalTeachingAssistant.ifPresent(teachingAssistant -> {
+ teachingAssistant.getCourses().forEach(course -> course.removeParticipant(teachingAssistant));
+ teachingAssistant.getTeams().forEach(team -> {
+ team.removeMember(teachingAssistant);
+ });
+ this.teachingAssistantRepository.delete(teachingAssistant);
+ });
+
+ return "redirect:/teaching_assistants";
+ }
+}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/Course.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/Course.java
index 4e65534..97a62f3 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/Course.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/Course.java
@@ -108,12 +108,20 @@ public class Course extends BasicEntity {
this.teachingAssistantTeams.add(team);
}
+ public void removeTeachingAssistantTeam(TeachingAssistantTeam team) {
+ this.teachingAssistantTeams.remove(team);
+ }
+
public void addParticipant(Person person) {
if (!this.participants.contains(person)) {
this.participants.add(person);
}
}
+ public void removeParticipant(Person person) {
+ this.participants.remove(person);
+ }
+
/*
Getters and Setters
*/
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/Person.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/Person.java
index 7909a7f..70245af 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/Person.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/Person.java
@@ -114,6 +114,10 @@ public abstract class Person extends BasicEntity {
return this.courses;
}
+ public List getTeams() {
+ return this.teams;
+ }
+
/**
* Determines if two Persons are equal. They are considered equal when all of the basic identifying information
* about the person is the same, regardless of case.
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/repositories/TeachingAssistantRepository.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/repositories/TeachingAssistantRepository.java
new file mode 100644
index 0000000..63154c9
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/repositories/TeachingAssistantRepository.java
@@ -0,0 +1,7 @@
+package nl.andrewlalis.teaching_assistant_assistant.model.repositories;
+
+import nl.andrewlalis.teaching_assistant_assistant.model.people.TeachingAssistant;
+import org.springframework.data.repository.CrudRepository;
+
+public interface TeachingAssistantRepository extends CrudRepository {
+}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/repositories/TeachingAssistantTeamRepository.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/repositories/TeachingAssistantTeamRepository.java
new file mode 100644
index 0000000..a06552b
--- /dev/null
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/repositories/TeachingAssistantTeamRepository.java
@@ -0,0 +1,7 @@
+package nl.andrewlalis.teaching_assistant_assistant.model.repositories;
+
+import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.TeachingAssistantTeam;
+import org.springframework.data.repository.CrudRepository;
+
+public interface TeachingAssistantTeamRepository extends CrudRepository {
+}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/github/GithubManager.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/github/GithubManager.java
index 5925a87..c314d8f 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/github/GithubManager.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/github/GithubManager.java
@@ -10,6 +10,9 @@ import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
+/**
+ * Encapsulates much of the github functionality that is needed.
+ */
public class GithubManager {
private GitHub github;
diff --git a/src/main/resources/templates/courses/entity/teaching_assistant_teams.html b/src/main/resources/templates/courses/entity/teaching_assistant_teams.html
index aefe237..b1eb8b7 100644
--- a/src/main/resources/templates/courses/entity/teaching_assistant_teams.html
+++ b/src/main/resources/templates/courses/entity/teaching_assistant_teams.html
@@ -25,12 +25,20 @@
|
+
+
+ Delete
+
+ |
+
+
+
+ Create your course here
+
+
+
+
+
+
+
diff --git a/src/main/resources/templates/courses/entity/teaching_assistant_teams/create.html b/src/main/resources/templates/courses/entity/teaching_assistant_teams/create.html
new file mode 100644
index 0000000..b37e0d9
--- /dev/null
+++ b/src/main/resources/templates/courses/entity/teaching_assistant_teams/create.html
@@ -0,0 +1,37 @@
+
+
+