{"action":"created","comment":{"url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/pulls/comments/171284656","pull_request_review_id":100109055,"id":171284656,"diff_hunk":"@@ -0,0 +1,190 @@\n+package mail.core.loader;\n+\n+import mail.api.event.EventBus;\n+import mail.api.loader.Loader;\n+import mail.api.loader.Mod;\n+import mail.api.loader.ModContainer;\n+import mail.api.loader.ModProvider;\n+import mail.api.serial.DataStructure;\n+import mail.core.event.EventBusImpl;\n+import mail.core.serial.JSONSerializationHandler;\n+\n+import java.io.File;\n+import java.io.FileInputStream;\n+import java.io.IOException;\n+import java.net.URI;\n+import java.net.URL;\n+import java.nio.file.FileSystem;\n+import java.nio.file.FileSystems;\n+import java.nio.file.Path;\n+import java.nio.file.Paths;\n+import java.util.Collections;\n+import java.util.HashSet;\n+import java.util.IdentityHashMap;\n+import java.util.Map;\n+import java.util.Set;\n+import java.util.zip.ZipEntry;\n+import java.util.zip.ZipFile;\n+\n+public enum LoaderImpl implements Loader {\n+    INSTANCE;\n+\n+    private static final String METADATA_FILE_NAME = \"mailmod.json\";\n+    private static final String MODS_DIRECTORY_NAME = \"mailmods\";\n+\n+    private final Set<ModContainer> containers = new HashSet<>();\n+    private final Map<ModProvider<?>, Set<? extends Mod.Prototype>> modPrototypes = new IdentityHashMap<>();\n+    private final Map<Mod.Prototype, Context> modContextMap = new IdentityHashMap<>();\n+\n+    // TODO: Implement in a prettier way with some libs\n+    private final Set<String> modNames = new HashSet<>();\n+    private Set<ModImpl> modSet;\n+\n+    @Override\n+    public boolean isLoaded(String id) {\n+        return modNames.contains(id);\n+    }\n+\n+    @Override\n+    public Set<? extends Mod> getLoadedMods() {\n+        return modSet;\n+    }\n+\n+    public void load(ClasspathManager manager) throws Exception {\n+        findMods(manager);\n+        findDependencies();\n+        injectDependencies();\n+        identifyMods();\n+        setupMods(manager);\n+        loadModules();\n+        loadMods();\n+    }\n+\n+    private void findMods(ClasspathManager manager) throws IOException {\n+        File modsDir = new File(\"./\" + MODS_DIRECTORY_NAME);\n+        modsDir.mkdirs();\n+\n+        File[] jars = modsDir.listFiles((dir, name) -> name.toLowerCase().endsWith(\".jar\"));\n+        for (File jar : jars) {\n+            considerModContainer(jar.getCanonicalFile().getAbsoluteFile());\n+        }\n+\n+        for (File file : manager.getClasspathSources()) {\n+            considerModContainer(file.getCanonicalFile().getAbsoluteFile());\n+        }\n+    }\n+\n+    private void considerModContainer(File file) throws IOException {\n+        Path path = Paths.get(file.toURI());\n+        FileSystem fileSystem;\n+        Path fileSystemRoot;\n+        DataStructure metadata;\n+\n+        if (file.getName().toLowerCase().endsWith(\".jar\")) {\n+            try (ZipFile jar = new ZipFile(file)) {\n+                ZipEntry metaFile = jar.getEntry(METADATA_FILE_NAME);\n+                if (metaFile == null) return; // Missing meta file - ignoring!\n+\n+                fileSystem = FileSystems.newFileSystem(URI.create(\"jar:\" + path.toUri().toString()), Collections.emptyMap());\n+                fileSystemRoot = fileSystem.getPath(\"/\");\n+                metadata = JSONSerializationHandler.instance.read(jar.getInputStream(metaFile));\n+            } catch (IOException e) {\n+                return; // Jar is not a mod - ignoring!\n+            }\n+        } else if (file.isDirectory()) {\n+            File metaFile = new File(file, METADATA_FILE_NAME);\n+            if (!metaFile.exists()) return; // Missing meta file - ignoring!\n+\n+            fileSystem = FileSystems.getDefault();\n+            fileSystemRoot = Paths.get(file.toURI());\n+            metadata = JSONSerializationHandler.instance.read(new FileInputStream(metaFile));\n+        } else {\n+            return; // Not something we can handle","path":"src/main/java/mail/core/loader/LoaderImpl.java","position":102,"original_position":102,"commit_id":"68c929b29dff1568dd4ccf0def75ef012d10d96b","original_commit_id":"68c929b29dff1568dd4ccf0def75ef012d10d96b","user":{"login":"TheCodedOne","id":17037059,"avatar_url":"https://avatars2.githubusercontent.com/u/17037059?v=4","gravatar_id":"","url":"https://api.github.com/users/TheCodedOne","html_url":"https://github.com/TheCodedOne","followers_url":"https://api.github.com/users/TheCodedOne/followers","following_url":"https://api.github.com/users/TheCodedOne/following{/other_user}","gists_url":"https://api.github.com/users/TheCodedOne/gists{/gist_id}","starred_url":"https://api.github.com/users/TheCodedOne/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TheCodedOne/subscriptions","organizations_url":"https://api.github.com/users/TheCodedOne/orgs","repos_url":"https://api.github.com/users/TheCodedOne/repos","events_url":"https://api.github.com/users/TheCodedOne/events{/privacy}","received_events_url":"https://api.github.com/users/TheCodedOne/received_events","type":"User","site_admin":false},"body":"Could this perhaps be a way to allow such things as javascript or similar mods if people wrote a parser for them, perhaps passing an unknown file to a type of registry to see if its a mod or not might be viable","created_at":"2018-02-28T15:37:02Z","updated_at":"2018-02-28T15:38:22Z","html_url":"https://github.com/TheMAILProject/MAIL-Core/pull/1#discussion_r171284656","pull_request_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/pulls/1","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/TheMAILProject/MAIL-Core/pulls/comments/171284656"},"html":{"href":"https://github.com/TheMAILProject/MAIL-Core/pull/1#discussion_r171284656"},"pull_request":{"href":"https://api.github.com/repos/TheMAILProject/MAIL-Core/pulls/1"}}},"pull_request":{"url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/pulls/1","id":171192584,"html_url":"https://github.com/TheMAILProject/MAIL-Core/pull/1","diff_url":"https://github.com/TheMAILProject/MAIL-Core/pull/1.diff","patch_url":"https://github.com/TheMAILProject/MAIL-Core/pull/1.patch","issue_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/issues/1","number":1,"state":"open","locked":false,"title":"Initial implementation of events and the loader system","user":{"login":"amadornes","id":2066666,"avatar_url":"https://avatars0.githubusercontent.com/u/2066666?v=4","gravatar_id":"","url":"https://api.github.com/users/amadornes","html_url":"https://github.com/amadornes","followers_url":"https://api.github.com/users/amadornes/followers","following_url":"https://api.github.com/users/amadornes/following{/other_user}","gists_url":"https://api.github.com/users/amadornes/gists{/gist_id}","starred_url":"https://api.github.com/users/amadornes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/amadornes/subscriptions","organizations_url":"https://api.github.com/users/amadornes/orgs","repos_url":"https://api.github.com/users/amadornes/repos","events_url":"https://api.github.com/users/amadornes/events{/privacy}","received_events_url":"https://api.github.com/users/amadornes/received_events","type":"User","site_admin":false},"body":"","created_at":"2018-02-24T19:08:08Z","updated_at":"2018-02-28T15:38:22Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e202d235bfa081616db561166c2519b0bc46c3f7","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/pulls/1/commits","review_comments_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/pulls/1/comments","review_comment_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/pulls/comments{/number}","comments_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/issues/1/comments","statuses_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/statuses/68c929b29dff1568dd4ccf0def75ef012d10d96b","head":{"label":"amadornes:feature_loader_events","ref":"feature_loader_events","sha":"68c929b29dff1568dd4ccf0def75ef012d10d96b","user":{"login":"amadornes","id":2066666,"avatar_url":"https://avatars0.githubusercontent.com/u/2066666?v=4","gravatar_id":"","url":"https://api.github.com/users/amadornes","html_url":"https://github.com/amadornes","followers_url":"https://api.github.com/users/amadornes/followers","following_url":"https://api.github.com/users/amadornes/following{/other_user}","gists_url":"https://api.github.com/users/amadornes/gists{/gist_id}","starred_url":"https://api.github.com/users/amadornes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/amadornes/subscriptions","organizations_url":"https://api.github.com/users/amadornes/orgs","repos_url":"https://api.github.com/users/amadornes/repos","events_url":"https://api.github.com/users/amadornes/events{/privacy}","received_events_url":"https://api.github.com/users/amadornes/received_events","type":"User","site_admin":false},"repo":{"id":122770562,"name":"MAIL-Core","full_name":"amadornes/MAIL-Core","owner":{"login":"amadornes","id":2066666,"avatar_url":"https://avatars0.githubusercontent.com/u/2066666?v=4","gravatar_id":"","url":"https://api.github.com/users/amadornes","html_url":"https://github.com/amadornes","followers_url":"https://api.github.com/users/amadornes/followers","following_url":"https://api.github.com/users/amadornes/following{/other_user}","gists_url":"https://api.github.com/users/amadornes/gists{/gist_id}","starred_url":"https://api.github.com/users/amadornes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/amadornes/subscriptions","organizations_url":"https://api.github.com/users/amadornes/orgs","repos_url":"https://api.github.com/users/amadornes/repos","events_url":"https://api.github.com/users/amadornes/events{/privacy}","received_events_url":"https://api.github.com/users/amadornes/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/amadornes/MAIL-Core","description":"Implementation of the core MAIL APIs in a platform-agnostic way","fork":true,"url":"https://api.github.com/repos/amadornes/MAIL-Core","forks_url":"https://api.github.com/repos/amadornes/MAIL-Core/forks","keys_url":"https://api.github.com/repos/amadornes/MAIL-Core/keys{/key_id}","collaborators_url":"https://api.github.com/repos/amadornes/MAIL-Core/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/amadornes/MAIL-Core/teams","hooks_url":"https://api.github.com/repos/amadornes/MAIL-Core/hooks","issue_events_url":"https://api.github.com/repos/amadornes/MAIL-Core/issues/events{/number}","events_url":"https://api.github.com/repos/amadornes/MAIL-Core/events","assignees_url":"https://api.github.com/repos/amadornes/MAIL-Core/assignees{/user}","branches_url":"https://api.github.com/repos/amadornes/MAIL-Core/branches{/branch}","tags_url":"https://api.github.com/repos/amadornes/MAIL-Core/tags","blobs_url":"https://api.github.com/repos/amadornes/MAIL-Core/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/amadornes/MAIL-Core/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/amadornes/MAIL-Core/git/refs{/sha}","trees_url":"https://api.github.com/repos/amadornes/MAIL-Core/git/trees{/sha}","statuses_url":"https://api.github.com/repos/amadornes/MAIL-Core/statuses/{sha}","languages_url":"https://api.github.com/repos/amadornes/MAIL-Core/languages","stargazers_url":"https://api.github.com/repos/amadornes/MAIL-Core/stargazers","contributors_url":"https://api.github.com/repos/amadornes/MAIL-Core/contributors","subscribers_url":"https://api.github.com/repos/amadornes/MAIL-Core/subscribers","subscription_url":"https://api.github.com/repos/amadornes/MAIL-Core/subscription","commits_url":"https://api.github.com/repos/amadornes/MAIL-Core/commits{/sha}","git_commits_url":"https://api.github.com/repos/amadornes/MAIL-Core/git/commits{/sha}","comments_url":"https://api.github.com/repos/amadornes/MAIL-Core/comments{/number}","issue_comment_url":"https://api.github.com/repos/amadornes/MAIL-Core/issues/comments{/number}","contents_url":"https://api.github.com/repos/amadornes/MAIL-Core/contents/{+path}","compare_url":"https://api.github.com/repos/amadornes/MAIL-Core/compare/{base}...{head}","merges_url":"https://api.github.com/repos/amadornes/MAIL-Core/merges","archive_url":"https://api.github.com/repos/amadornes/MAIL-Core/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/amadornes/MAIL-Core/downloads","issues_url":"https://api.github.com/repos/amadornes/MAIL-Core/issues{/number}","pulls_url":"https://api.github.com/repos/amadornes/MAIL-Core/pulls{/number}","milestones_url":"https://api.github.com/repos/amadornes/MAIL-Core/milestones{/number}","notifications_url":"https://api.github.com/repos/amadornes/MAIL-Core/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/amadornes/MAIL-Core/labels{/name}","releases_url":"https://api.github.com/repos/amadornes/MAIL-Core/releases{/id}","deployments_url":"https://api.github.com/repos/amadornes/MAIL-Core/deployments","created_at":"2018-02-24T19:04:59Z","updated_at":"2018-02-22T00:13:01Z","pushed_at":"2018-02-24T19:07:45Z","git_url":"git://github.com/amadornes/MAIL-Core.git","ssh_url":"git@github.com:amadornes/MAIL-Core.git","clone_url":"https://github.com/amadornes/MAIL-Core.git","svn_url":"https://github.com/amadornes/MAIL-Core","homepage":"","size":58,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"TheMAILProject:master","ref":"master","sha":"1a57ddc76f8b5c1a537633d3af6f169ae3d352c6","user":{"login":"TheMAILProject","id":32556448,"avatar_url":"https://avatars1.githubusercontent.com/u/32556448?v=4","gravatar_id":"","url":"https://api.github.com/users/TheMAILProject","html_url":"https://github.com/TheMAILProject","followers_url":"https://api.github.com/users/TheMAILProject/followers","following_url":"https://api.github.com/users/TheMAILProject/following{/other_user}","gists_url":"https://api.github.com/users/TheMAILProject/gists{/gist_id}","starred_url":"https://api.github.com/users/TheMAILProject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TheMAILProject/subscriptions","organizations_url":"https://api.github.com/users/TheMAILProject/orgs","repos_url":"https://api.github.com/users/TheMAILProject/repos","events_url":"https://api.github.com/users/TheMAILProject/events{/privacy}","received_events_url":"https://api.github.com/users/TheMAILProject/received_events","type":"Organization","site_admin":false},"repo":{"id":115936589,"name":"MAIL-Core","full_name":"TheMAILProject/MAIL-Core","owner":{"login":"TheMAILProject","id":32556448,"avatar_url":"https://avatars1.githubusercontent.com/u/32556448?v=4","gravatar_id":"","url":"https://api.github.com/users/TheMAILProject","html_url":"https://github.com/TheMAILProject","followers_url":"https://api.github.com/users/TheMAILProject/followers","following_url":"https://api.github.com/users/TheMAILProject/following{/other_user}","gists_url":"https://api.github.com/users/TheMAILProject/gists{/gist_id}","starred_url":"https://api.github.com/users/TheMAILProject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TheMAILProject/subscriptions","organizations_url":"https://api.github.com/users/TheMAILProject/orgs","repos_url":"https://api.github.com/users/TheMAILProject/repos","events_url":"https://api.github.com/users/TheMAILProject/events{/privacy}","received_events_url":"https://api.github.com/users/TheMAILProject/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/TheMAILProject/MAIL-Core","description":"Implementation of the core MAIL APIs in a platform-agnostic way","fork":false,"url":"https://api.github.com/repos/TheMAILProject/MAIL-Core","forks_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/forks","keys_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/keys{/key_id}","collaborators_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/teams","hooks_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/hooks","issue_events_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/issues/events{/number}","events_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/events","assignees_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/assignees{/user}","branches_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/branches{/branch}","tags_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/tags","blobs_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/git/refs{/sha}","trees_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/git/trees{/sha}","statuses_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/statuses/{sha}","languages_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/languages","stargazers_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/stargazers","contributors_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/contributors","subscribers_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/subscribers","subscription_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/subscription","commits_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/commits{/sha}","git_commits_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/git/commits{/sha}","comments_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/comments{/number}","issue_comment_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/issues/comments{/number}","contents_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/contents/{+path}","compare_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/compare/{base}...{head}","merges_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/merges","archive_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/downloads","issues_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/issues{/number}","pulls_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/pulls{/number}","milestones_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/milestones{/number}","notifications_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/labels{/name}","releases_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/releases{/id}","deployments_url":"https://api.github.com/repos/TheMAILProject/MAIL-Core/deployments","created_at":"2018-01-01T18:10:43Z","updated_at":"2018-02-22T00:13:01Z","pushed_at":"2018-02-24T19:08:09Z","git_url":"git://github.com/TheMAILProject/MAIL-Core.git","ssh_url":"git@github.com:TheMAILProject/MAIL-Core.git","clone_url":"https://github.com/TheMAILProject/MAIL-Core.git","svn_url":"https://github.com/TheMAILProject/MAIL-Core","homepage":"","size":49,"stargazers_count":3,"watchers_count":3,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"archived":false,"open_issues_count":1,"license":null,"forks":2,"open_issues":1,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/TheMAILProject/MAIL-Core/pulls/1"},"html":{"href":"https://github.com/TheMAILProject/MAIL-Core/pull/1"},"issue":{"href":"https://api.github.com/repos/TheMAILProject/MAIL-Core/issues/1"},"comments":{"href":"https://api.github.com/repos/TheMAILProject/MAIL-Core/issues/1/comments"},"review_comments":{"href":"https://api.github.com/repos/TheMAILProject/MAIL-Core/pulls/1/comments"},"review_comment":{"href":"https://api.github.com/repos/TheMAILProject/MAIL-Core/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/TheMAILProject/MAIL-Core/pulls/1/commits"},"statuses":{"href":"https://api.github.com/repos/TheMAILProject/MAIL-Core/statuses/68c929b29dff1568dd4ccf0def75ef012d10d96b"}},"author_association":"OWNER"}}
{"actor":{"display_login":"TheCodedOne"}}