From 2d40820025b3769d0a01cb19b5628f1a0d8acf32 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Sun, 26 Aug 2018 17:04:35 +0200 Subject: [PATCH] Added tons of stuff. --- src/main/java/nl/andrewlalis/Main.java | 29 ++- .../nl/andrewlalis/git_api/GithubManager.java | 168 +++++++++++------- .../nl/andrewlalis/model/StudentTeam.java | 15 +- .../java/nl/andrewlalis/model/TATeam.java | 17 +- .../andrewlalis/model/database/Database.java | 28 ++- .../ui/control/OutputTextHandler.java | 3 + .../ui/control/command/CommandExecutor.java | 16 +- .../command/executables/ArchiveRepos.java | 30 ++++ .../command/executables/GithubExecutable.java | 34 ++++ .../executables/ReadStudentsFileToDB.java | 36 ++++ .../listeners/CommandFieldKeyListener.java | 2 +- .../andrewlalis/ui/view/InitializerApp.java | 58 +++++- .../java/nl/andrewlalis/util/FileUtils.java | 4 +- src/main/resources/sql/insert/types.sql | 4 +- 14 files changed, 343 insertions(+), 101 deletions(-) create mode 100644 src/main/java/nl/andrewlalis/ui/control/command/executables/ArchiveRepos.java create mode 100644 src/main/java/nl/andrewlalis/ui/control/command/executables/GithubExecutable.java create mode 100644 src/main/java/nl/andrewlalis/ui/control/command/executables/ReadStudentsFileToDB.java diff --git a/src/main/java/nl/andrewlalis/Main.java b/src/main/java/nl/andrewlalis/Main.java index e2aee76..681ac2d 100644 --- a/src/main/java/nl/andrewlalis/Main.java +++ b/src/main/java/nl/andrewlalis/Main.java @@ -6,6 +6,8 @@ import nl.andrewlalis.model.Student; import nl.andrewlalis.model.StudentTeam; import nl.andrewlalis.ui.control.command.CommandExecutor; import nl.andrewlalis.ui.control.command.Executable; +import nl.andrewlalis.ui.control.command.executables.ArchiveRepos; +import nl.andrewlalis.ui.control.command.executables.ReadStudentsFileToDB; import nl.andrewlalis.ui.view.InitializerApp; import nl.andrewlalis.util.CommandLine; import nl.andrewlalis.util.Logging; @@ -38,18 +40,26 @@ public class Main { logger.severe("Unable to save log to file."); } + // Command executor which will be used by all actions the user can do. CommandExecutor executor = new CommandExecutor(); + + // Initialize User Interface. + InitializerApp app = new InitializerApp(executor); + app.begin(); + + Database db = new Database("database/initializer.sqlite"); + db.initialize(); + executor.registerCommand("test", args1 -> { System.out.println("TESTING"); return true; }); + executor.registerCommand("readstudents", new ReadStudentsFileToDB(db)); + executor.registerCommand("archiveall", new ArchiveRepos()); - // Initialize User Interface. - InitializerApp app = new InitializerApp(executor); + logger.info("GithubManager for Github Repositories in Educational Organizations. Program initialized."); - app.begin(); - logger.info("GithubManager for Github Repositories in Educational Organizations."); // Get studentTeams from CSV file. // List studentTeams = getStudentTeamsFromCSV(userOptions.get("input"), Integer.parseInt(userOptions.get("teamsize"))); @@ -68,17 +78,6 @@ public class Main { } catch (Exception e) { e.printStackTrace(); } - - // Initialize database. -// Database db = new Database("database/initializer.sqlite"); -// db.initialize(); -// for (StudentTeam team : studentTeams) { -// for (Student student : team.getStudents()) { -// db.storeStudent(student); -// } -// } - - } diff --git a/src/main/java/nl/andrewlalis/git_api/GithubManager.java b/src/main/java/nl/andrewlalis/git_api/GithubManager.java index d7265a2..88ed56c 100644 --- a/src/main/java/nl/andrewlalis/git_api/GithubManager.java +++ b/src/main/java/nl/andrewlalis/git_api/GithubManager.java @@ -5,6 +5,7 @@ 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 nl.andrewlalis.model.TATeam; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpPatch; import org.apache.http.entity.StringEntity; @@ -26,18 +27,6 @@ public class GithubManager { * The assignments repository where students will get assignments from. */ private GHRepository assignmentsRepo; - private String assignmentsRepoName; - - /** - * The name of the team which contains all teaching assistants. - */ - private String teachingAssistantsTeamName; - - /** - * The prefix used to prepend the names of student repositories. - * Should ideally contain the current school year. - */ - private String studentRepoPrefix; /** * Github object for API interactions. @@ -54,12 +43,8 @@ public class GithubManager { logger.setParent(Logger.getGlobal()); } - public GithubManager(String organizationName, String accessToken, String assignmentsRepo, String teachingAssistantsTeamName, String studentRepoPrefix) { - this.assignmentsRepoName = assignmentsRepo; - this.teachingAssistantsTeamName = teachingAssistantsTeamName; - this.studentRepoPrefix = studentRepoPrefix; + public GithubManager(String organizationName, String accessToken) { this.accessToken = accessToken; - try { this.github = GitHub.connectUsingOAuth(accessToken); this.organization = this.github.getOrganization(organizationName); @@ -80,57 +65,59 @@ public class GithubManager { * - adds students to repository * - adds all students to assignments repository. * @param studentTeams The list of student studentTeams. + * @param teamAll The team of all teaching assistants. + * @param assignmentsRepoName The name of the assignments repo. * @throws Exception If an error occurs while initializing the github repositories. */ - public void initializeGithubRepos(List studentTeams) throws Exception { - GHTeam teamAll = this.organization.getTeamByName(this.teachingAssistantsTeamName); - - this.setupAssignmentsRepo(teamAll); + public void initializeGithubRepos(List studentTeams, TATeam teamAll, String assignmentsRepoName) throws Exception { + this.setupAssignmentsRepo(assignmentsRepoName, "fuck the police", teamAll); StudentTeam t = new StudentTeam(); Student s = new Student(3050831, "Andrew Lalis", "andrewlalisofficial@gmail.com", "andrewlalis", null); t.addMember(s); t.setId(42); - this.setupStudentTeam(t, teamAll); + this.setupStudentTeam(t, teamAll, "advoop_2018"); + // TODO: Finish this method. } /** * Sets up the organization's assignments repository, and grants permissions to all teaching assistants. + * @param assignmentsRepoName The name of the assignments repository. + * @param description The description of the repository. * @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 { + private void setupAssignmentsRepo(String assignmentsRepoName, String description, TATeam allTeachingAssistants) throws IOException { // Check if the repository already exists. - GHRepository existingRepo = this.organization.getRepository(this.assignmentsRepoName); + GHRepository existingRepo = this.organization.getRepository(assignmentsRepoName); if (existingRepo != null) { existingRepo.delete(); logger.fine("Deleted pre-existing assignments repository."); } // Create the repository. - GHCreateRepositoryBuilder builder = this.organization.createRepository(this.assignmentsRepoName); + GHCreateRepositoryBuilder builder = this.organization.createRepository(assignmentsRepoName); builder.description("Assignments repository for Advanced Object Oriented Programming"); builder.wiki(false); builder.issues(true); builder.private_(false); // TODO: Make this true for production. - builder.team(allTeachingAssistants); + builder.team(allTeachingAssistants.getGithubTeam()); builder.gitignoreTemplate("Java"); this.assignmentsRepo = builder.create(); logger.info("Created assignments repository."); - // Protect the master branch. - GHBranchProtectionBuilder protectionBuilder = this.assignmentsRepo.getBranch("master").enableProtection(); - protectionBuilder.includeAdmins(false); - protectionBuilder.restrictPushAccess(); - protectionBuilder.teamPushAccess(allTeachingAssistants); - protectionBuilder.addRequiredChecks("ci/circleci"); - protectionBuilder.enable(); - logger.fine("Protected master branch of assignments repository."); + this.assignmentsRepo = this.createRepository(assignmentsRepoName, allTeachingAssistants, description, false, true, false); + + if (this.assignmentsRepo == null) { + logger.severe("Could not create assignments repository."); + return; + } + + this.protectMasterBranch(this.assignmentsRepo, allTeachingAssistants); // Grant all teaching assistants write access. - allTeachingAssistants.add(this.assignmentsRepo, GHOrganization.Permission.ADMIN); + allTeachingAssistants.getGithubTeam().add(this.assignmentsRepo, GHOrganization.Permission.ADMIN); logger.fine("Gave admin rights to all teaching assistants in team: " + allTeachingAssistants.getName()); } @@ -139,44 +126,27 @@ public class GithubManager { * repository as well. * @param team The student team to set up. * @param taTeam The team of teaching assistants that is responsible for these students. + * @param prefix The prefix to append to the front of the repo name. * @throws IOException If an HTTP request fails. */ - @SuppressWarnings("deprecation") - private void setupStudentTeam(StudentTeam team, GHTeam taTeam) throws IOException { - String teamRepoName = team.generateUniqueName(this.studentRepoPrefix); - - Student[] students = team.getStudents(); - StringBuilder description = new StringBuilder("Group "); - description.append(team.getId()).append(": "); - - for (Student s : students) { - description.append(s.getName()).append(' '); + private void setupStudentTeam(StudentTeam team, TATeam taTeam, String prefix) throws IOException { + // First check that the assignments repo exists, otherwise no invitations can be sent. + if (this.assignmentsRepo == null) { + logger.warning("Assignments repository must be created before student repositories."); + return; } - GHCreateRepositoryBuilder builder = this.organization.createRepository(teamRepoName); - builder.team(taTeam); - builder.wiki(false); - builder.issues(true); - builder.description(description.toString()); - builder.gitignoreTemplate("Java"); - builder.private_(false); // TODO: Change this to true for production - GHRepository repo = builder.create(); - logger.info("Created repository: " + repo.getName()); + GHRepository repo = this.createRepository(team.generateUniqueName(prefix), taTeam, team.generateRepoDescription(), false, true, false); - // Protect the master branch. - GHBranchProtectionBuilder protectionBuilder = repo.getBranch("master").enableProtection(); - protectionBuilder.includeAdmins(false); - protectionBuilder.teamPushAccess(taTeam); - protectionBuilder.addRequiredChecks("ci/circleci"); - protectionBuilder.enable(); - logger.fine("Protected master branch of repository: " + repo.getName()); + if (repo == null) { + logger.severe("Repository for student team " + team.getId() + " could not be created."); + return; + } - // Create development branch. - String sha1 = repo.getBranch(repo.getDefaultBranch()).getSHA1(); - repo.createRef("refs/heads/development", sha1); - logger.fine("Created development branch of repository: " + repo.getName()); + this.protectMasterBranch(repo, taTeam); + this.createDevelopmentBranch(repo); - taTeam.add(repo, GHOrganization.Permission.ADMIN); + taTeam.getGithubTeam().add(repo, GHOrganization.Permission.ADMIN); logger.fine("Added team " + taTeam.getName() + " as admin to repository: " + repo.getName()); List users = new ArrayList<>(); @@ -234,4 +204,68 @@ public class GithubManager { logger.info("Archived repository: " + repo.getFullName()); } + /** + * Protects the master branch of a given repository, and gives admin rights to the given team. + * @param repo The repository to protect the master branch of. + * @param team The team which gets admin rights to the master branch. + */ + @SuppressWarnings("deprecation") + private void protectMasterBranch(GHRepository repo, TATeam team) { + try { + GHBranchProtectionBuilder protectionBuilder = repo.getBranch("master").enableProtection(); + protectionBuilder.includeAdmins(false); + protectionBuilder.restrictPushAccess(); + protectionBuilder.teamPushAccess(team.getGithubTeam()); + protectionBuilder.addRequiredChecks("ci/circleci"); + protectionBuilder.enable(); + logger.fine("Protected master branch of repository: " + repo.getName()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Creates a development branch for the given repository. + * @param repo The repository to create a development branch for. + */ + private void createDevelopmentBranch(GHRepository repo) { + try { + String sha1 = repo.getBranch(repo.getDefaultBranch()).getSHA1(); + repo.createRef("refs/heads/development", sha1); + logger.fine("Created development branch of repository: " + repo.getName()); + } catch (IOException e) { + logger.severe("Could not create development branch for repository: " + repo.getName() + '\n' + e.getMessage()); + e.printStackTrace(); + } + } + + /** + * Creates a new github repository. + * @param name The name of the repository. + * @param taTeam The team to give admin rights. + * @param description The description of the repository. + * @param hasWiki Whether the repo has a wiki enabled. + * @param hasIssues Whether the repo has issues enabled. + * @param isPrivate Whether or not the repository is private. + * @return The repository that was created, or + */ + private GHRepository createRepository(String name, TATeam taTeam, String description, boolean hasWiki, boolean hasIssues, boolean isPrivate){ + try { + GHCreateRepositoryBuilder builder = this.organization.createRepository(name); + builder.team(taTeam.getGithubTeam()); + builder.wiki(hasWiki); + builder.issues(hasIssues); + builder.description(description); + builder.gitignoreTemplate("Java"); + builder.private_(isPrivate); // TODO: Change this to true for production + GHRepository repo = builder.create(); + logger.fine("Created repository: " + repo.getName()); + return repo; + } catch (IOException e) { + logger.severe("Could not create repository: " + name + '\n' + e.getMessage()); + e.printStackTrace(); + return null; + } + } + } diff --git a/src/main/java/nl/andrewlalis/model/StudentTeam.java b/src/main/java/nl/andrewlalis/model/StudentTeam.java index 4243aa2..6a4a9e5 100644 --- a/src/main/java/nl/andrewlalis/model/StudentTeam.java +++ b/src/main/java/nl/andrewlalis/model/StudentTeam.java @@ -52,9 +52,22 @@ public class StudentTeam extends Team{ public String generateUniqueName(String prefix) { StringBuilder sb = new StringBuilder(prefix); sb.append("_team_").append(this.id); - for (Student s : (Student[]) this.getMembers()) { + for (Student s : this.getStudents()) { sb.append('_').append(s.getNumber()); } return sb.toString(); } + + /** + * Generates a description for the repository, based on the students' names and group number. + * @return A description for the students' repository. + */ + public String generateRepoDescription() { + StringBuilder sb = new StringBuilder(); + sb.append("Group ").append(this.id).append(": "); + for (Student s : this.getStudents()) { + sb.append(s.getName()).append(' '); + } + return sb.toString(); + } } diff --git a/src/main/java/nl/andrewlalis/model/TATeam.java b/src/main/java/nl/andrewlalis/model/TATeam.java index 0bbcdf3..2e252df 100644 --- a/src/main/java/nl/andrewlalis/model/TATeam.java +++ b/src/main/java/nl/andrewlalis/model/TATeam.java @@ -1,8 +1,7 @@ package nl.andrewlalis.model; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; +import org.kohsuke.github.GHOrganization; +import org.kohsuke.github.GHTeam; import java.util.ArrayList; import java.util.List; @@ -25,6 +24,11 @@ public class TATeam { */ private int id; + /** + * The Github team associated with this team. + */ + private GHTeam githubTeam; + /** * Constructs a team without any teaching assistant members. * @param name The name of the team. @@ -58,4 +62,11 @@ public class TATeam { return this.name; } + public GHTeam getGithubTeam() { + return this.githubTeam; + } + + public void setGithubTeam(GHTeam team) { + this.githubTeam = team; + } } diff --git a/src/main/java/nl/andrewlalis/model/database/Database.java b/src/main/java/nl/andrewlalis/model/database/Database.java index 311dde3..d8878c3 100644 --- a/src/main/java/nl/andrewlalis/model/database/Database.java +++ b/src/main/java/nl/andrewlalis/model/database/Database.java @@ -1,9 +1,6 @@ package nl.andrewlalis.model.database; -import nl.andrewlalis.model.Person; -import nl.andrewlalis.model.Student; -import nl.andrewlalis.model.TeachingAssistant; -import nl.andrewlalis.model.Team; +import nl.andrewlalis.model.*; import java.sql.Connection; import java.sql.DriverManager; @@ -24,8 +21,8 @@ public class Database { private static final int TEAM_TYPE_TA = 1; private static final int TEAM_TYPE_TA_ALL = 2; - private static final int TEAM_NONE = 0; - private static final int TEAM_TA_ALL = 1; + private static final int TEAM_NONE = 1000000; + private static final int TEAM_TA_ALL = 1000001; private static final int ERROR_TYPE_TEAM = 0; private static final int ERROR_TYPE_PERSON = 1; @@ -157,6 +154,25 @@ public class Database { } } + /** + * Stores a list of student teams in the database. + * @param teams The list of teams to store. + * @return True if successful, or false if an error occurred. + */ + public boolean storeStudentTeams(List teams) { + for (StudentTeam team : teams) { + if (!this.storeTeam(team, TEAM_TYPE_STUDENT)) { + return false; + } + for (Student student : team.getStudents()) { + if (!this.storeStudent(student, team.getId())) { + return false; + } + } + } + return true; + } + /** * Stores a student without a team. * @param student The student to store. diff --git a/src/main/java/nl/andrewlalis/ui/control/OutputTextHandler.java b/src/main/java/nl/andrewlalis/ui/control/OutputTextHandler.java index a4d6710..875c148 100644 --- a/src/main/java/nl/andrewlalis/ui/control/OutputTextHandler.java +++ b/src/main/java/nl/andrewlalis/ui/control/OutputTextHandler.java @@ -8,6 +8,9 @@ import java.util.Date; import java.util.logging.Handler; import java.util.logging.LogRecord; +/** + * A custom handler for printing log messages to the user interface text output pane. + */ public class OutputTextHandler extends Handler { /** diff --git a/src/main/java/nl/andrewlalis/ui/control/command/CommandExecutor.java b/src/main/java/nl/andrewlalis/ui/control/command/CommandExecutor.java index 222bfb3..dd5d84a 100644 --- a/src/main/java/nl/andrewlalis/ui/control/command/CommandExecutor.java +++ b/src/main/java/nl/andrewlalis/ui/control/command/CommandExecutor.java @@ -1,5 +1,6 @@ package nl.andrewlalis.ui.control.command; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; @@ -33,6 +34,7 @@ public class CommandExecutor { */ public void registerCommand(String commandName, Executable executable) { this.commands.put(commandName, executable); + logger.fine("Registered command: " + commandName); } /** @@ -40,7 +42,7 @@ public class CommandExecutor { * @param commandString The String command and any arguments that go with it. */ public void executeString(String commandString) { - String[] words = commandString.trim().toLowerCase().split(" "); + String[] words = commandString.trim().split(" "); if (words.length < 1) { logger.warning("No command supplied."); return; @@ -50,9 +52,19 @@ public class CommandExecutor { if (words.length > 1) { System.arraycopy(words, 1, args, 0, words.length - 1); } + this.executeCommand(commandName, args); + } + + /** + * Executes a command with the given name, and given arguments. + * @param commandName The name of the command. A command must be registered using registerCommand before it can be + * called here. + * @param args The list of arguments to provide to the command as needed by the executable that was registered. + */ + public void executeCommand(String commandName, String[] args) { if (this.commands.containsKey(commandName)) { + logger.info(commandName + ' ' + Arrays.toString(args)); this.commands.get(commandName).execute(args); - logger.info(commandString); } else { logger.warning(commandName + " is not a valid command."); } diff --git a/src/main/java/nl/andrewlalis/ui/control/command/executables/ArchiveRepos.java b/src/main/java/nl/andrewlalis/ui/control/command/executables/ArchiveRepos.java new file mode 100644 index 0000000..3f7368b --- /dev/null +++ b/src/main/java/nl/andrewlalis/ui/control/command/executables/ArchiveRepos.java @@ -0,0 +1,30 @@ +package nl.andrewlalis.ui.control.command.executables; + +import nl.andrewlalis.git_api.GithubManager; + +import java.io.IOException; + +/** + * Represents the action archive all repositories with a certain substring in their name. + * It takes the following arguments: + * + * 1. Organization name + * 2. Access Token + * 3. Repo substring to archive by + */ +public class ArchiveRepos extends GithubExecutable { + + @Override + protected boolean executeWithManager(GithubManager manager, String[] args) { + if (args.length < 1) { + return false; + } + try { + manager.archiveAllRepositories(args[0]); + return true; + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } +} diff --git a/src/main/java/nl/andrewlalis/ui/control/command/executables/GithubExecutable.java b/src/main/java/nl/andrewlalis/ui/control/command/executables/GithubExecutable.java new file mode 100644 index 0000000..e7362bd --- /dev/null +++ b/src/main/java/nl/andrewlalis/ui/control/command/executables/GithubExecutable.java @@ -0,0 +1,34 @@ +package nl.andrewlalis.ui.control.command.executables; + +import nl.andrewlalis.git_api.GithubManager; +import nl.andrewlalis.ui.control.command.Executable; + +/** + * Represents an executable which interacts with github, and therefore needs access to a Github + * manager to execute. + * + * Requires two arguments: + * 1. The organization name. + * 2. The organization's access token. + */ +public abstract class GithubExecutable implements Executable { + + @Override + public boolean execute(String[] args) { + if (args.length < 2) { + return false; + } + String[] extraArgs = new String[args.length-2]; + System.arraycopy(args, 2, extraArgs, 0, args.length-2); + GithubManager manager = new GithubManager(args[0], args[1]); + return this.executeWithManager(manager, extraArgs); + } + + /** + * Executes a command and provides a github manager with which to perform operations. + * @param manager The GithubManager used to perform actions on the repositories. + * @param args Any additional arguments provided to the executable. + * @return True if successful, or false otherwise. + */ + protected abstract boolean executeWithManager(GithubManager manager, String[] args); +} diff --git a/src/main/java/nl/andrewlalis/ui/control/command/executables/ReadStudentsFileToDB.java b/src/main/java/nl/andrewlalis/ui/control/command/executables/ReadStudentsFileToDB.java new file mode 100644 index 0000000..2baf651 --- /dev/null +++ b/src/main/java/nl/andrewlalis/ui/control/command/executables/ReadStudentsFileToDB.java @@ -0,0 +1,36 @@ +package nl.andrewlalis.ui.control.command.executables; + +import nl.andrewlalis.model.StudentTeam; +import nl.andrewlalis.model.database.Database; +import nl.andrewlalis.ui.control.command.Executable; +import nl.andrewlalis.util.FileUtils; + +import java.util.List; + +/** + * Execute this class to read students from a supplied filename and teamsize, and store their + * information in the database. + */ +public class ReadStudentsFileToDB implements Executable { + + /** + * The database used to store the students. + */ + private Database db; + + public ReadStudentsFileToDB(Database db) { + this.db = db; + } + + + @Override + public boolean execute(String[] args) { + if (args.length < 2) { + return false; + } + String filename = args[0]; + int teamSize = Integer.parseUnsignedInt(args[1]); + List teams = FileUtils.getStudentTeamsFromCSV(filename, teamSize); + return this.db.storeStudentTeams(teams); + } +} diff --git a/src/main/java/nl/andrewlalis/ui/control/listeners/CommandFieldKeyListener.java b/src/main/java/nl/andrewlalis/ui/control/listeners/CommandFieldKeyListener.java index a90f909..d68ac1e 100644 --- a/src/main/java/nl/andrewlalis/ui/control/listeners/CommandFieldKeyListener.java +++ b/src/main/java/nl/andrewlalis/ui/control/listeners/CommandFieldKeyListener.java @@ -15,7 +15,7 @@ public class CommandFieldKeyListener implements KeyListener { /** * This is responsible for parsing and running entered commands. */ - CommandExecutor executor; + private CommandExecutor executor; public CommandFieldKeyListener(CommandExecutor executor) { this.executor = executor; diff --git a/src/main/java/nl/andrewlalis/ui/view/InitializerApp.java b/src/main/java/nl/andrewlalis/ui/view/InitializerApp.java index 7a3b614..c9890a7 100644 --- a/src/main/java/nl/andrewlalis/ui/view/InitializerApp.java +++ b/src/main/java/nl/andrewlalis/ui/view/InitializerApp.java @@ -6,6 +6,7 @@ import nl.andrewlalis.ui.control.OutputTextHandler; import javax.swing.*; import java.awt.*; +import java.util.logging.Level; import java.util.logging.Logger; /** @@ -28,6 +29,13 @@ public class InitializerApp extends JFrame { */ private OutputTextPane outputTextPane; + private JTextField organizationField = new JTextField(); + private JTextField accessTokenField = new JTextField(); + private JTextField assignmentsRepoField = new JTextField(); + private JTextField teachingAssistantsField = new JTextField(); + private JTextField studentRepoField = new JTextField(); + private JTextField teamSizeField = new JTextField(); + /** * The executor responsible for performing meaningful actions. */ @@ -53,7 +61,9 @@ public class InitializerApp extends JFrame { */ private void initLoggingHandler() { Logger logger = Logger.getGlobal(); - logger.addHandler(new OutputTextHandler(this.outputTextPane)); + OutputTextHandler handler = new OutputTextHandler(this.outputTextPane); + handler.setLevel(Level.FINE); + logger.addHandler(handler); } /** @@ -68,12 +78,42 @@ public class InitializerApp extends JFrame { mainPanel.add(this.initCommandPanel(), BorderLayout.CENTER); mainPanel.add(this.initRepoPanel(), BorderLayout.WEST); + mainPanel.add(this.initGithubManagerPanel(), BorderLayout.EAST); this.setContentPane(mainPanel); this.initLoggingHandler(); } + /** + * @return A JPanel containing input for all fields needed to connect to github, plus some commonly used buttons + * which perform actions, as shortcuts for command actions. + */ + private JPanel initGithubManagerPanel() { + JPanel githubManagerPanel = new JPanel(new BorderLayout()); + + // Information input (org name, key, etc.) + JPanel infoInputPanel = new JPanel(); + infoInputPanel.setLayout(new BoxLayout(infoInputPanel, BoxLayout.PAGE_AXIS)); + + infoInputPanel.add(generateTextFieldPanel("Organization Name", this.organizationField)); + this.organizationField.setText("InitializerTesting"); + infoInputPanel.add(generateTextFieldPanel("Access Token", this.accessTokenField)); + this.accessTokenField.setText("d3699963f23cee85fe44c42f66057acc98c9ec7a"); + infoInputPanel.add(generateTextFieldPanel("Assignments Repo Name", this.assignmentsRepoField)); + this.assignmentsRepoField.setText("assignments_2018"); + infoInputPanel.add(generateTextFieldPanel("TA-All Team Name", this.teachingAssistantsField)); + this.teachingAssistantsField.setText("teaching-assistants"); + infoInputPanel.add(generateTextFieldPanel("Student Repo Prefix", this.studentRepoField)); + this.studentRepoField.setText("advoop_2018"); + infoInputPanel.add(generateTextFieldPanel("Team Size", this.teamSizeField)); + this.teamSizeField.setText("2"); + + githubManagerPanel.add(infoInputPanel, BorderLayout.NORTH); + + return githubManagerPanel; + } + /** * @return A JPanel containing the command prompt field and output text pane. */ @@ -83,7 +123,7 @@ public class InitializerApp extends JFrame { this.outputTextPane = new OutputTextPane(); JScrollPane scrollPane = new JScrollPane(this.outputTextPane); scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); - scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); // Text enter field and label. JPanel textEnterPanel = new JPanel(new BorderLayout()); textEnterPanel.setBorder(BorderFactory.createLoweredBevelBorder()); @@ -111,4 +151,18 @@ public class InitializerApp extends JFrame { return repoPanel; } + /** + * Generates a text input field panel. + * @param labelText The text for the label above the panel. + * @param textField A reference to the text field that is used in the panel. + * @return A JPanel containing the label and text field. + */ + private JPanel generateTextFieldPanel(String labelText, JTextField textField) { + JPanel newPanel = new JPanel(new BorderLayout()); + newPanel.add(new JLabel(labelText), BorderLayout.NORTH); + newPanel.add(textField); + newPanel.setBorder(BorderFactory.createEmptyBorder(5, 2, 5, 2)); + return newPanel; + } + } diff --git a/src/main/java/nl/andrewlalis/util/FileUtils.java b/src/main/java/nl/andrewlalis/util/FileUtils.java index f5cf3db..972ffb1 100644 --- a/src/main/java/nl/andrewlalis/util/FileUtils.java +++ b/src/main/java/nl/andrewlalis/util/FileUtils.java @@ -47,13 +47,13 @@ public class FileUtils { * @return A list of student teams. */ public static List getStudentTeamsFromCSV(String filename, int teamSize) { - List studentTeams = null; + List studentTeams; try { studentTeams = TeamGenerator.generateFromCSV(filename, teamSize); logger.fine("Teams created:\n" + studentTeams); return studentTeams; } catch (IOException | ArrayIndexOutOfBoundsException e) { - logger.severe("Unable to generate studentTeams from CSV file, exiting."); + logger.severe("Unable to generate studentTeams from CSV file, exiting. " + e.getMessage()); System.exit(1); return null; } diff --git a/src/main/resources/sql/insert/types.sql b/src/main/resources/sql/insert/types.sql index 45ab89d..3940146 100644 --- a/src/main/resources/sql/insert/types.sql +++ b/src/main/resources/sql/insert/types.sql @@ -10,8 +10,8 @@ VALUES (0, 'student_team'), (3, 'none'); INSERT INTO teams (id, team_type_id) -VALUES (0, 3), -- None team for all students or TA's without a team. - (1, 2); -- Team for all teaching assistants. +VALUES (1000000, 3), -- None team for all students or TA's without a team. + (1000001, 2); -- Team for all teaching assistants. INSERT INTO error_types (id, name) VALUES (0, 'team_error'),