GitHub PullRequestReviewCommentEvent at 2014-07-23 21:31:37
Repository: scijava-common
Actor: ctrueden
Payload: {"action":"created","comment":{"url":"https://api.github.com/repos/scijava/scijava-common/pulls/comments/15317373","id":15317373,"diff_hunk":"@@ -0,0 +1,100 @@\n+/*\n+ * #%L\n+ * SciJava Common shared library for SciJava software.\n+ * %%\n+ * Copyright (C) 2009 - 2014 Board of Regents of the University of\n+ * Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck\n+ * Institute of Molecular Cell Biology and Genetics.\n+ * %%\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions are met:\n+ * \n+ * 1. Redistributions of source code must retain the above copyright notice,\n+ *    this list of conditions and the following disclaimer.\n+ * 2. Redistributions in binary form must reproduce the above copyright notice,\n+ *    this list of conditions and the following disclaimer in the documentation\n+ *    and/or other materials provided with the distribution.\n+ * \n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE\n+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n+ * POSSIBILITY OF SUCH DAMAGE.\n+ * #L%\n+ */\n+\n+package org.scijava.usage;\n+\n+import java.util.HashMap;\n+import java.util.Map;\n+\n+import org.scijava.Identifiable;\n+import org.scijava.Locatable;\n+import org.scijava.event.EventHandler;\n+import org.scijava.module.ModuleInfo;\n+import org.scijava.module.event.ModuleExecutedEvent;\n+import org.scijava.plugin.Plugin;\n+import org.scijava.service.AbstractService;\n+import org.scijava.service.Service;\n+\n+/**\n+ * Default service for tracking anonymous usage statistics.\n+ * \n+ * @author Curtis Rueden\n+ */\n+@Plugin(type = Service.class)\n+public class DefaultUsageService extends AbstractService\n+\timplements UsageService\n+{\n+\n+\t/** Table of usage statistics. */\n+\tprivate HashMap<String, UsageStats> stats = new HashMap<String, UsageStats>();\n+\n+\t// -- UsageService methods --\n+\n+\t@Override\n+\tpublic Map<String, UsageStats> getStats() {\n+\t\treturn stats;\n+\t}\n+\n+\t@Override\n+\tpublic void clearStats() {\n+\t\t// NB: Rather than calling stats.clear(), we allocate a new object\n+\t\t// so that references to the old table are not modified.\n+\t\tstats = new HashMap<String, UsageStats>();\n+\t}\n+\n+\t@Override\n+\tpublic UsageStats getUsage(final Object o) {\n+\t\tif (!(o instanceof Identifiable) || !(o instanceof Locatable)) {","path":"src/main/java/org/scijava/usage/DefaultUsageService.java","position":null,"original_position":75,"commit_id":"b89655564dab23d9173b2a1914c4aeccfc6f84d6","original_commit_id":"b11600fb361a296b802bc32fa9cc87621a9c0d47","user":{"login":"ctrueden","id":556626,"avatar_url":"https://avatars.githubusercontent.com/u/556626?","gravatar_id":"63df759e2779af56fd050a968ff98d09","url":"https://api.github.com/users/ctrueden","html_url":"https://github.com/ctrueden","followers_url":"https://api.github.com/users/ctrueden/followers","following_url":"https://api.github.com/users/ctrueden/following{/other_user}","gists_url":"https://api.github.com/users/ctrueden/gists{/gist_id}","starred_url":"https://api.github.com/users/ctrueden/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ctrueden/subscriptions","organizations_url":"https://api.github.com/users/ctrueden/orgs","repos_url":"https://api.github.com/users/ctrueden/repos","events_url":"https://api.github.com/users/ctrueden/events{/privacy}","received_events_url":"https://api.github.com/users/ctrueden/received_events","type":"User","site_admin":false},"body":"b89655564dab23d9173b2a1914c4aeccfc6f84d6","created_at":"2014-07-23T21:31:37Z","updated_at":"2014-07-23T21:31:37Z","html_url":"https://github.com/scijava/scijava-common/pull/103#discussion_r15317373","pull_request_url":"https://api.github.com/repos/scijava/scijava-common/pulls/103","_links":{"self":{"href":"https://api.github.com/repos/scijava/scijava-common/pulls/comments/15317373"},"html":{"href":"https://github.com/scijava/scijava-common/pull/103#discussion_r15317373"},"pull_request":{"href":"https://api.github.com/repos/scijava/scijava-common/pulls/103"}}},"pull_request":{"url":"https://api.github.com/repos/scijava/scijava-common/pulls/103","id":18684002,"html_url":"https://github.com/scijava/scijava-common/pull/103","diff_url":"https://github.com/scijava/scijava-common/pull/103.diff","patch_url":"https://github.com/scijava/scijava-common/pull/103.patch","issue_url":"https://api.github.com/repos/scijava/scijava-common/issues/103","number":103,"state":"open","title":"Usage statistics service","user":{"login":"ctrueden","id":556626,"avatar_url":"https://avatars.githubusercontent.com/u/556626?","gravatar_id":"63df759e2779af56fd050a968ff98d09","url":"https://api.github.com/users/ctrueden","html_url":"https://github.com/ctrueden","followers_url":"https://api.github.com/users/ctrueden/followers","following_url":"https://api.github.com/users/ctrueden/following{/other_user}","gists_url":"https://api.github.com/users/ctrueden/gists{/gist_id}","starred_url":"https://api.github.com/users/ctrueden/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ctrueden/subscriptions","organizations_url":"https://api.github.com/users/ctrueden/orgs","repos_url":"https://api.github.com/users/ctrueden/repos","events_url":"https://api.github.com/users/ctrueden/events{/privacy}","received_events_url":"https://api.github.com/users/ctrueden/received_events","type":"User","site_admin":false},"body":"This branch adds a service for tracking usage statistics. The service can currently track any object that implements the `Identifiable` and `Locatable` interfaces (the latter being new to this branch). It would be possible to generalize things even further, but I think this approach is good enough for our initial use case: tracking module executions. In that regard: the service subscribes to `ModuleExecutedEvent` and tracks usage of the executed modules via their `ModuleInfo` descriptors, which typically implement the two necessary interfaces, at least in the case of `CommandInfo` and `ScriptInfo`.\r\n\r\nThis branch also fixes a serious bug discovered incidentally: services with `@EventHandler` methods but which do not explicitly depend on the `EventService` may not have their event handlers subscribed properly when creating a `Context` with an explicit list of service interfaces. We avoided this problem in the past for full-blown contexts (created using the noargs constructor) by [setting the priority of the `DefaultEventService` absurdly high](https://github.com/imagej/imagej/commit/b9abe178b813fb68aa49fdd7515a5e6698436793),  but that was really an incomplete solution that papered over the actual issue. This branch finally fixes things properly by inferring an `EventService` dependency whenever one or more `@EventHandler` methods are present. I was slighly worried about the performance of more recursive class scanning to make this possible, but the performance difference is negligible in my tests (276 vs. 286 ms average creation time for a full-blown context with complete classpath), so I think it is OK.\r\n\r\nBoth the new `EventService` dependency logic and the `UsageService` are unit tested down the middle.\r\n\r\nSee also the `usage-statistics` branch of some other repositories, which are not yet ready to merge:\r\n* [imagej-usage](https://github.com/imagej/imagej-usage/compare/usage-statistics)\r\n* [imagej-updater](https://github.com/imagej/imagej-updater/compare/usage-statistics)\r\n","created_at":"2014-07-21T22:18:02Z","updated_at":"2014-07-23T21:31:37Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b82979698dffbd53dcabef41514336bc4268bb1e","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/scijava/scijava-common/pulls/103/commits","review_comments_url":"https://api.github.com/repos/scijava/scijava-common/pulls/103/comments","review_comment_url":"https://api.github.com/repos/scijava/scijava-common/pulls/comments/{number}","comments_url":"https://api.github.com/repos/scijava/scijava-common/issues/103/comments","statuses_url":"https://api.github.com/repos/scijava/scijava-common/statuses/b89655564dab23d9173b2a1914c4aeccfc6f84d6","head":{"label":"scijava:usage-statistics","ref":"usage-statistics","sha":"b89655564dab23d9173b2a1914c4aeccfc6f84d6","user":{"login":"scijava","id":1262770,"avatar_url":"https://avatars.githubusercontent.com/u/1262770?","gravatar_id":"93161c2cf73a9eb599c055a09afbe5b5","url":"https://api.github.com/users/scijava","html_url":"https://github.com/scijava","followers_url":"https://api.github.com/users/scijava/followers","following_url":"https://api.github.com/users/scijava/following{/other_user}","gists_url":"https://api.github.com/users/scijava/gists{/gist_id}","starred_url":"https://api.github.com/users/scijava/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scijava/subscriptions","organizations_url":"https://api.github.com/users/scijava/orgs","repos_url":"https://api.github.com/users/scijava/repos","events_url":"https://api.github.com/users/scijava/events{/privacy}","received_events_url":"https://api.github.com/users/scijava/received_events","type":"Organization","site_admin":false},"repo":{"id":3594497,"name":"scijava-common","full_name":"scijava/scijava-common","owner":{"login":"scijava","id":1262770,"avatar_url":"https://avatars.githubusercontent.com/u/1262770?","gravatar_id":"93161c2cf73a9eb599c055a09afbe5b5","url":"https://api.github.com/users/scijava","html_url":"https://github.com/scijava","followers_url":"https://api.github.com/users/scijava/followers","following_url":"https://api.github.com/users/scijava/following{/other_user}","gists_url":"https://api.github.com/users/scijava/gists{/gist_id}","starred_url":"https://api.github.com/users/scijava/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scijava/subscriptions","organizations_url":"https://api.github.com/users/scijava/orgs","repos_url":"https://api.github.com/users/scijava/repos","events_url":"https://api.github.com/users/scijava/events{/privacy}","received_events_url":"https://api.github.com/users/scijava/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/scijava/scijava-common","description":"A plugin framework and application container with built-in extensibility mechanism.","fork":false,"url":"https://api.github.com/repos/scijava/scijava-common","forks_url":"https://api.github.com/repos/scijava/scijava-common/forks","keys_url":"https://api.github.com/repos/scijava/scijava-common/keys{/key_id}","collaborators_url":"https://api.github.com/repos/scijava/scijava-common/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/scijava/scijava-common/teams","hooks_url":"https://api.github.com/repos/scijava/scijava-common/hooks","issue_events_url":"https://api.github.com/repos/scijava/scijava-common/issues/events{/number}","events_url":"https://api.github.com/repos/scijava/scijava-common/events","assignees_url":"https://api.github.com/repos/scijava/scijava-common/assignees{/user}","branches_url":"https://api.github.com/repos/scijava/scijava-common/branches{/branch}","tags_url":"https://api.github.com/repos/scijava/scijava-common/tags","blobs_url":"https://api.github.com/repos/scijava/scijava-common/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/scijava/scijava-common/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/scijava/scijava-common/git/refs{/sha}","trees_url":"https://api.github.com/repos/scijava/scijava-common/git/trees{/sha}","statuses_url":"https://api.github.com/repos/scijava/scijava-common/statuses/{sha}","languages_url":"https://api.github.com/repos/scijava/scijava-common/languages","stargazers_url":"https://api.github.com/repos/scijava/scijava-common/stargazers","contributors_url":"https://api.github.com/repos/scijava/scijava-common/contributors","subscribers_url":"https://api.github.com/repos/scijava/scijava-common/subscribers","subscription_url":"https://api.github.com/repos/scijava/scijava-common/subscription","commits_url":"https://api.github.com/repos/scijava/scijava-common/commits{/sha}","git_commits_url":"https://api.github.com/repos/scijava/scijava-common/git/commits{/sha}","comments_url":"https://api.github.com/repos/scijava/scijava-common/comments{/number}","issue_comment_url":"https://api.github.com/repos/scijava/scijava-common/issues/comments/{number}","contents_url":"https://api.github.com/repos/scijava/scijava-common/contents/{+path}","compare_url":"https://api.github.com/repos/scijava/scijava-common/compare/{base}...{head}","merges_url":"https://api.github.com/repos/scijava/scijava-common/merges","archive_url":"https://api.github.com/repos/scijava/scijava-common/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/scijava/scijava-common/downloads","issues_url":"https://api.github.com/repos/scijava/scijava-common/issues{/number}","pulls_url":"https://api.github.com/repos/scijava/scijava-common/pulls{/number}","milestones_url":"https://api.github.com/repos/scijava/scijava-common/milestones{/number}","notifications_url":"https://api.github.com/repos/scijava/scijava-common/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/scijava/scijava-common/labels{/name}","releases_url":"https://api.github.com/repos/scijava/scijava-common/releases{/id}","created_at":"2012-03-01T18:06:45Z","updated_at":"2014-06-27T21:48:57Z","pushed_at":"2014-07-23T21:31:22Z","git_url":"git://github.com/scijava/scijava-common.git","ssh_url":"git@github.com:scijava/scijava-common.git","clone_url":"https://github.com/scijava/scijava-common.git","svn_url":"https://github.com/scijava/scijava-common","homepage":"","size":7609,"stargazers_count":7,"watchers_count":7,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"forks_count":6,"mirror_url":null,"open_issues_count":41,"forks":6,"open_issues":41,"watchers":7,"default_branch":"master"}},"base":{"label":"scijava:master","ref":"master","sha":"858afc8bfd07b9db5a97d2cd38e0e995edb93c8f","user":{"login":"scijava","id":1262770,"avatar_url":"https://avatars.githubusercontent.com/u/1262770?","gravatar_id":"93161c2cf73a9eb599c055a09afbe5b5","url":"https://api.github.com/users/scijava","html_url":"https://github.com/scijava","followers_url":"https://api.github.com/users/scijava/followers","following_url":"https://api.github.com/users/scijava/following{/other_user}","gists_url":"https://api.github.com/users/scijava/gists{/gist_id}","starred_url":"https://api.github.com/users/scijava/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scijava/subscriptions","organizations_url":"https://api.github.com/users/scijava/orgs","repos_url":"https://api.github.com/users/scijava/repos","events_url":"https://api.github.com/users/scijava/events{/privacy}","received_events_url":"https://api.github.com/users/scijava/received_events","type":"Organization","site_admin":false},"repo":{"id":3594497,"name":"scijava-common","full_name":"scijava/scijava-common","owner":{"login":"scijava","id":1262770,"avatar_url":"https://avatars.githubusercontent.com/u/1262770?","gravatar_id":"93161c2cf73a9eb599c055a09afbe5b5","url":"https://api.github.com/users/scijava","html_url":"https://github.com/scijava","followers_url":"https://api.github.com/users/scijava/followers","following_url":"https://api.github.com/users/scijava/following{/other_user}","gists_url":"https://api.github.com/users/scijava/gists{/gist_id}","starred_url":"https://api.github.com/users/scijava/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scijava/subscriptions","organizations_url":"https://api.github.com/users/scijava/orgs","repos_url":"https://api.github.com/users/scijava/repos","events_url":"https://api.github.com/users/scijava/events{/privacy}","received_events_url":"https://api.github.com/users/scijava/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/scijava/scijava-common","description":"A plugin framework and application container with built-in extensibility mechanism.","fork":false,"url":"https://api.github.com/repos/scijava/scijava-common","forks_url":"https://api.github.com/repos/scijava/scijava-common/forks","keys_url":"https://api.github.com/repos/scijava/scijava-common/keys{/key_id}","collaborators_url":"https://api.github.com/repos/scijava/scijava-common/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/scijava/scijava-common/teams","hooks_url":"https://api.github.com/repos/scijava/scijava-common/hooks","issue_events_url":"https://api.github.com/repos/scijava/scijava-common/issues/events{/number}","events_url":"https://api.github.com/repos/scijava/scijava-common/events","assignees_url":"https://api.github.com/repos/scijava/scijava-common/assignees{/user}","branches_url":"https://api.github.com/repos/scijava/scijava-common/branches{/branch}","tags_url":"https://api.github.com/repos/scijava/scijava-common/tags","blobs_url":"https://api.github.com/repos/scijava/scijava-common/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/scijava/scijava-common/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/scijava/scijava-common/git/refs{/sha}","trees_url":"https://api.github.com/repos/scijava/scijava-common/git/trees{/sha}","statuses_url":"https://api.github.com/repos/scijava/scijava-common/statuses/{sha}","languages_url":"https://api.github.com/repos/scijava/scijava-common/languages","stargazers_url":"https://api.github.com/repos/scijava/scijava-common/stargazers","contributors_url":"https://api.github.com/repos/scijava/scijava-common/contributors","subscribers_url":"https://api.github.com/repos/scijava/scijava-common/subscribers","subscription_url":"https://api.github.com/repos/scijava/scijava-common/subscription","commits_url":"https://api.github.com/repos/scijava/scijava-common/commits{/sha}","git_commits_url":"https://api.github.com/repos/scijava/scijava-common/git/commits{/sha}","comments_url":"https://api.github.com/repos/scijava/scijava-common/comments{/number}","issue_comment_url":"https://api.github.com/repos/scijava/scijava-common/issues/comments/{number}","contents_url":"https://api.github.com/repos/scijava/scijava-common/contents/{+path}","compare_url":"https://api.github.com/repos/scijava/scijava-common/compare/{base}...{head}","merges_url":"https://api.github.com/repos/scijava/scijava-common/merges","archive_url":"https://api.github.com/repos/scijava/scijava-common/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/scijava/scijava-common/downloads","issues_url":"https://api.github.com/repos/scijava/scijava-common/issues{/number}","pulls_url":"https://api.github.com/repos/scijava/scijava-common/pulls{/number}","milestones_url":"https://api.github.com/repos/scijava/scijava-common/milestones{/number}","notifications_url":"https://api.github.com/repos/scijava/scijava-common/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/scijava/scijava-common/labels{/name}","releases_url":"https://api.github.com/repos/scijava/scijava-common/releases{/id}","created_at":"2012-03-01T18:06:45Z","updated_at":"2014-06-27T21:48:57Z","pushed_at":"2014-07-23T21:31:22Z","git_url":"git://github.com/scijava/scijava-common.git","ssh_url":"git@github.com:scijava/scijava-common.git","clone_url":"https://github.com/scijava/scijava-common.git","svn_url":"https://github.com/scijava/scijava-common","homepage":"","size":7609,"stargazers_count":7,"watchers_count":7,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"forks_count":6,"mirror_url":null,"open_issues_count":41,"forks":6,"open_issues":41,"watchers":7,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/scijava/scijava-common/pulls/103"},"html":{"href":"https://github.com/scijava/scijava-common/pull/103"},"issue":{"href":"https://api.github.com/repos/scijava/scijava-common/issues/103"},"comments":{"href":"https://api.github.com/repos/scijava/scijava-common/issues/103/comments"},"review_comments":{"href":"https://api.github.com/repos/scijava/scijava-common/pulls/103/comments"},"review_comment":{"href":"https://api.github.com/repos/scijava/scijava-common/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/scijava/scijava-common/pulls/103/commits"},"statuses":{"href":"https://api.github.com/repos/scijava/scijava-common/statuses/b89655564dab23d9173b2a1914c4aeccfc6f84d6"}}}}