Abstracted team object.
This commit is contained in:
parent
b7a89c0946
commit
54498a4955
|
@ -1,11 +1,10 @@
|
|||
package nl.andrewlalis;
|
||||
|
||||
import nl.andrewlalis.database.Database;
|
||||
import nl.andrewlalis.model.database.Database;
|
||||
import nl.andrewlalis.git_api.GithubManager;
|
||||
import nl.andrewlalis.model.Student;
|
||||
import nl.andrewlalis.model.StudentTeam;
|
||||
import nl.andrewlalis.util.CommandLine;
|
||||
import nl.andrewlalis.util.FileUtils;
|
||||
import nl.andrewlalis.util.Logging;
|
||||
import nl.andrewlalis.util.TeamGenerator;
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package nl.andrewlalis.git_api;
|
|||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import jdk.nashorn.internal.ir.annotations.Ignore;
|
||||
import nl.andrewlalis.model.Student;
|
||||
import nl.andrewlalis.model.StudentTeam;
|
||||
import org.apache.http.HttpResponse;
|
||||
|
@ -88,7 +89,7 @@ public class GithubManager {
|
|||
|
||||
StudentTeam t = new StudentTeam();
|
||||
Student s = new Student(3050831, "Andrew Lalis", "andrewlalisofficial@gmail.com", "andrewlalis", null);
|
||||
t.addStudent(s);
|
||||
t.addMember(s);
|
||||
t.setId(42);
|
||||
|
||||
this.setupStudentTeam(t, teamAll);
|
||||
|
@ -99,6 +100,7 @@ public class GithubManager {
|
|||
* @param allTeachingAssistants A team consisting of all teaching assistants.
|
||||
* @throws IOException If an HTTP request failed.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private void setupAssignmentsRepo(GHTeam allTeachingAssistants) throws IOException {
|
||||
// Check if the repository already exists.
|
||||
GHRepository existingRepo = this.organization.getRepository(this.assignmentsRepoName);
|
||||
|
@ -139,10 +141,11 @@ public class GithubManager {
|
|||
* @param taTeam The team of teaching assistants that is responsible for these students.
|
||||
* @throws IOException If an HTTP request fails.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private void setupStudentTeam(StudentTeam team, GHTeam taTeam) throws IOException {
|
||||
String teamRepoName = team.generateUniqueName(this.studentRepoPrefix);
|
||||
|
||||
List<Student> students = team.getStudents();
|
||||
Student[] students = team.getStudents();
|
||||
StringBuilder description = new StringBuilder("Group ");
|
||||
description.append(team.getId()).append(": ");
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ package nl.andrewlalis.model;
|
|||
* A generic object that students, teaching assistants, and professors can extend from. This covers all the basic
|
||||
* functionality that applies to anyone in the system.
|
||||
*/
|
||||
public abstract class Person {
|
||||
public abstract class Person {
|
||||
|
||||
/**
|
||||
* The unique identification number for this person. (P- or S-Number)
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package nl.andrewlalis.model;
|
||||
|
||||
import java.sql.Connection;
|
||||
|
||||
/**
|
||||
* Defines objects which may be stored in the database, and requires that they implement methods for both storage and
|
||||
* retrieval of the objects.
|
||||
*/
|
||||
public interface Storable {
|
||||
|
||||
/**
|
||||
* Stores the object in the database.
|
||||
* @param connection The connection to the database which can be used for preparation of and execution of queries.
|
||||
* @return True if the object is successfully stored, false if an error occurred.
|
||||
*/
|
||||
boolean store(Connection connection);
|
||||
|
||||
}
|
|
@ -39,9 +39,9 @@ public class Student extends Person {
|
|||
public StudentTeam getPreferredTeam(Map<Integer, Student> studentMap) {
|
||||
StudentTeam t = new StudentTeam();
|
||||
for (int partnerNumber : this.getPreferredPartners()) {
|
||||
t.addStudent(studentMap.get(partnerNumber));
|
||||
t.addMember(studentMap.get(partnerNumber));
|
||||
}
|
||||
t.addStudent(this);
|
||||
t.addMember(this);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,74 +1,22 @@
|
|||
package nl.andrewlalis.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Represents one or more students' collective information.
|
||||
*/
|
||||
public class StudentTeam {
|
||||
|
||||
/**
|
||||
* The list of students in this team.
|
||||
*/
|
||||
private List<Student> students;
|
||||
|
||||
/**
|
||||
* The team identification number.
|
||||
*/
|
||||
private int id;
|
||||
public class StudentTeam extends Team{
|
||||
|
||||
public StudentTeam() {
|
||||
this.students = new ArrayList<>();
|
||||
this.id = -1;
|
||||
super(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a student is already included in this team.
|
||||
* @param student A student.
|
||||
* @return True if the student is in this team, false otherwise.
|
||||
* Gets a list of students, casted from the original Person[].
|
||||
* @return An array of Students.
|
||||
*/
|
||||
public boolean hasStudent(Student student) {
|
||||
for (Student s : this.students) {
|
||||
if (s.equals(student)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getStudentCount() {
|
||||
return this.students.size();
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setStudents(List<Student> students) {
|
||||
this.students = students;
|
||||
}
|
||||
|
||||
public List<Student> getStudents() {
|
||||
return this.students;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a student to this team.
|
||||
* @param student The student to add.
|
||||
* @return True if the student could be added, false otherwise.
|
||||
*/
|
||||
public boolean addStudent(Student student) {
|
||||
if (!this.hasStudent(student)) {
|
||||
this.students.add(student);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
public Student[] getStudents() {
|
||||
return Arrays.copyOf(this.getMembers(), this.memberCount(), Student[].class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -81,10 +29,9 @@ public class StudentTeam {
|
|||
* @return True if the team is valid, and false otherwise.
|
||||
*/
|
||||
public boolean isValid(int teamSize) {
|
||||
if (this.getStudentCount() == teamSize) {
|
||||
List<Integer> encounteredIds = new ArrayList<>();
|
||||
for (Student studentA : this.students) {
|
||||
for (Student studentB : this.students) {
|
||||
if (this.memberCount() == teamSize) {
|
||||
for (Student studentA : this.getStudents()) {
|
||||
for (Student studentB : this.getStudents()) {
|
||||
if (!studentA.equals(studentB) && !studentA.getPreferredPartners().contains(studentB.getNumber())) {
|
||||
return false;
|
||||
}
|
||||
|
@ -105,48 +52,9 @@ public class StudentTeam {
|
|||
public String generateUniqueName(String prefix) {
|
||||
StringBuilder sb = new StringBuilder(prefix);
|
||||
sb.append("_team_").append(this.id);
|
||||
for (Student s : this.students) {
|
||||
for (Student s : (Student[]) this.getMembers()) {
|
||||
sb.append('_').append(s.getNumber());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pretty formatting of this team so that it can be viewed in the command line. This is mainly for
|
||||
* debugging purposes.
|
||||
* @return A string representing the team.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder("StudentTeam: ");
|
||||
sb.append(this.id).append('\n');
|
||||
for (Student s : this.students) {
|
||||
sb.append('\t').append(s.toString()).append('\n');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if one team is equivalent to another. This is determined by if the two teams are comprised of the same
|
||||
* students, in any order.
|
||||
* @param o The object to compare to this team.
|
||||
* @return True if the teams contain the same students, false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof StudentTeam) {
|
||||
StudentTeam t = (StudentTeam) o;
|
||||
if (t.getStudentCount() != this.getStudentCount()) {
|
||||
return false;
|
||||
}
|
||||
for (Student s : this.students) {
|
||||
if (!t.hasStudent(s)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
package nl.andrewlalis.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An abstract Team object from which both Teaching Assistant and Student teams can be built.
|
||||
*/
|
||||
public abstract class Team {
|
||||
|
||||
/**
|
||||
* An identification number unique to this team alone.
|
||||
*/
|
||||
protected int id;
|
||||
|
||||
/**
|
||||
* A list of members of this team.
|
||||
*/
|
||||
private List<Person> members;
|
||||
|
||||
/**
|
||||
* Constructs this team with the given id.
|
||||
* @param id The id to assign to this team.
|
||||
*/
|
||||
public Team(int id) {
|
||||
this.id = id;
|
||||
this.members = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param newId The new id number to assign to this team.
|
||||
*/
|
||||
public void setId(int newId) {
|
||||
this.id = newId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return This team's id number.
|
||||
*/
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new person to this team, only if they do not exist in this team yet.
|
||||
* @param newMember The new member to add.
|
||||
*/
|
||||
public void addMember(Person newMember) {
|
||||
for (Person person : this.members) {
|
||||
if (person.equals(newMember)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.members.add(newMember);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a person from this team.
|
||||
* @param person The person to remove.
|
||||
*/
|
||||
public void removeMember(Person person) {
|
||||
this.members.remove(person);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this team contains the given person.
|
||||
* @param person The person to check for.
|
||||
* @return True if the person is a member of this team, false otherwise.
|
||||
*/
|
||||
public boolean containsMember(Person person) {
|
||||
for (Person p : this.members) {
|
||||
if (p.equals(person)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the team to be comprised of only the members given in the array.
|
||||
* @param people The people which will make up the members of this team.
|
||||
*/
|
||||
public void setMembers(Person[] people) {
|
||||
this.members = new ArrayList<>(Arrays.asList(people));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of people in this team.
|
||||
* @return A list of people in this team.
|
||||
*/
|
||||
public Person[] getMembers() {
|
||||
Person[] people = new Person[this.memberCount()];
|
||||
this.members.toArray(people);
|
||||
return people;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of people in this team.
|
||||
* @return The number of people in this team.
|
||||
*/
|
||||
public int memberCount() {
|
||||
return this.members.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if another team has the same members as this team.
|
||||
* @param team The team to compare to this team.
|
||||
* @return True if the other team has all the same members as this team.
|
||||
*/
|
||||
public boolean hasSameMembers(Team team) {
|
||||
if (this.memberCount() == team.memberCount()) {
|
||||
for (Person person : this.members) {
|
||||
if (!team.containsMember(person)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an object is equal to this team. First checks if the other object is a Team, and then if it has the
|
||||
* same id and team size. If both of those conditions are met, then it will check that all team members are the
|
||||
* same.
|
||||
* @param obj The object to check for equality.
|
||||
* @return True if the two objects represent the same team, or false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Team) {
|
||||
Team team = (Team) obj;
|
||||
if (team.getId() == this.getId() && this.hasSameMembers(team)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A String containing a line for each member in the team.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Person person : this.members) {
|
||||
sb.append(person.toString()).append('\n');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
package nl.andrewlalis.database;
|
||||
package nl.andrewlalis.model.database;
|
||||
|
||||
import nl.andrewlalis.model.Person;
|
||||
import nl.andrewlalis.model.Student;
|
||||
import nl.andrewlalis.model.TeachingAssistant;
|
||||
import nl.andrewlalis.util.FileUtils;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
|
@ -53,18 +53,13 @@ public class Database {
|
|||
* @return True, if successful, false if not.
|
||||
*/
|
||||
public boolean initialize() {
|
||||
String sql = FileUtils.readStringFromFile("/sql/table_init.sql");
|
||||
String[] commands = sql.split(";");
|
||||
for (String command : commands) {
|
||||
logger.finest("Executing command: " + command);
|
||||
if (command.trim().length() > 1) {
|
||||
try {
|
||||
PreparedStatement statement = this.connection.prepareStatement(command);
|
||||
statement.execute();
|
||||
} catch (SQLException e) {
|
||||
logger.severe("SQLException: " + e.getErrorCode());
|
||||
return false;
|
||||
}
|
||||
List<PreparedStatement> statements = Utils.prepareStatementsFromFile("/sql/table_init.sql", this.connection);
|
||||
for (PreparedStatement statement : statements) {
|
||||
try {
|
||||
statement.execute();
|
||||
} catch (SQLException e) {
|
||||
logger.severe("SQLException while executing prepared statement: " + statement.toString() + ". Code: " + e.getErrorCode());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
logger.fine("Database initialized.");
|
|
@ -0,0 +1,52 @@
|
|||
package nl.andrewlalis.model.database;
|
||||
|
||||
import nl.andrewlalis.util.FileUtils;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Contains some methods which make database actions much easier.
|
||||
*/
|
||||
public class Utils {
|
||||
|
||||
/**
|
||||
* The logger for outputting debug info.
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(Utils.class.getName());
|
||||
static {
|
||||
logger.setParent(Logger.getGlobal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an ordered list of prepared statements from a file which contains multiple statements separated by a
|
||||
* semicolon. This method separates those statements into their own strings, and prepares them individually to be
|
||||
* executed later.
|
||||
* @param filename The name of the file which contains the statements.
|
||||
* @param connection The connection to a database; used to prepare statements.
|
||||
* @return An ordered list of prepared statements which are based on the contents of the file provided.
|
||||
*/
|
||||
public static List<PreparedStatement> prepareStatementsFromFile(String filename, Connection connection) {
|
||||
String string = FileUtils.readStringFromFile(filename);
|
||||
if (string == null || string.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
String[] splits = string.split(";");
|
||||
List<PreparedStatement> statements = new ArrayList<>();
|
||||
for (String split : splits) {
|
||||
if (split.trim().length() > 1) {
|
||||
try {
|
||||
statements.add(connection.prepareStatement(split));
|
||||
} catch (SQLException e) {
|
||||
logger.severe("SQLException while preparing a statement:\n" + split + "\nError Code: " + e.getErrorCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
return statements;
|
||||
}
|
||||
|
||||
}
|
|
@ -80,15 +80,15 @@ public class TeamGenerator {
|
|||
// For each student, try to make a team from its preferred partners.
|
||||
for (Map.Entry<Integer, Student> e : studentMap.entrySet()) {
|
||||
StudentTeam newTeam = e.getValue().getPreferredTeam(studentMap);
|
||||
logger.finest("Checking if student's preferred team is valid: " + newTeam.getStudents());
|
||||
logger.finest("Checking if student's preferred team is valid:\n" + newTeam);
|
||||
// Check if the team is of a valid size, and is not a duplicate.
|
||||
// Note that at this stage, singles are treated as studentTeams of 1, and thus not valid for any teamSize > 1.
|
||||
if (newTeam.isValid(teamSize) && !studentTeams.contains(newTeam)) {
|
||||
// Once we know this team is completely valid, we remove all the students in it from the list of singles.
|
||||
newTeam.setId(teamCount++);
|
||||
singleStudents.removeAll(newTeam.getStudents());
|
||||
singleStudents.removeAll(Arrays.asList(newTeam.getStudents()));
|
||||
studentTeams.add(newTeam);
|
||||
logger.fine("Created team: " + newTeam);
|
||||
logger.fine("Created team:\n" + newTeam);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,11 +109,11 @@ public class TeamGenerator {
|
|||
while (!singleStudents.isEmpty()) {
|
||||
StudentTeam t = new StudentTeam();
|
||||
t.setId(teamIndex++);
|
||||
logger.fine("Creating new team of single students: " + t);
|
||||
while (t.getStudentCount() < teamSize && !singleStudents.isEmpty()) {
|
||||
logger.fine("Creating new team of single students:\n" + t);
|
||||
while (t.memberCount() < teamSize && !singleStudents.isEmpty()) {
|
||||
Student s = singleStudents.remove(0);
|
||||
logger.finest("Single student: " + s);
|
||||
t.addStudent(s);
|
||||
t.addMember(s);
|
||||
}
|
||||
studentTeams.add(t);
|
||||
logger.fine("Created team: " + t);
|
||||
|
|
Loading…
Reference in New Issue