Improvements and new version in development #5
			
				
			
		
		
		
	
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							|  | @ -1,14 +1,12 @@ | ||||||
| package nl.andrewlalis; | package nl.andrewlalis; | ||||||
| 
 | 
 | ||||||
| import nl.andrewlalis.model.Student; | import nl.andrewlalis.command.CommandExecutor; | ||||||
| import nl.andrewlalis.model.database.DbUtil; | import nl.andrewlalis.command.executables.*; | ||||||
| import nl.andrewlalis.ui.control.command.CommandExecutor; | import nl.andrewlalis.git_api.GithubManager; | ||||||
| import nl.andrewlalis.ui.control.command.executables.*; |  | ||||||
| import nl.andrewlalis.ui.view.InitializerApp; | import nl.andrewlalis.ui.view.InitializerApp; | ||||||
|  | import nl.andrewlalis.ui.view.StartView; | ||||||
| import nl.andrewlalis.util.CommandLine; | import nl.andrewlalis.util.CommandLine; | ||||||
| import nl.andrewlalis.util.Logging; | import nl.andrewlalis.util.Logging; | ||||||
| import org.hibernate.Session; |  | ||||||
| import org.hibernate.SessionFactory; |  | ||||||
| 
 | 
 | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.logging.Logger; | import java.util.logging.Logger; | ||||||
|  | @ -51,12 +49,15 @@ public class Main { | ||||||
|                 "© Andrew Lalis (2018), All rights reserved.\n" + |                 "© Andrew Lalis (2018), All rights reserved.\n" + | ||||||
|                 "Program initialized."); |                 "Program initialized."); | ||||||
| 
 | 
 | ||||||
|         SessionFactory factory = DbUtil.getSessionFactory(); |         GithubManager manager = new GithubManager(); | ||||||
|         Session session = factory.openSession(); |         StartView startView = new StartView(manager); | ||||||
|         session.beginTransaction(); | 
 | ||||||
|         System.out.println(session.save(new Student(1, "a", "a@e.com", "git", null))); | //        SessionFactory factory = DbUtil.getSessionFactory(); | ||||||
|         session.getTransaction().commit(); | //        Session session = factory.openSession(); | ||||||
|         session.close(); | //        session.beginTransaction(); | ||||||
|  | //        System.out.println(session.save(new Student(1, "a", "a@e.com", "git", null))); | ||||||
|  | //        session.getTransaction().commit(); | ||||||
|  | //        session.close(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| package nl.andrewlalis.ui.control.command; | package nl.andrewlalis.command; | ||||||
| 
 | 
 | ||||||
| import nl.andrewlalis.ui.control.command.executables.ExecutableContext; | import nl.andrewlalis.command.executables.ExecutableContext; | ||||||
| 
 | 
 | ||||||
| import java.util.*; | import java.util.*; | ||||||
| import java.util.logging.Logger; | import java.util.logging.Logger; | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| package nl.andrewlalis.ui.control.command; | package nl.andrewlalis.command; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Classes which implement this interface tell that they may be 'executed', either via command-line, or through the use |  * Classes which implement this interface tell that they may be 'executed', either via command-line, or through the use | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| package nl.andrewlalis.ui.control.command.executables; | package nl.andrewlalis.command.executables; | ||||||
| 
 | 
 | ||||||
| import nl.andrewlalis.git_api.GithubManager; | import nl.andrewlalis.git_api.GithubManager; | ||||||
| 
 | 
 | ||||||
|  | @ -1,8 +1,8 @@ | ||||||
| package nl.andrewlalis.ui.control.command.executables; | package nl.andrewlalis.command.executables; | ||||||
| 
 | 
 | ||||||
| import nl.andrewlalis.git_api.GithubManager; | import nl.andrewlalis.git_api.GithubManager; | ||||||
| import nl.andrewlalis.ui.view.dialogs.DefineTaTeamsDialog; |  | ||||||
| import nl.andrewlalis.ui.view.InitializerApp; | import nl.andrewlalis.ui.view.InitializerApp; | ||||||
|  | import nl.andrewlalis.ui.view.dialogs.DefineTaTeamsDialog; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * This executable is slightly different from the others, in that it opens up a user interface to make editing TA teams |  * This executable is slightly different from the others, in that it opens up a user interface to make editing TA teams | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| package nl.andrewlalis.ui.control.command.executables; | package nl.andrewlalis.command.executables; | ||||||
| 
 | 
 | ||||||
| import nl.andrewlalis.git_api.GithubManager; | import nl.andrewlalis.git_api.GithubManager; | ||||||
| import nl.andrewlalis.model.StudentTeam; | import nl.andrewlalis.model.StudentTeam; | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| package nl.andrewlalis.ui.control.command.executables; | package nl.andrewlalis.command.executables; | ||||||
| 
 | 
 | ||||||
| import nl.andrewlalis.git_api.GithubManager; | import nl.andrewlalis.git_api.GithubManager; | ||||||
| 
 | 
 | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| package nl.andrewlalis.ui.control.command.executables; | package nl.andrewlalis.command.executables; | ||||||
| 
 | 
 | ||||||
| import nl.andrewlalis.ui.control.command.Executable; | import nl.andrewlalis.command.Executable; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * An object to record a specific executable's execution context (args given), with the ability to re-run the executable |  * An object to record a specific executable's execution context (args given), with the ability to re-run the executable | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| package nl.andrewlalis.ui.control.command.executables; | package nl.andrewlalis.command.executables; | ||||||
| 
 | 
 | ||||||
| import nl.andrewlalis.git_api.GithubManager; | import nl.andrewlalis.git_api.GithubManager; | ||||||
| 
 | 
 | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| package nl.andrewlalis.ui.control.command.executables; | package nl.andrewlalis.command.executables; | ||||||
| 
 | 
 | ||||||
|  | import nl.andrewlalis.command.Executable; | ||||||
| import nl.andrewlalis.git_api.GithubManager; | 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 |  * Represents an executable which interacts with github, and therefore needs access to a Github | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| package nl.andrewlalis.ui.control.command.executables; | package nl.andrewlalis.command.executables; | ||||||
| 
 | 
 | ||||||
|  | import nl.andrewlalis.command.Executable; | ||||||
| import nl.andrewlalis.model.error.Error; | import nl.andrewlalis.model.error.Error; | ||||||
| import nl.andrewlalis.ui.control.command.Executable; |  | ||||||
| import nl.andrewlalis.ui.view.InitializerApp; | import nl.andrewlalis.ui.view.InitializerApp; | ||||||
| 
 | 
 | ||||||
| import java.util.logging.Logger; | import java.util.logging.Logger; | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| package nl.andrewlalis.ui.control.command.executables; | package nl.andrewlalis.command.executables; | ||||||
| 
 | 
 | ||||||
| import nl.andrewlalis.git_api.GithubManager; | import nl.andrewlalis.git_api.GithubManager; | ||||||
| import org.kohsuke.github.GHRepository; | import org.kohsuke.github.GHRepository; | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| package nl.andrewlalis.ui.control.command.executables; | package nl.andrewlalis.command.executables; | ||||||
| 
 | 
 | ||||||
|  | import nl.andrewlalis.command.Executable; | ||||||
| import nl.andrewlalis.model.StudentTeam; | import nl.andrewlalis.model.StudentTeam; | ||||||
| import nl.andrewlalis.ui.control.command.Executable; |  | ||||||
| import nl.andrewlalis.ui.view.InitializerApp; | import nl.andrewlalis.ui.view.InitializerApp; | ||||||
| import nl.andrewlalis.util.FileUtils; | import nl.andrewlalis.util.FileUtils; | ||||||
| 
 | 
 | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| package nl.andrewlalis.ui.control.command.executables; | package nl.andrewlalis.command.executables; | ||||||
| 
 | 
 | ||||||
| import nl.andrewlalis.git_api.GithubManager; | import nl.andrewlalis.git_api.GithubManager; | ||||||
| import nl.andrewlalis.model.StudentTeam; | import nl.andrewlalis.model.StudentTeam; | ||||||
|  | @ -31,6 +31,7 @@ public class GithubManager { | ||||||
|     private GitHub github; |     private GitHub github; | ||||||
|     private GHOrganization organization; |     private GHOrganization organization; | ||||||
|     private String accessToken; |     private String accessToken; | ||||||
|  |     private String organizationName; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * The logger for outputting debug info. |      * The logger for outputting debug info. | ||||||
|  | @ -40,14 +41,82 @@ public class GithubManager { | ||||||
|         logger.setParent(Logger.getGlobal()); |         logger.setParent(Logger.getGlobal()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Creates an empty github manager, which at this point, essentially just allocates the object in memory. | ||||||
|  |      */ | ||||||
|  |     public GithubManager() { | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public GithubManager(String organizationName, String accessToken) { |     public GithubManager(String organizationName, String accessToken) { | ||||||
|  |         this.organizationName = organizationName; | ||||||
|         this.accessToken = accessToken; |         this.accessToken = accessToken; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Gets the organization that this manager manages. | ||||||
|  |      * @return The Organization object that this manager was constructed for. | ||||||
|  |      * @throws IOException If the organization does not exist or some other error occurs. | ||||||
|  |      */ | ||||||
|  |     private GHOrganization getOrganization() throws IOException { | ||||||
|  |         if (this.github == null || this.organization == null) { | ||||||
|  |             this.github = GitHub.connectUsingOAuth(this.accessToken); | ||||||
|  |             this.organization = this.github.getOrganization(this.organizationName); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return this.organization; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Determine if the manager is currently connected to github with the current organization name and access token. | ||||||
|  |      * @return True if the manager is connected, or false otherwise. | ||||||
|  |      */ | ||||||
|  |     public boolean validate() { | ||||||
|         try { |         try { | ||||||
|             this.github = GitHub.connectUsingOAuth(accessToken); |             this.organization = this.getOrganization(); | ||||||
|             this.organization = this.github.getOrganization(organizationName); |             return this.organization != null; | ||||||
|         } catch (IOException e) { |         } catch (IOException e) { | ||||||
|             logger.severe("Unable to make a GithubManager with organization name: " + organizationName + " and access token: " + accessToken); |             return false; | ||||||
|             e.printStackTrace(); |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setOrganizationName(String name) { | ||||||
|  |         this.organizationName = name; | ||||||
|  |         this.github = null; | ||||||
|  |         this.organization = null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setAccessToken(String token) { | ||||||
|  |         this.accessToken = token; | ||||||
|  |         this.github = null; | ||||||
|  |         this.organization = null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Determines if a repository exists in the current organization. | ||||||
|  |      * @param repoName The name of the repository. | ||||||
|  |      * @return True if the repository exists, false otherwise. | ||||||
|  |      */ | ||||||
|  |     public boolean repoExists(String repoName) { | ||||||
|  |         try { | ||||||
|  |             GHRepository repo = this.getOrganization().getRepository(repoName); | ||||||
|  |             return repo != null; | ||||||
|  |         } catch (IOException e) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Determines if a team exists in the current organization. | ||||||
|  |      * @param teamName The name of the team. | ||||||
|  |      * @return True if the team exists, false otherwise. | ||||||
|  |      */ | ||||||
|  |     public boolean teamExists(String teamName) { | ||||||
|  |         try { | ||||||
|  |             GHTeam team = this.getOrganization().getTeamByName(teamName); | ||||||
|  |             return team != null; | ||||||
|  |         } catch (IOException e) { | ||||||
|  |             return false; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -59,7 +128,7 @@ public class GithubManager { | ||||||
|     public List<GHRepository> listReposWithPrefix(String substring) { |     public List<GHRepository> listReposWithPrefix(String substring) { | ||||||
|         List<GHRepository> repos = new ArrayList<>(); |         List<GHRepository> repos = new ArrayList<>(); | ||||||
|         try { |         try { | ||||||
|             List<GHRepository> allRepos = this.organization.listRepositories().asList(); |             List<GHRepository> allRepos = this.getOrganization().listRepositories().asList(); | ||||||
|             for (GHRepository repo : allRepos) { |             for (GHRepository repo : allRepos) { | ||||||
|                 if (repo.getName().contains(substring)) { |                 if (repo.getName().contains(substring)) { | ||||||
|                     repos.add(repo); |                     repos.add(repo); | ||||||
|  | @ -81,7 +150,7 @@ public class GithubManager { | ||||||
|     public GHRepository getRepository(String name) { |     public GHRepository getRepository(String name) { | ||||||
|         System.out.println(name); |         System.out.println(name); | ||||||
|         try { |         try { | ||||||
|             return this.organization.getRepository(name); |             return this.getOrganization().getRepository(name); | ||||||
|         } catch (IOException e) { |         } catch (IOException e) { | ||||||
|             logger.severe("No repository with name: " + name + " exists."); |             logger.severe("No repository with name: " + name + " exists."); | ||||||
|             e.printStackTrace(); |             e.printStackTrace(); | ||||||
|  | @ -97,7 +166,7 @@ public class GithubManager { | ||||||
|         List<TATeam> teams = new ArrayList<>(); |         List<TATeam> teams = new ArrayList<>(); | ||||||
|         try { |         try { | ||||||
|             Random rand = new Random(); |             Random rand = new Random(); | ||||||
|             for (Map.Entry<String, GHTeam> entry : this.organization.getTeams().entrySet()) { |             for (Map.Entry<String, GHTeam> entry : this.getOrganization().getTeams().entrySet()) { | ||||||
|                 TATeam team = new TATeam(entry.getKey(), entry.getValue().getId()); |                 TATeam team = new TATeam(entry.getKey(), entry.getValue().getId()); | ||||||
|                 team.setGithubTeam(entry.getValue()); |                 team.setGithubTeam(entry.getValue()); | ||||||
|                 for (GHUser user : entry.getValue().listMembers().asList()) { |                 for (GHUser user : entry.getValue().listMembers().asList()) { | ||||||
|  | @ -119,7 +188,7 @@ public class GithubManager { | ||||||
|     public List<TeachingAssistant> getMembers() { |     public List<TeachingAssistant> getMembers() { | ||||||
|         List<TeachingAssistant> teachingAssistants = new ArrayList<>(); |         List<TeachingAssistant> teachingAssistants = new ArrayList<>(); | ||||||
|         try { |         try { | ||||||
|             for (GHUser member : this.organization.listMembers().asList()) { |             for (GHUser member : this.getOrganization().listMembers().asList()) { | ||||||
|                 teachingAssistants.add(new TeachingAssistant(-1, member.getName(), member.getEmail(), member.getLogin())); |                 teachingAssistants.add(new TeachingAssistant(-1, member.getName(), member.getEmail(), member.getLogin())); | ||||||
|             } |             } | ||||||
|         } catch (IOException e) { |         } catch (IOException e) { | ||||||
|  | @ -137,9 +206,9 @@ public class GithubManager { | ||||||
|      * @throws IOException If an HTTP request failed. |      * @throws IOException If an HTTP request failed. | ||||||
|      */ |      */ | ||||||
|     public void setupAssignmentsRepo(String assignmentsRepoName, String description, String allTeachingAssistants) throws IOException { |     public void setupAssignmentsRepo(String assignmentsRepoName, String description, String allTeachingAssistants) throws IOException { | ||||||
|         GHTeam team = this.organization.getTeamByName(allTeachingAssistants); |         GHTeam team = this.getOrganization().getTeamByName(allTeachingAssistants); | ||||||
|         // Check if the repository already exists. |         // Check if the repository already exists. | ||||||
|         GHRepository existingRepo = this.organization.getRepository(assignmentsRepoName); |         GHRepository existingRepo = this.getOrganization().getRepository(assignmentsRepoName); | ||||||
|         if (existingRepo != null) { |         if (existingRepo != null) { | ||||||
|             existingRepo.delete(); |             existingRepo.delete(); | ||||||
|             logger.fine("Deleted pre-existing assignments repository."); |             logger.fine("Deleted pre-existing assignments repository."); | ||||||
|  | @ -174,9 +243,10 @@ public class GithubManager { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         GHRepository repo = this.createRepository(team.generateUniqueName(prefix), taTeam.getGithubTeam(), team.generateRepoDescription(), false, true, true); |         GHRepository repo; | ||||||
| 
 |         try { | ||||||
|         if (repo == null) { |             repo = this.createRepository(team.generateUniqueName(prefix), taTeam.getGithubTeam(), team.generateRepoDescription(), false, true, true); | ||||||
|  |         } catch (IOException e) { | ||||||
|             logger.severe("Repository for student team " + team.getNumber() + " could not be created."); |             logger.severe("Repository for student team " + team.getNumber() + " could not be created."); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  | @ -195,17 +265,22 @@ public class GithubManager { | ||||||
|      * @param substring The substring which repository names should contain to be deleted. |      * @param substring The substring which repository names should contain to be deleted. | ||||||
|      */ |      */ | ||||||
|     public void deleteAllRepositories(String substring) { |     public void deleteAllRepositories(String substring) { | ||||||
|         List<GHRepository> repositories = this.organization.listRepositories().asList(); |         try { | ||||||
|         for (GHRepository repo : repositories) { |             List<GHRepository> repositories = this.getOrganization().listRepositories().asList(); | ||||||
|             if (repo.getName().contains(substring)) { |             for (GHRepository repo : repositories) { | ||||||
|                 try { |                 if (repo.getName().contains(substring)) { | ||||||
|                     repo.delete(); |                     try { | ||||||
|                     logger.info("Deleted repository: " + repo.getName()); |                         repo.delete(); | ||||||
|                 } catch (IOException e) { |                         logger.info("Deleted repository: " + repo.getName()); | ||||||
|                     logger.severe("Could not delete repository: " + repo.getName()); |                     } catch (IOException e) { | ||||||
|                     e.printStackTrace(); |                         logger.severe("Could not delete repository: " + repo.getName()); | ||||||
|  |                         e.printStackTrace(); | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |         } catch (IOException e) { | ||||||
|  |             logger.severe("Could not get Organization for listing repositories."); | ||||||
|  |             e.printStackTrace(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -214,11 +289,16 @@ public class GithubManager { | ||||||
|      * @param sub Any repository containing this substring will be archived. |      * @param sub Any repository containing this substring will be archived. | ||||||
|      */ |      */ | ||||||
|     public void archiveAllRepositories(String sub) { |     public void archiveAllRepositories(String sub) { | ||||||
|         List<GHRepository> repositories = this.organization.listRepositories().asList(); |         try { | ||||||
|         for (GHRepository repo : repositories) { |             List<GHRepository> repositories = this.getOrganization().listRepositories().asList(); | ||||||
|             if (repo.getName().contains(sub)) { |             for (GHRepository repo : repositories) { | ||||||
|                 archiveRepository(repo); |                 if (repo.getName().contains(sub)) { | ||||||
|  |                     archiveRepository(repo); | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|  |         } catch (IOException e) { | ||||||
|  |             logger.severe("Could not get Organization for listing repositories."); | ||||||
|  |             e.printStackTrace(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -339,25 +419,20 @@ public class GithubManager { | ||||||
|      * @param hasWiki Whether the repo has a wiki enabled. |      * @param hasWiki Whether the repo has a wiki enabled. | ||||||
|      * @param hasIssues Whether the repo has issues enabled. |      * @param hasIssues Whether the repo has issues enabled. | ||||||
|      * @param isPrivate Whether or not the repository is private. |      * @param isPrivate Whether or not the repository is private. | ||||||
|      * @return The repository that was created, or null if it could not be created. |      * @return The repository that was created. | ||||||
|  |      * @throws IOException If an exception occurred while sending a request. | ||||||
|      */ |      */ | ||||||
|     private GHRepository createRepository(String name, GHTeam taTeam, String description, boolean hasWiki, boolean hasIssues, boolean isPrivate){ |     private GHRepository createRepository(String name, GHTeam taTeam, String description, boolean hasWiki, boolean hasIssues, boolean isPrivate) throws IOException { | ||||||
|         try { |         GHCreateRepositoryBuilder builder = this.getOrganization().createRepository(name); | ||||||
|             GHCreateRepositoryBuilder builder = this.organization.createRepository(name); |         builder.team(taTeam); | ||||||
|             builder.team(taTeam); |         builder.wiki(hasWiki); | ||||||
|             builder.wiki(hasWiki); |         builder.issues(hasIssues); | ||||||
|             builder.issues(hasIssues); |         builder.description(description); | ||||||
|             builder.description(description); |         builder.gitignoreTemplate("Java"); | ||||||
|             builder.gitignoreTemplate("Java"); |         builder.private_(isPrivate); | ||||||
|             builder.private_(isPrivate); |         GHRepository repo = builder.create(); | ||||||
|             GHRepository repo = builder.create(); |         logger.fine("Created repository: " + repo.getName()); | ||||||
|             logger.fine("Created repository: " + repo.getName()); |         return repo; | ||||||
|             return repo; |  | ||||||
|         } catch (IOException e) { |  | ||||||
|             logger.severe("Could not create repository: " + name); |  | ||||||
|             e.printStackTrace(); |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,9 +0,0 @@ | ||||||
| package nl.andrewlalis.model; |  | ||||||
| 
 |  | ||||||
| public abstract class DatabaseObject { |  | ||||||
| 
 |  | ||||||
|     public abstract DatabaseObject retrieve(); |  | ||||||
| 
 |  | ||||||
|     public abstract boolean store(); |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| package nl.andrewlalis.ui.control.listeners; | package nl.andrewlalis.ui.control.listeners; | ||||||
| 
 | 
 | ||||||
| import nl.andrewlalis.ui.control.command.CommandExecutor; | import nl.andrewlalis.command.CommandExecutor; | ||||||
| import nl.andrewlalis.ui.view.InitializerApp; | import nl.andrewlalis.ui.view.InitializerApp; | ||||||
| 
 | 
 | ||||||
| import javax.swing.*; | import javax.swing.*; | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| package nl.andrewlalis.ui.control.listeners; | package nl.andrewlalis.ui.control.listeners; | ||||||
| 
 | 
 | ||||||
| import nl.andrewlalis.ui.control.command.CommandExecutor; | import nl.andrewlalis.command.CommandExecutor; | ||||||
| 
 | 
 | ||||||
| import javax.swing.*; | import javax.swing.*; | ||||||
| import java.awt.event.KeyEvent; | import java.awt.event.KeyEvent; | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| package nl.andrewlalis.ui.control.listeners; | package nl.andrewlalis.ui.control.listeners; | ||||||
| 
 | 
 | ||||||
| import nl.andrewlalis.ui.control.command.CommandExecutor; | import nl.andrewlalis.command.CommandExecutor; | ||||||
| import nl.andrewlalis.ui.view.InitializerApp; | import nl.andrewlalis.ui.view.InitializerApp; | ||||||
| 
 | 
 | ||||||
| import java.awt.event.ActionEvent; | import java.awt.event.ActionEvent; | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| package nl.andrewlalis.ui.control.listeners; | package nl.andrewlalis.ui.control.listeners; | ||||||
| 
 | 
 | ||||||
| import nl.andrewlalis.ui.control.command.CommandExecutor; | import nl.andrewlalis.command.CommandExecutor; | ||||||
| import nl.andrewlalis.ui.view.InitializerApp; | import nl.andrewlalis.ui.view.InitializerApp; | ||||||
| 
 | 
 | ||||||
| import java.awt.event.ActionEvent; | import java.awt.event.ActionEvent; | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| package nl.andrewlalis.ui.control.listeners; | package nl.andrewlalis.ui.control.listeners; | ||||||
| 
 | 
 | ||||||
| import nl.andrewlalis.ui.control.command.CommandExecutor; | import nl.andrewlalis.command.CommandExecutor; | ||||||
| import nl.andrewlalis.ui.view.InitializerApp; | import nl.andrewlalis.ui.view.InitializerApp; | ||||||
| 
 | 
 | ||||||
| import javax.swing.*; | import javax.swing.*; | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| package nl.andrewlalis.ui.control.listeners; | package nl.andrewlalis.ui.control.listeners; | ||||||
| 
 | 
 | ||||||
| import nl.andrewlalis.ui.control.command.CommandExecutor; | import nl.andrewlalis.command.CommandExecutor; | ||||||
| import nl.andrewlalis.ui.view.InitializerApp; | import nl.andrewlalis.ui.view.InitializerApp; | ||||||
| 
 | 
 | ||||||
| import java.awt.event.ActionListener; | import java.awt.event.ActionListener; | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| package nl.andrewlalis.ui.control.listeners; | package nl.andrewlalis.ui.control.listeners; | ||||||
| 
 | 
 | ||||||
| import nl.andrewlalis.ui.control.command.CommandExecutor; | import nl.andrewlalis.command.CommandExecutor; | ||||||
| import nl.andrewlalis.ui.view.InitializerApp; | import nl.andrewlalis.ui.view.InitializerApp; | ||||||
| 
 | 
 | ||||||
| import javax.swing.*; | import javax.swing.*; | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| package nl.andrewlalis.ui.control.listeners; | package nl.andrewlalis.ui.control.listeners; | ||||||
| 
 | 
 | ||||||
| import nl.andrewlalis.ui.control.command.CommandExecutor; | import nl.andrewlalis.command.CommandExecutor; | ||||||
| import nl.andrewlalis.ui.view.InitializerApp; | import nl.andrewlalis.ui.view.InitializerApp; | ||||||
| 
 | 
 | ||||||
| import javax.swing.*; | import javax.swing.*; | ||||||
|  |  | ||||||
|  | @ -0,0 +1,68 @@ | ||||||
|  | package nl.andrewlalis.ui.control.listeners; | ||||||
|  | 
 | ||||||
|  | import nl.andrewlalis.ui.view.AbstractView; | ||||||
|  | 
 | ||||||
|  | import java.awt.event.ActionEvent; | ||||||
|  | import java.awt.event.ActionListener; | ||||||
|  | import java.awt.event.WindowAdapter; | ||||||
|  | import java.awt.event.WindowEvent; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * The ViewChangeListener is attached to buttons which should change the view to a new view. With this listener, one | ||||||
|  |  * needs to simply give the previous view, and the next view, and | ||||||
|  |  */ | ||||||
|  | public class ViewChangeListener implements ActionListener { | ||||||
|  | 
 | ||||||
|  |     protected AbstractView previousView; | ||||||
|  |     protected AbstractView newView; | ||||||
|  | 
 | ||||||
|  |     public ViewChangeListener(AbstractView previousView, AbstractView newView) { | ||||||
|  |         this.previousView = previousView; | ||||||
|  |         this.newView = newView; | ||||||
|  |         this.newView.addWindowListener(new WindowAdapter() { | ||||||
|  |             @Override | ||||||
|  |             public void windowClosing(WindowEvent windowEvent) { | ||||||
|  |                 back(); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * This method is called just before the view is changed. | ||||||
|  |      * @return True if the change should happen, or false if some validation or check prevents the user from moving to | ||||||
|  |      * the next view. | ||||||
|  |      */ | ||||||
|  |     protected boolean beforeChange() { | ||||||
|  |         // Child classes can implement extra behavior here. | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Defines some default behavior for switching to a new view. | ||||||
|  |      * @param actionEvent The event which triggered this action. | ||||||
|  |      */ | ||||||
|  |     @Override | ||||||
|  |     public void actionPerformed(ActionEvent actionEvent) { | ||||||
|  |         if (this.beforeChange()) { | ||||||
|  |             this.forward(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Goes to the new view, and hides the previous view. | ||||||
|  |      */ | ||||||
|  |     private void forward() { | ||||||
|  |         this.previousView.setVisible(false); | ||||||
|  |         this.newView.reset(); | ||||||
|  |         this.newView.setVisible(true); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Goes 'back in time', or rather, hides the current view and moves back to the one which sent us here. | ||||||
|  |      */ | ||||||
|  |     private void back() { | ||||||
|  |         this.previousView.reset(); | ||||||
|  |         this.previousView.setVisible(true); | ||||||
|  |         this.newView.setVisible(false); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,59 @@ | ||||||
|  | package nl.andrewlalis.ui.control.listeners.create_assignments_view; | ||||||
|  | 
 | ||||||
|  | import nl.andrewlalis.git_api.GithubManager; | ||||||
|  | import nl.andrewlalis.ui.control.listeners.ViewChangeListener; | ||||||
|  | import nl.andrewlalis.ui.view.AbstractView; | ||||||
|  | import nl.andrewlalis.ui.view.CreateAssignmentsView; | ||||||
|  | 
 | ||||||
|  | import javax.swing.*; | ||||||
|  | import java.io.IOException; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Listens for when the user clicks 'next' in the CreateAssignmentsView. This listener is responsible for checking that | ||||||
|  |  * the user enters a correct repository name, or if not, asks if the user wishes to create the repository with that | ||||||
|  |  * name. | ||||||
|  |  */ | ||||||
|  | public class NextListener extends ViewChangeListener { | ||||||
|  | 
 | ||||||
|  |     public NextListener(AbstractView previousView, AbstractView newView) { | ||||||
|  |         super(previousView, newView); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Validate that the repository the user has entered exists in the organization. | ||||||
|  |      * @return True if the repository exists, or if the user creates a repository with that name, or false if an | ||||||
|  |      * Assignments repository was not created. | ||||||
|  |      */ | ||||||
|  |     @Override | ||||||
|  |     protected boolean beforeChange() { | ||||||
|  |         CreateAssignmentsView assignmentsView = (CreateAssignmentsView) this.previousView; | ||||||
|  |         String repoName = assignmentsView.getRepositoryName(); | ||||||
|  |         GithubManager manager = assignmentsView.getGithubManager(); | ||||||
|  |         if (manager.repoExists(repoName)) { | ||||||
|  |             return true; | ||||||
|  |         } else { | ||||||
|  |             int reply = JOptionPane.showConfirmDialog( | ||||||
|  |                     assignmentsView, | ||||||
|  |                     "The repository you gave does not exist.\nWould you like to create it?", | ||||||
|  |                     "Create new repository?", | ||||||
|  |                     JOptionPane.YES_NO_OPTION); | ||||||
|  |             if (reply == JOptionPane.YES_OPTION) { | ||||||
|  |                 try { | ||||||
|  |                     assignmentsView.getGithubManager().setupAssignmentsRepo(repoName, "", this.getTeachingAssistantsTeamName()); | ||||||
|  |                     return true; | ||||||
|  |                 } catch (IOException e) { | ||||||
|  |                     //e.printStackTrace(); | ||||||
|  |                     JOptionPane.showMessageDialog(assignmentsView, "Could not create repository:\n" + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private String getTeachingAssistantsTeamName() { | ||||||
|  |         String name = JOptionPane.showInputDialog(this.previousView, "Please enter (exactly) the name of Github team\nthat contains all teaching assistants.", "Select TA Team", JOptionPane.QUESTION_MESSAGE); | ||||||
|  |         return name; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,27 @@ | ||||||
|  | package nl.andrewlalis.ui.control.listeners.start_view; | ||||||
|  | 
 | ||||||
|  | import nl.andrewlalis.ui.control.listeners.ViewChangeListener; | ||||||
|  | import nl.andrewlalis.ui.view.AbstractView; | ||||||
|  | import nl.andrewlalis.ui.view.StartView; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Listener for when the user intends to create repositories for a new course. | ||||||
|  |  */ | ||||||
|  | public class CreateAssignmentsRepoListener extends ViewChangeListener { | ||||||
|  | 
 | ||||||
|  |     public CreateAssignmentsRepoListener(AbstractView previousView, AbstractView newView) { | ||||||
|  |         super(previousView, newView); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * All that needs to be done here is check that the github manager can work with the given info. | ||||||
|  |      * @return True if the github manager accepts the organization name and access token, false otherwise. | ||||||
|  |      */ | ||||||
|  |     @Override | ||||||
|  |     protected boolean beforeChange() { | ||||||
|  |         StartView startView = (StartView) this.previousView; | ||||||
|  |         startView.getGithubManager().setOrganizationName(startView.getOrganizationName()); | ||||||
|  |         startView.getGithubManager().setAccessToken(startView.getAccessToken()); | ||||||
|  |         return startView.getGithubManager().validate(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,72 @@ | ||||||
|  | package nl.andrewlalis.ui.view; | ||||||
|  | 
 | ||||||
|  | import nl.andrewlalis.git_api.GithubManager; | ||||||
|  | 
 | ||||||
|  | import javax.swing.*; | ||||||
|  | import java.awt.*; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * All views in the application will extend from this view, as a means of simplifying and organizing how visual | ||||||
|  |  * components are made. | ||||||
|  |  */ | ||||||
|  | public abstract class AbstractView extends JFrame { | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * A GithubManager object which can be used to interact with github. | ||||||
|  |      */ | ||||||
|  |     private GithubManager githubManager; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Initializes the view by packing the content pane as it is defined by any child, and setting some generic swing | ||||||
|  |      * values. | ||||||
|  |      * @param title The window's title. | ||||||
|  |      * @param startVisible Whether or not to start the view as visible. | ||||||
|  |      * @param defaultCloseOperation What to do when the user closes the window. | ||||||
|  |      * @param preferredSize The preferred size of the view. | ||||||
|  |      */ | ||||||
|  |     AbstractView(String title, boolean startVisible, int defaultCloseOperation, Dimension preferredSize, GithubManager githubManager) { | ||||||
|  |         super(title); | ||||||
|  |         this.githubManager = githubManager; | ||||||
|  |         this.setContentPane(this.buildContentPane()); | ||||||
|  |         this.setDefaultCloseOperation(defaultCloseOperation); | ||||||
|  |         if (preferredSize != null) { | ||||||
|  |             this.setSize(preferredSize); | ||||||
|  |         } | ||||||
|  |         this.setLocationRelativeTo(null); | ||||||
|  |         this.pack(); | ||||||
|  |         this.setVisible(startVisible); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Constructs this view. Child classes will define how the content pane is constructed by returning that content | ||||||
|  |      * pane here. | ||||||
|  |      * @return The content pane containing the view to be rendered. | ||||||
|  |      */ | ||||||
|  |     protected abstract JPanel buildContentPane(); | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Resets this view and all form components within it. It is the responsibility of child classes to define how to | ||||||
|  |      * reset themselves. | ||||||
|  |      */ | ||||||
|  |     public void reset() { | ||||||
|  |         // Child classes can define custom behavior here. | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public GithubManager getGithubManager() { | ||||||
|  |         return githubManager; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 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. | ||||||
|  |      */ | ||||||
|  |     final 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; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,45 @@ | ||||||
|  | package nl.andrewlalis.ui.view; | ||||||
|  | 
 | ||||||
|  | import nl.andrewlalis.git_api.GithubManager; | ||||||
|  | import nl.andrewlalis.ui.control.listeners.create_assignments_view.NextListener; | ||||||
|  | 
 | ||||||
|  | import javax.swing.*; | ||||||
|  | import java.awt.*; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * In this view, the user will enter the name of an assignments repository to use for the course, or allows the user to | ||||||
|  |  * create a new one. | ||||||
|  |  * | ||||||
|  |  * Once the user is here, it is guaranteed that the github manager has been validated. | ||||||
|  |  */ | ||||||
|  | public class CreateAssignmentsView extends AbstractView { | ||||||
|  | 
 | ||||||
|  |     private JTextField repositoryNameField; | ||||||
|  | 
 | ||||||
|  |     public CreateAssignmentsView(GithubManager manager) { | ||||||
|  |         super("Create/Set Assignments Repository", | ||||||
|  |                 false, | ||||||
|  |                 DISPOSE_ON_CLOSE, | ||||||
|  |                 null, | ||||||
|  |                 manager); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getRepositoryName() { | ||||||
|  |         return this.repositoryNameField.getText(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     protected JPanel buildContentPane() { | ||||||
|  |         JPanel contentPane = new JPanel(); | ||||||
|  | 
 | ||||||
|  |         contentPane.setLayout(new BorderLayout()); | ||||||
|  |         this.repositoryNameField = new JTextField(); | ||||||
|  |         contentPane.add(this.generateTextFieldPanel("Repository name:", this.repositoryNameField), BorderLayout.CENTER); | ||||||
|  | 
 | ||||||
|  |         JButton nextButton = new JButton("Next"); | ||||||
|  |         nextButton.addActionListener(new NextListener(this, new InputStudentsFileView(this.getGithubManager()))); | ||||||
|  |         contentPane.add(nextButton, BorderLayout.SOUTH); | ||||||
|  | 
 | ||||||
|  |         return contentPane; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -1,8 +1,8 @@ | ||||||
| package nl.andrewlalis.ui.view; | package nl.andrewlalis.ui.view; | ||||||
| 
 | 
 | ||||||
|  | import nl.andrewlalis.command.CommandExecutor; | ||||||
| import nl.andrewlalis.model.Organization; | import nl.andrewlalis.model.Organization; | ||||||
| import nl.andrewlalis.ui.control.OutputTextHandler; | import nl.andrewlalis.ui.control.OutputTextHandler; | ||||||
| import nl.andrewlalis.ui.control.command.CommandExecutor; |  | ||||||
| import nl.andrewlalis.ui.control.listeners.*; | import nl.andrewlalis.ui.control.listeners.*; | ||||||
| 
 | 
 | ||||||
| import javax.swing.*; | import javax.swing.*; | ||||||
|  | @ -129,11 +129,6 @@ public class InitializerApp extends JFrame { | ||||||
|         commonActionsPanel.add(this.generateButtonPanel("Delegate Student Teams", new DelegateStudentTeamsListener(this.executor, this))); |         commonActionsPanel.add(this.generateButtonPanel("Delegate Student Teams", new DelegateStudentTeamsListener(this.executor, this))); | ||||||
|         commonActionsPanel.add(this.generateButtonPanel("Generate Assignments Repo", new GenerateAssignmentsRepoListener(this.executor, this))); |         commonActionsPanel.add(this.generateButtonPanel("Generate Assignments Repo", new GenerateAssignmentsRepoListener(this.executor, this))); | ||||||
| 
 | 
 | ||||||
|         // TODO: Enable this once the define teams dialog is complete. |  | ||||||
| //        JButton defineTaTeamsButton = new JButton("Define TA Teams"); |  | ||||||
| //        defineTaTeamsButton.addActionListener(new DefineTaTeamsListener(this.executor, this)); |  | ||||||
| //        commonActionsPanel.add(f); |  | ||||||
| 
 |  | ||||||
|         commonActionsPanel.add(this.generateButtonPanel("Delete Repos", new DeleteReposListener(this.executor, this))); |         commonActionsPanel.add(this.generateButtonPanel("Delete Repos", new DeleteReposListener(this.executor, this))); | ||||||
| 
 | 
 | ||||||
|         // Extra panel to push buttons to the top. |         // Extra panel to push buttons to the top. | ||||||
|  |  | ||||||
|  | @ -0,0 +1,33 @@ | ||||||
|  | package nl.andrewlalis.ui.view; | ||||||
|  | 
 | ||||||
|  | import nl.andrewlalis.git_api.GithubManager; | ||||||
|  | 
 | ||||||
|  | import javax.swing.*; | ||||||
|  | import java.awt.*; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * In this view, the user will select a file to read a list of students from, and generates the list of teams from that. | ||||||
|  |  */ | ||||||
|  | public class InputStudentsFileView extends AbstractView { | ||||||
|  | 
 | ||||||
|  |     InputStudentsFileView(GithubManager manager) { | ||||||
|  |         super("Input Students CSV", | ||||||
|  |                 false, | ||||||
|  |                 DISPOSE_ON_CLOSE, | ||||||
|  |                 null, | ||||||
|  |                 manager); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     protected JPanel buildContentPane() { | ||||||
|  |         JPanel contentPane = new JPanel(new BorderLayout()); | ||||||
|  | 
 | ||||||
|  |         JButton selectFileButton = new JButton("Select File"); | ||||||
|  |         contentPane.add(selectFileButton, BorderLayout.CENTER); | ||||||
|  | 
 | ||||||
|  |         JButton doneButton = new JButton("Done"); | ||||||
|  |         contentPane.add(doneButton, BorderLayout.SOUTH); | ||||||
|  | 
 | ||||||
|  |         return contentPane; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,63 @@ | ||||||
|  | package nl.andrewlalis.ui.view; | ||||||
|  | 
 | ||||||
|  | import nl.andrewlalis.git_api.GithubManager; | ||||||
|  | import nl.andrewlalis.ui.control.listeners.start_view.CreateAssignmentsRepoListener; | ||||||
|  | 
 | ||||||
|  | import javax.swing.*; | ||||||
|  | import java.awt.*; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * At this view, the user is asked to first enter the name of the organization, and the access token they created for | ||||||
|  |  * their authenticated Github account. | ||||||
|  |  * | ||||||
|  |  * Then, the user must choose whether they are starting a new course setup, or managing an existing one. | ||||||
|  |  * | ||||||
|  |  * If they choose to start a new course, they are taken to the AssignmentsRepoView, otherwise if they want to manage | ||||||
|  |  * an existing course, they are taken to the ManagementView. | ||||||
|  |  */ | ||||||
|  | public class StartView extends AbstractView { | ||||||
|  | 
 | ||||||
|  |     // Fields which hold information needed by the Github Manager. | ||||||
|  |     private JTextField organizationNameField; | ||||||
|  |     private JTextField accessTokenField; | ||||||
|  | 
 | ||||||
|  |     public StartView(GithubManager githubManager) { | ||||||
|  |         super("Github Initializer Startup", | ||||||
|  |                 true, | ||||||
|  |                 DISPOSE_ON_CLOSE, | ||||||
|  |                 null, | ||||||
|  |                 githubManager); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getOrganizationName() { | ||||||
|  |         return this.organizationNameField.getText(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getAccessToken() { | ||||||
|  |         return this.accessTokenField.getText(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     protected JPanel buildContentPane() { | ||||||
|  |         JPanel contentPane = new JPanel(new BorderLayout()); | ||||||
|  | 
 | ||||||
|  |         JPanel infoInputPanel = new JPanel(); | ||||||
|  |         infoInputPanel.setLayout(new BoxLayout(infoInputPanel, BoxLayout.PAGE_AXIS)); | ||||||
|  |         this.organizationNameField = new JTextField(); | ||||||
|  |         infoInputPanel.add(this.generateTextFieldPanel("Organization name:", this.organizationNameField)); | ||||||
|  |         this.accessTokenField = new JTextField(); | ||||||
|  |         infoInputPanel.add(this.generateTextFieldPanel("Access token:", this.accessTokenField)); | ||||||
|  | 
 | ||||||
|  |         JPanel buttonsPanel = new JPanel(); | ||||||
|  |         JButton assignmentsViewButton = new JButton("Start New Course"); | ||||||
|  |         assignmentsViewButton.addActionListener(new CreateAssignmentsRepoListener(this, new CreateAssignmentsView(this.getGithubManager()))); | ||||||
|  |         JButton managementViewButton = new JButton("Manage Existing Course"); | ||||||
|  | 
 | ||||||
|  |         buttonsPanel.add(assignmentsViewButton); | ||||||
|  |         buttonsPanel.add(managementViewButton); | ||||||
|  | 
 | ||||||
|  |         contentPane.add(infoInputPanel, BorderLayout.CENTER); | ||||||
|  |         contentPane.add(buttonsPanel, BorderLayout.SOUTH); | ||||||
|  |         return contentPane; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -1,19 +0,0 @@ | ||||||
| INSERT INTO person_types (id, name) |  | ||||||
| VALUES (0, 'student'), |  | ||||||
|        (1, 'teaching-assistant'), |  | ||||||
|        (2, 'professor'); |  | ||||||
| 
 |  | ||||||
| INSERT INTO team_types (id, name) |  | ||||||
| VALUES (0, 'student_team'), |  | ||||||
|        (1, 'teaching_assistant_team'), |  | ||||||
|        (2, 'all_teaching_assistants'), |  | ||||||
|        (3, 'none'); |  | ||||||
| 
 |  | ||||||
| INSERT INTO teams (id, team_type_id) |  | ||||||
| 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'), |  | ||||||
|        (1, 'person_error'), |  | ||||||
|        (2, 'system_error'); |  | ||||||
|  | @ -1,153 +0,0 @@ | ||||||
| PRAGMA foreign_keys = TRUE; |  | ||||||
| PRAGMA writable_schema = 1; |  | ||||||
| DELETE FROM sqlite_master WHERE type IN ('table', 'index', 'trigger'); |  | ||||||
| PRAGMA writable_schema = 0; |  | ||||||
| VACUUM; |  | ||||||
| 
 |  | ||||||
| -- Basic schema design. |  | ||||||
| CREATE TABLE IF NOT EXISTS person_types ( |  | ||||||
|   id INTEGER PRIMARY KEY, |  | ||||||
|   name TEXT NOT NULL UNIQUE |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| CREATE TABLE IF NOT EXISTS persons ( |  | ||||||
|   id INTEGER PRIMARY KEY, |  | ||||||
|   name TEXT NOT NULL, |  | ||||||
|   email_address TEXT NOT NULL, |  | ||||||
|   github_username TEXT NOT NULL UNIQUE, |  | ||||||
|   person_type_id INTEGER NOT NULL, |  | ||||||
|   team_id INTEGER NULL, |  | ||||||
|   FOREIGN KEY (person_type_id) |  | ||||||
|     REFERENCES person_types(id) |  | ||||||
|     ON DELETE CASCADE |  | ||||||
|     ON UPDATE CASCADE, |  | ||||||
|   FOREIGN KEY (team_id) |  | ||||||
|     REFERENCES teams(id) |  | ||||||
|       ON DELETE CASCADE |  | ||||||
|       ON UPDATE CASCADE |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| -- Team tables for all types of teams. |  | ||||||
| CREATE TABLE IF NOT EXISTS team_types ( |  | ||||||
|   id INTEGER PRIMARY KEY, |  | ||||||
|   name TEXT NOT NULL UNIQUE |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| CREATE TABLE IF NOT EXISTS teams ( |  | ||||||
|   id INTEGER PRIMARY KEY AUTOINCREMENT, |  | ||||||
|   team_type_id INTEGER NOT NULL, |  | ||||||
|   FOREIGN KEY (team_type_id) |  | ||||||
|     REFERENCES team_types(id) |  | ||||||
|     ON DELETE CASCADE |  | ||||||
|     ON UPDATE CASCADE |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| CREATE TABLE IF NOT EXISTS team_members ( |  | ||||||
|   id INTEGER PRIMARY KEY AUTOINCREMENT, |  | ||||||
|   team_id INTEGER NOT NULL, |  | ||||||
|   person_id INTEGER NOT NULL, |  | ||||||
|   FOREIGN KEY (team_id) |  | ||||||
|     REFERENCES teams(id) |  | ||||||
|     ON DELETE CASCADE |  | ||||||
|     ON UPDATE CASCADE, |  | ||||||
|   FOREIGN KEY (person_id) |  | ||||||
|     REFERENCES persons(id) |  | ||||||
|     ON DELETE CASCADE |  | ||||||
|     ON UPDATE CASCADE, |  | ||||||
|   UNIQUE (team_id, person_id) |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| CREATE TABLE IF NOT EXISTS teaching_assistant_teams ( |  | ||||||
|   team_id INTEGER PRIMARY KEY, |  | ||||||
|   name TEXT NOT NULL UNIQUE, |  | ||||||
|   FOREIGN KEY (team_id) |  | ||||||
|     REFERENCES teams(id) |  | ||||||
|     ON DELETE CASCADE |  | ||||||
|     ON UPDATE CASCADE |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| CREATE TABLE IF NOT EXISTS student_teams ( |  | ||||||
|   team_id INTEGER PRIMARY KEY, |  | ||||||
|   repository_name TEXT, |  | ||||||
|   teaching_assistant_team_id INTEGER, |  | ||||||
|   FOREIGN KEY (team_id) |  | ||||||
|     REFERENCES teams(id) |  | ||||||
|     ON DELETE CASCADE |  | ||||||
|     ON UPDATE CASCADE, |  | ||||||
|   FOREIGN KEY (teaching_assistant_team_id) |  | ||||||
|     REFERENCES  teaching_assistant_teams(team_id) |  | ||||||
|     ON DELETE CASCADE |  | ||||||
|     ON UPDATE CASCADE |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| -- Student-specific tables. |  | ||||||
| CREATE TABLE IF NOT EXISTS students ( |  | ||||||
|   person_id INTEGER PRIMARY KEY, |  | ||||||
|   chose_partner INTEGER NOT NULL, |  | ||||||
|   FOREIGN KEY (person_id) |  | ||||||
|     REFERENCES persons(id) |  | ||||||
|     ON DELETE CASCADE |  | ||||||
|     ON UPDATE CASCADE |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| CREATE TABLE IF NOT EXISTS student_preferred_partners ( |  | ||||||
|   student_id INTEGER PRIMARY KEY, |  | ||||||
|   partner_id INTEGER NOT NULL, |  | ||||||
|   FOREIGN KEY (student_id) |  | ||||||
|     REFERENCES students(person_id) |  | ||||||
|     ON DELETE CASCADE |  | ||||||
|     ON UPDATE CASCADE, |  | ||||||
|   UNIQUE (student_id, partner_id) |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| -- TeachingAssistant-specific tables. |  | ||||||
| CREATE TABLE IF NOT EXISTS teaching_assistants ( |  | ||||||
|   person_id INTEGER PRIMARY KEY, |  | ||||||
|   FOREIGN KEY (person_id) |  | ||||||
|     REFERENCES persons(id) |  | ||||||
|     ON DELETE CASCADE |  | ||||||
|     ON UPDATE CASCADE |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| -- Error queue storage. |  | ||||||
| CREATE TABLE IF NOT EXISTS error_types ( |  | ||||||
|   id INTEGER PRIMARY KEY, |  | ||||||
|   name TEXT NOT NULL UNIQUE |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| CREATE TABLE IF NOT EXISTS errors ( |  | ||||||
|   id INTEGER PRIMARY KEY, |  | ||||||
|   timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, |  | ||||||
|   error_type_id INTEGER NOT NULL, |  | ||||||
|   message TEXT NOT NULL, |  | ||||||
|   FOREIGN KEY (error_type_id) |  | ||||||
|     REFERENCES error_types(id) |  | ||||||
|     ON DELETE CASCADE |  | ||||||
|     ON UPDATE CASCADE |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| CREATE TABLE IF NOT EXISTS team_errors ( |  | ||||||
|   error_id INTEGER PRIMARY KEY, |  | ||||||
|   team_id INTEGER NOT NULL, |  | ||||||
|   FOREIGN KEY (error_id) |  | ||||||
|     REFERENCES errors(id) |  | ||||||
|     ON DELETE CASCADE |  | ||||||
|     ON UPDATE CASCADE, |  | ||||||
|   FOREIGN KEY (team_id) |  | ||||||
|     REFERENCES teams(id) |  | ||||||
|     ON DELETE CASCADE |  | ||||||
|     ON UPDATE CASCADE |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| CREATE TABLE IF NOT EXISTS person_errors ( |  | ||||||
|   error_id INTEGER PRIMARY KEY, |  | ||||||
|   person_id INTEGER NOT NULL, |  | ||||||
|   FOREIGN KEY (error_id) |  | ||||||
|     REFERENCES errors(id) |  | ||||||
|     ON DELETE CASCADE |  | ||||||
|     ON UPDATE CASCADE, |  | ||||||
|   FOREIGN KEY (person_id) |  | ||||||
|     REFERENCES persons(id) |  | ||||||
|     ON DELETE CASCADE |  | ||||||
|     ON UPDATE CASCADE |  | ||||||
| ); |  | ||||||
		Loading…
	
		Reference in New Issue