{"action":"created","comment":{"url":"https://api.github.com/repos/allure-framework/allure-core/pulls/comments/28887025","id":28887025,"diff_hunk":"@@ -1,94 +1,162 @@\n package ru.yandex.qatools.allure.data.plugins\n \n+import com.google.common.reflect.ClassPath\n import com.google.inject.Inject\n import com.google.inject.Injector\n import ru.yandex.qatools.allure.data.io.ReportWriter\n import ru.yandex.qatools.allure.data.utils.PluginUtils\n \n /**\n+ * Plugin manager helps you to find plugins and run\n+ * only plugins you need.\n+ * <p/>\n  * @author Dmitry Baev charlie@yandex-team.ru\n  *         Date: 17.02.15\n  */\n class PluginManager {\n \n-    protected Storage storage;\n+    /**\n+     * File with this name contains list of plugins with resources.\n+     */\n+    public static final String PLUGINS_JSON = \"plugins.json\"\n \n+    protected final Storage<PreparePlugin> preparePlugins\n+\n+    protected final Storage<ProcessPlugin> processPlugins\n+\n+    protected final List<PluginWithResources> pluginsWithResources\n+\n+    /**\n+     * Create an instance of plugin manager.\n+     */\n     @Inject\n     PluginManager(PluginLoader loader, Injector injector = null) {\n-        storage = new Storage(loader, injector)\n+        def plugins = load(loader, injector)\n+        preparePlugins = new Storage<>(filterByType(plugins, PreparePlugin))\n+        processPlugins = new Storage<>(filterByType(plugins, ProcessPlugin))\n+        pluginsWithResources = filterByType(processPlugins.values().flatten(), PluginWithResources)\n     }\n \n+    /**\n+     * Find all prepare plugins an process given object for\n+     * each of found plugins.\n+     */\n     public <T> void prepare(T object) {\n-        if (!object) {\n-            return\n-        }\n-        def plugins = storage.get(object.class, PreparePlugin)\n-\n-        plugins.each {\n-            it.prepare(object)\n-        }\n+        preparePlugins.get(object?.class)*.prepare(object)\n     }\n \n+    /**\n+     * Find all process plugins an process given object for\n+     * each of found plugins.\n+     */\n     public <T> void process(T object) {\n-        if (!object) {\n-            return\n-        }\n-        def plugins = storage.get(object.class, ProcessPlugin)\n+        def plugins = processPlugins.get(object?.class)\n \n         plugins.each {\n+            //copy each time, we can't use group operation\n             it.process(PluginUtils.clone(object))\n         }\n     }\n \n+    /**\n+     * Write all plugin data using given report writer\n+     */\n     public <T> void writePluginData(Class<T> type, ReportWriter writer) {\n         writer.write(getData(type))\n     }\n \n-\n+    /**\n+     * Get plugin data for given type\n+     */\n     protected List<PluginData> getData(Class<?> type) {\n-        if (!type) {\n-            []\n+        processPlugins.get(type)*.pluginData?.flatten() as List<PluginData>\n+    }\n+\n+    /**\n+     * Get list of names of plugins with resources\n+     */\n+    List<String> getPluginsWithResourcesNames() {\n+        pluginsWithResources.collect { plugin ->\n+            plugin.pluginName\n         }\n-        storage.get(type, ProcessPlugin).collect {\n-            it.pluginData\n-        }.flatten()\n     }\n \n-    protected class Storage {\n+    /**\n+     * Write list of plugins with resources to {@link #PLUGINS_JSON}\n+     */\n+    void writePluginList(ReportWriter writer) {\n+        writer.write(new PluginData(PLUGINS_JSON, pluginsWithResourcesNames))\n+    }\n \n-        private Map<Class, Map<Class, List<Plugin>>> storage = new HashMap<>().withDefault {\n-            new HashMap<>().withDefault {\n-                new ArrayList<>()\n+    /**\n+     * Write plugin resources. For each plugin search resources using\n+     * {@link #findPluginResources(ru.yandex.qatools.allure.data.plugins.ProcessPlugin)}\n+     *\n+     * @see ReportWriter\n+     */\n+    void writePluginResources(ReportWriter writer) {\n+        pluginsWithResources.each { plugin ->\n+            def resources = findPluginResources(plugin)\n+            resources.each { resource ->\n+                writer.write(plugin.pluginName, resource)\n             }\n         }\n+    }\n \n-        Storage(PluginLoader loader, Injector injector) {\n-            def plugins = loader.loadPlugins()\n-            if (!plugins) {\n-                return\n+    /**\n+     * Find all resources for plugin.\n+     */\n+    protected static List<URL> findPluginResources(ProcessPlugin plugin) {\n+        def path = plugin.class.canonicalName.replaceAll('\\\\.', '/')\n+        def pattern = ~\"^$path/.+\\$\"\n+        def result = []\n+        for (def resource : ClassPath.from(plugin.class.classLoader).resources) {\n+            if (resource.resourceName =~ pattern) {","path":"allure-report-data/src/main/groovy/ru/yandex/qatools/allure/data/plugins/PluginManager.groovy","position":142,"original_position":142,"commit_id":"4a8a90bb40dac4171e9d6cf14ef58a7f00191126","original_commit_id":"4a8a90bb40dac4171e9d6cf14ef58a7f00191126","user":{"login":"lanwen","id":1964214,"avatar_url":"https://avatars.githubusercontent.com/u/1964214?v=3","gravatar_id":"","url":"https://api.github.com/users/lanwen","html_url":"https://github.com/lanwen","followers_url":"https://api.github.com/users/lanwen/followers","following_url":"https://api.github.com/users/lanwen/following{/other_user}","gists_url":"https://api.github.com/users/lanwen/gists{/gist_id}","starred_url":"https://api.github.com/users/lanwen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lanwen/subscriptions","organizations_url":"https://api.github.com/users/lanwen/orgs","repos_url":"https://api.github.com/users/lanwen/repos","events_url":"https://api.github.com/users/lanwen/events{/privacy}","received_events_url":"https://api.github.com/users/lanwen/received_events","type":"User","site_admin":false},"body":"what means `=~`?","created_at":"2015-04-22T16:00:58Z","updated_at":"2015-04-22T16:00:58Z","html_url":"https://github.com/allure-framework/allure-core/pull/560#discussion_r28887025","pull_request_url":"https://api.github.com/repos/allure-framework/allure-core/pulls/560","_links":{"self":{"href":"https://api.github.com/repos/allure-framework/allure-core/pulls/comments/28887025"},"html":{"href":"https://github.com/allure-framework/allure-core/pull/560#discussion_r28887025"},"pull_request":{"href":"https://api.github.com/repos/allure-framework/allure-core/pulls/560"}}},"pull_request":{"url":"https://api.github.com/repos/allure-framework/allure-core/pulls/560","id":33872305,"html_url":"https://github.com/allure-framework/allure-core/pull/560","diff_url":"https://github.com/allure-framework/allure-core/pull/560.diff","patch_url":"https://github.com/allure-framework/allure-core/pull/560.patch","issue_url":"https://api.github.com/repos/allure-framework/allure-core/issues/560","number":560,"state":"closed","locked":false,"title":"Hmmmm. Bunch of changes. Copying plugin resources, few docs, api improvements etc","user":{"login":"baev","id":2149631,"avatar_url":"https://avatars.githubusercontent.com/u/2149631?v=3","gravatar_id":"","url":"https://api.github.com/users/baev","html_url":"https://github.com/baev","followers_url":"https://api.github.com/users/baev/followers","following_url":"https://api.github.com/users/baev/following{/other_user}","gists_url":"https://api.github.com/users/baev/gists{/gist_id}","starred_url":"https://api.github.com/users/baev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/baev/subscriptions","organizations_url":"https://api.github.com/users/baev/orgs","repos_url":"https://api.github.com/users/baev/repos","events_url":"https://api.github.com/users/baev/events{/privacy}","received_events_url":"https://api.github.com/users/baev/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-04-22T15:51:11Z","updated_at":"2015-04-22T16:00:58Z","closed_at":"2015-04-22T15:55:38Z","merged_at":"2015-04-22T15:55:38Z","merge_commit_sha":"9fd1755cbfcfab0d05d72daacbf873ae9f0bcb8d","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/allure-framework/allure-core/pulls/560/commits","review_comments_url":"https://api.github.com/repos/allure-framework/allure-core/pulls/560/comments","review_comment_url":"https://api.github.com/repos/allure-framework/allure-core/pulls/comments{/number}","comments_url":"https://api.github.com/repos/allure-framework/allure-core/issues/560/comments","statuses_url":"https://api.github.com/repos/allure-framework/allure-core/statuses/4a8a90bb40dac4171e9d6cf14ef58a7f00191126","head":{"label":"baev:new-repot-generation","ref":"new-repot-generation","sha":"4a8a90bb40dac4171e9d6cf14ef58a7f00191126","user":{"login":"baev","id":2149631,"avatar_url":"https://avatars.githubusercontent.com/u/2149631?v=3","gravatar_id":"","url":"https://api.github.com/users/baev","html_url":"https://github.com/baev","followers_url":"https://api.github.com/users/baev/followers","following_url":"https://api.github.com/users/baev/following{/other_user}","gists_url":"https://api.github.com/users/baev/gists{/gist_id}","starred_url":"https://api.github.com/users/baev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/baev/subscriptions","organizations_url":"https://api.github.com/users/baev/orgs","repos_url":"https://api.github.com/users/baev/repos","events_url":"https://api.github.com/users/baev/events{/privacy}","received_events_url":"https://api.github.com/users/baev/received_events","type":"User","site_admin":false},"repo":{"id":19652400,"name":"allure-core","full_name":"baev/allure-core","owner":{"login":"baev","id":2149631,"avatar_url":"https://avatars.githubusercontent.com/u/2149631?v=3","gravatar_id":"","url":"https://api.github.com/users/baev","html_url":"https://github.com/baev","followers_url":"https://api.github.com/users/baev/followers","following_url":"https://api.github.com/users/baev/following{/other_user}","gists_url":"https://api.github.com/users/baev/gists{/gist_id}","starred_url":"https://api.github.com/users/baev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/baev/subscriptions","organizations_url":"https://api.github.com/users/baev/orgs","repos_url":"https://api.github.com/users/baev/repos","events_url":"https://api.github.com/users/baev/events{/privacy}","received_events_url":"https://api.github.com/users/baev/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/baev/allure-core","description":"Flexible, lightweight and multi-language framework for writing self-documenting tests, with the ability to store attachments, such as screenshots, logs etc.","fork":true,"url":"https://api.github.com/repos/baev/allure-core","forks_url":"https://api.github.com/repos/baev/allure-core/forks","keys_url":"https://api.github.com/repos/baev/allure-core/keys{/key_id}","collaborators_url":"https://api.github.com/repos/baev/allure-core/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/baev/allure-core/teams","hooks_url":"https://api.github.com/repos/baev/allure-core/hooks","issue_events_url":"https://api.github.com/repos/baev/allure-core/issues/events{/number}","events_url":"https://api.github.com/repos/baev/allure-core/events","assignees_url":"https://api.github.com/repos/baev/allure-core/assignees{/user}","branches_url":"https://api.github.com/repos/baev/allure-core/branches{/branch}","tags_url":"https://api.github.com/repos/baev/allure-core/tags","blobs_url":"https://api.github.com/repos/baev/allure-core/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/baev/allure-core/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/baev/allure-core/git/refs{/sha}","trees_url":"https://api.github.com/repos/baev/allure-core/git/trees{/sha}","statuses_url":"https://api.github.com/repos/baev/allure-core/statuses/{sha}","languages_url":"https://api.github.com/repos/baev/allure-core/languages","stargazers_url":"https://api.github.com/repos/baev/allure-core/stargazers","contributors_url":"https://api.github.com/repos/baev/allure-core/contributors","subscribers_url":"https://api.github.com/repos/baev/allure-core/subscribers","subscription_url":"https://api.github.com/repos/baev/allure-core/subscription","commits_url":"https://api.github.com/repos/baev/allure-core/commits{/sha}","git_commits_url":"https://api.github.com/repos/baev/allure-core/git/commits{/sha}","comments_url":"https://api.github.com/repos/baev/allure-core/comments{/number}","issue_comment_url":"https://api.github.com/repos/baev/allure-core/issues/comments{/number}","contents_url":"https://api.github.com/repos/baev/allure-core/contents/{+path}","compare_url":"https://api.github.com/repos/baev/allure-core/compare/{base}...{head}","merges_url":"https://api.github.com/repos/baev/allure-core/merges","archive_url":"https://api.github.com/repos/baev/allure-core/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/baev/allure-core/downloads","issues_url":"https://api.github.com/repos/baev/allure-core/issues{/number}","pulls_url":"https://api.github.com/repos/baev/allure-core/pulls{/number}","milestones_url":"https://api.github.com/repos/baev/allure-core/milestones{/number}","notifications_url":"https://api.github.com/repos/baev/allure-core/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/baev/allure-core/labels{/name}","releases_url":"https://api.github.com/repos/baev/allure-core/releases{/id}","created_at":"2014-05-10T21:26:52Z","updated_at":"2015-04-17T11:43:06Z","pushed_at":"2015-04-22T15:40:52Z","git_url":"git://github.com/baev/allure-core.git","ssh_url":"git@github.com:baev/allure-core.git","clone_url":"https://github.com/baev/allure-core.git","svn_url":"https://github.com/baev/allure-core","homepage":"","size":11328,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"allure-framework:master","ref":"master","sha":"f4622dfcec88b23e36291e44a141426f092bffdf","user":{"login":"allure-framework","id":5879127,"avatar_url":"https://avatars.githubusercontent.com/u/5879127?v=3","gravatar_id":"","url":"https://api.github.com/users/allure-framework","html_url":"https://github.com/allure-framework","followers_url":"https://api.github.com/users/allure-framework/followers","following_url":"https://api.github.com/users/allure-framework/following{/other_user}","gists_url":"https://api.github.com/users/allure-framework/gists{/gist_id}","starred_url":"https://api.github.com/users/allure-framework/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/allure-framework/subscriptions","organizations_url":"https://api.github.com/users/allure-framework/orgs","repos_url":"https://api.github.com/users/allure-framework/repos","events_url":"https://api.github.com/users/allure-framework/events{/privacy}","received_events_url":"https://api.github.com/users/allure-framework/received_events","type":"Organization","site_admin":false},"repo":{"id":14718267,"name":"allure-core","full_name":"allure-framework/allure-core","owner":{"login":"allure-framework","id":5879127,"avatar_url":"https://avatars.githubusercontent.com/u/5879127?v=3","gravatar_id":"","url":"https://api.github.com/users/allure-framework","html_url":"https://github.com/allure-framework","followers_url":"https://api.github.com/users/allure-framework/followers","following_url":"https://api.github.com/users/allure-framework/following{/other_user}","gists_url":"https://api.github.com/users/allure-framework/gists{/gist_id}","starred_url":"https://api.github.com/users/allure-framework/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/allure-framework/subscriptions","organizations_url":"https://api.github.com/users/allure-framework/orgs","repos_url":"https://api.github.com/users/allure-framework/repos","events_url":"https://api.github.com/users/allure-framework/events{/privacy}","received_events_url":"https://api.github.com/users/allure-framework/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/allure-framework/allure-core","description":"A flexible lightweight multi-language test report tool with the possibility to add steps, attachments, parameters and so on.","fork":false,"url":"https://api.github.com/repos/allure-framework/allure-core","forks_url":"https://api.github.com/repos/allure-framework/allure-core/forks","keys_url":"https://api.github.com/repos/allure-framework/allure-core/keys{/key_id}","collaborators_url":"https://api.github.com/repos/allure-framework/allure-core/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/allure-framework/allure-core/teams","hooks_url":"https://api.github.com/repos/allure-framework/allure-core/hooks","issue_events_url":"https://api.github.com/repos/allure-framework/allure-core/issues/events{/number}","events_url":"https://api.github.com/repos/allure-framework/allure-core/events","assignees_url":"https://api.github.com/repos/allure-framework/allure-core/assignees{/user}","branches_url":"https://api.github.com/repos/allure-framework/allure-core/branches{/branch}","tags_url":"https://api.github.com/repos/allure-framework/allure-core/tags","blobs_url":"https://api.github.com/repos/allure-framework/allure-core/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/allure-framework/allure-core/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/allure-framework/allure-core/git/refs{/sha}","trees_url":"https://api.github.com/repos/allure-framework/allure-core/git/trees{/sha}","statuses_url":"https://api.github.com/repos/allure-framework/allure-core/statuses/{sha}","languages_url":"https://api.github.com/repos/allure-framework/allure-core/languages","stargazers_url":"https://api.github.com/repos/allure-framework/allure-core/stargazers","contributors_url":"https://api.github.com/repos/allure-framework/allure-core/contributors","subscribers_url":"https://api.github.com/repos/allure-framework/allure-core/subscribers","subscription_url":"https://api.github.com/repos/allure-framework/allure-core/subscription","commits_url":"https://api.github.com/repos/allure-framework/allure-core/commits{/sha}","git_commits_url":"https://api.github.com/repos/allure-framework/allure-core/git/commits{/sha}","comments_url":"https://api.github.com/repos/allure-framework/allure-core/comments{/number}","issue_comment_url":"https://api.github.com/repos/allure-framework/allure-core/issues/comments{/number}","contents_url":"https://api.github.com/repos/allure-framework/allure-core/contents/{+path}","compare_url":"https://api.github.com/repos/allure-framework/allure-core/compare/{base}...{head}","merges_url":"https://api.github.com/repos/allure-framework/allure-core/merges","archive_url":"https://api.github.com/repos/allure-framework/allure-core/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/allure-framework/allure-core/downloads","issues_url":"https://api.github.com/repos/allure-framework/allure-core/issues{/number}","pulls_url":"https://api.github.com/repos/allure-framework/allure-core/pulls{/number}","milestones_url":"https://api.github.com/repos/allure-framework/allure-core/milestones{/number}","notifications_url":"https://api.github.com/repos/allure-framework/allure-core/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/allure-framework/allure-core/labels{/name}","releases_url":"https://api.github.com/repos/allure-framework/allure-core/releases{/id}","created_at":"2013-11-26T13:54:51Z","updated_at":"2015-04-22T15:55:40Z","pushed_at":"2015-04-22T15:55:38Z","git_url":"git://github.com/allure-framework/allure-core.git","ssh_url":"git@github.com:allure-framework/allure-core.git","clone_url":"https://github.com/allure-framework/allure-core.git","svn_url":"https://github.com/allure-framework/allure-core","homepage":"http://allure.qatools.ru","size":16816,"stargazers_count":222,"watchers_count":222,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":52,"mirror_url":null,"open_issues_count":38,"forks":52,"open_issues":38,"watchers":222,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/allure-framework/allure-core/pulls/560"},"html":{"href":"https://github.com/allure-framework/allure-core/pull/560"},"issue":{"href":"https://api.github.com/repos/allure-framework/allure-core/issues/560"},"comments":{"href":"https://api.github.com/repos/allure-framework/allure-core/issues/560/comments"},"review_comments":{"href":"https://api.github.com/repos/allure-framework/allure-core/pulls/560/comments"},"review_comment":{"href":"https://api.github.com/repos/allure-framework/allure-core/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/allure-framework/allure-core/pulls/560/commits"},"statuses":{"href":"https://api.github.com/repos/allure-framework/allure-core/statuses/4a8a90bb40dac4171e9d6cf14ef58a7f00191126"}}}}