{"action":"created","comment":{"url":"https://api.github.com/repos/GPII/gpii-express/pulls/comments/26247574","id":26247574,"diff_hunk":"@@ -0,0 +1,179 @@\n+// Express instance represented as a component\n+//\n+// Add additional routers and middleware as child components of this module\n+\"use strict\";\n+var fluid = fluid || require(\"infusion\");\n+var gpii  = fluid.registerNamespace(\"gpii\");\n+fluid.registerNamespace(\"gpii.express\");\n+\n+// Look up the path (parent, sibling, child) relationships for a node.\n+// Used in constructing the hierarchy we will use to wire together everything in our onCreate method.\n+//\n+// This does not require an invoker as it is basically a static method.\n+gpii.express.pathForComponent = function (that) {\n+    var instantiator  = fluid.getInstantiator(that);\n+    var path          = instantiator.idToPath(that.id);\n+    var segments      = fluid.model.parseEL(path);\n+    return segments;\n+};\n+\n+// Make a note of the lineage of this middleware or router component, all the way back presumably to this gpii.express\n+// instance itself.\n+//\n+// This information will be used to wire together all nested routers and any middleware dependencies they have.\n+gpii.express.registerComponentLineage = function(childComponent, expressComponent) {\n+    // Get the list of parents for this component\n+    var segments = gpii.express.pathForComponent(childComponent);\n+\n+    var childNickname  = segments[segments.length - 1];\n+\n+    var expressSegments = gpii.express.pathForComponent(expressComponent);\n+\n+    // If we only have one segment more than express, we are a child of express itself.\n+    // We need this to be able to handle cases in which express itself is a child component.\n+    if (segments.length === expressSegments.length + 1) {\n+        expressComponent.options.members.directChildrenOfInterest.push(childNickname);\n+    }\n+    // Otherwise, register the nickname of this component and its immediate parent path, each level will take care of the next highest.\n+    else if (segments.length > expressSegments.length + 1) {\n+        var parentPath = segments.slice(expressSegments.length, segments.length - 1).join(\".\");\n+        if (expressComponent.options.members.childrenByParent[parentPath]) {\n+            expressComponent.options.members.childrenByParent[parentPath].push(childNickname);\n+        }\n+        else {\n+            expressComponent.options.members.childrenByParent[parentPath] = [childNickname];\n+        }\n+    }\n+};\n+\n+// Wire a child to its immediate descendants.\n+gpii.express.connectDirectDescendants = function(that, childComponent, childPath) {\n+    var descendants =  that.options.members.childrenByParent[childPath];\n+\n+    // This component has descendants, wire them in first\n+    if (descendants !== undefined) {\n+        // Wire together one level of routers and middleware, then recurse\n+        for (var a = 0; a < descendants.length; a++) {\n+            var grandchildNickname  = descendants[a];\n+            var grandchildComponent = childComponent[grandchildNickname];\n+            if (fluid.hasGrade(grandchildComponent.options, \"gpii.express.router\")) {\n+                // We have to wire our children in with our path to preserve relative pathing, so that their router will begin with our path.\n+                childComponent.options.router.use(childComponent.options.path, grandchildComponent.options.router);\n+\n+                // Recurse from here on down.\n+                that.connectDirectDescendants(grandchildComponent, childPath + \".\" + grandchildNickname);\n+            }\n+            else if (fluid.hasGrade(grandchildComponent.options, \"gpii.express.middleware\")) {\n+                if (childComponent.options.router) {\n+                    // We have to wire our children in with our path to preserve relative pathing, so that their router will begin with our path.\n+                    childComponent.options.router.use(childComponent.options.path, grandchildComponent.getMiddlewareFunction());\n+                }\n+                else {\n+                    throw(new Error({message: \"A component must expose a router in order to work with child middleware components.\"}));","path":"src/js/express.js","position":72,"original_position":72,"commit_id":"60aa3444cf15dbccfa7727c957b4ac8c55bfd39f","original_commit_id":"60aa3444cf15dbccfa7727c957b4ac8c55bfd39f","user":{"login":"amb26","id":561418,"avatar_url":"https://avatars.githubusercontent.com/u/561418?v=3","gravatar_id":"","url":"https://api.github.com/users/amb26","html_url":"https://github.com/amb26","followers_url":"https://api.github.com/users/amb26/followers","following_url":"https://api.github.com/users/amb26/following{/other_user}","gists_url":"https://api.github.com/users/amb26/gists{/gist_id}","starred_url":"https://api.github.com/users/amb26/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/amb26/subscriptions","organizations_url":"https://api.github.com/users/amb26/orgs","repos_url":"https://api.github.com/users/amb26/repos","events_url":"https://api.github.com/users/amb26/events{/privacy}","received_events_url":"https://api.github.com/users/amb26/received_events","type":"User","site_admin":false},"body":"We use fluid.fail in these cases - exception handling in JavaScript is a cursed technique which must never be used. As well as not working the way that developers in corporate languages (C++/Java/C#) expect, it is handled extremely badly by the optimisers in the JavaScript VMs.","created_at":"2015-03-11T19:39:13Z","updated_at":"2015-03-11T19:39:13Z","html_url":"https://github.com/GPII/gpii-express/pull/2#discussion_r26247574","pull_request_url":"https://api.github.com/repos/GPII/gpii-express/pulls/2","_links":{"self":{"href":"https://api.github.com/repos/GPII/gpii-express/pulls/comments/26247574"},"html":{"href":"https://github.com/GPII/gpii-express/pull/2#discussion_r26247574"},"pull_request":{"href":"https://api.github.com/repos/GPII/gpii-express/pulls/2"}}},"pull_request":{"url":"https://api.github.com/repos/GPII/gpii-express/pulls/2","id":30860001,"html_url":"https://github.com/GPII/gpii-express/pull/2","diff_url":"https://github.com/GPII/gpii-express/pull/2.diff","patch_url":"https://github.com/GPII/gpii-express/pull/2.patch","issue_url":"https://api.github.com/repos/GPII/gpii-express/issues/2","number":2,"state":"open","locked":false,"title":"Second review of gpii.express module...","user":{"login":"the-t-in-rtf","id":5765222,"avatar_url":"https://avatars.githubusercontent.com/u/5765222?v=3","gravatar_id":"","url":"https://api.github.com/users/the-t-in-rtf","html_url":"https://github.com/the-t-in-rtf","followers_url":"https://api.github.com/users/the-t-in-rtf/followers","following_url":"https://api.github.com/users/the-t-in-rtf/following{/other_user}","gists_url":"https://api.github.com/users/the-t-in-rtf/gists{/gist_id}","starred_url":"https://api.github.com/users/the-t-in-rtf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/the-t-in-rtf/subscriptions","organizations_url":"https://api.github.com/users/the-t-in-rtf/orgs","repos_url":"https://api.github.com/users/the-t-in-rtf/repos","events_url":"https://api.github.com/users/the-t-in-rtf/events{/privacy}","received_events_url":"https://api.github.com/users/the-t-in-rtf/received_events","type":"User","site_admin":false},"body":"I have completed another round of updates since our last discussion, and am submitting my work for review.\r\n\r\nThe biggest change is that gpii.express is now responsible for wiring all middleware and components together.","created_at":"2015-03-10T15:20:27Z","updated_at":"2015-03-11T19:39:13Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1a646aa9b45bc08c7617a9df92a5dda3f5af3f3c","assignee":{"login":"amb26","id":561418,"avatar_url":"https://avatars.githubusercontent.com/u/561418?v=3","gravatar_id":"","url":"https://api.github.com/users/amb26","html_url":"https://github.com/amb26","followers_url":"https://api.github.com/users/amb26/followers","following_url":"https://api.github.com/users/amb26/following{/other_user}","gists_url":"https://api.github.com/users/amb26/gists{/gist_id}","starred_url":"https://api.github.com/users/amb26/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/amb26/subscriptions","organizations_url":"https://api.github.com/users/amb26/orgs","repos_url":"https://api.github.com/users/amb26/repos","events_url":"https://api.github.com/users/amb26/events{/privacy}","received_events_url":"https://api.github.com/users/amb26/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/GPII/gpii-express/pulls/2/commits","review_comments_url":"https://api.github.com/repos/GPII/gpii-express/pulls/2/comments","review_comment_url":"https://api.github.com/repos/GPII/gpii-express/pulls/comments{/number}","comments_url":"https://api.github.com/repos/GPII/gpii-express/issues/2/comments","statuses_url":"https://api.github.com/repos/GPII/gpii-express/statuses/60aa3444cf15dbccfa7727c957b4ac8c55bfd39f","head":{"label":"the-t-in-rtf:second-review","ref":"second-review","sha":"60aa3444cf15dbccfa7727c957b4ac8c55bfd39f","user":{"login":"the-t-in-rtf","id":5765222,"avatar_url":"https://avatars.githubusercontent.com/u/5765222?v=3","gravatar_id":"","url":"https://api.github.com/users/the-t-in-rtf","html_url":"https://github.com/the-t-in-rtf","followers_url":"https://api.github.com/users/the-t-in-rtf/followers","following_url":"https://api.github.com/users/the-t-in-rtf/following{/other_user}","gists_url":"https://api.github.com/users/the-t-in-rtf/gists{/gist_id}","starred_url":"https://api.github.com/users/the-t-in-rtf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/the-t-in-rtf/subscriptions","organizations_url":"https://api.github.com/users/the-t-in-rtf/orgs","repos_url":"https://api.github.com/users/the-t-in-rtf/repos","events_url":"https://api.github.com/users/the-t-in-rtf/events{/privacy}","received_events_url":"https://api.github.com/users/the-t-in-rtf/received_events","type":"User","site_admin":false},"repo":{"id":30924618,"name":"gpii-express","full_name":"the-t-in-rtf/gpii-express","owner":{"login":"the-t-in-rtf","id":5765222,"avatar_url":"https://avatars.githubusercontent.com/u/5765222?v=3","gravatar_id":"","url":"https://api.github.com/users/the-t-in-rtf","html_url":"https://github.com/the-t-in-rtf","followers_url":"https://api.github.com/users/the-t-in-rtf/followers","following_url":"https://api.github.com/users/the-t-in-rtf/following{/other_user}","gists_url":"https://api.github.com/users/the-t-in-rtf/gists{/gist_id}","starred_url":"https://api.github.com/users/the-t-in-rtf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/the-t-in-rtf/subscriptions","organizations_url":"https://api.github.com/users/the-t-in-rtf/orgs","repos_url":"https://api.github.com/users/the-t-in-rtf/repos","events_url":"https://api.github.com/users/the-t-in-rtf/events{/privacy}","received_events_url":"https://api.github.com/users/the-t-in-rtf/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/the-t-in-rtf/gpii-express","description":"A fluid module to load express.js","fork":true,"url":"https://api.github.com/repos/the-t-in-rtf/gpii-express","forks_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/forks","keys_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/keys{/key_id}","collaborators_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/teams","hooks_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/hooks","issue_events_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/issues/events{/number}","events_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/events","assignees_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/assignees{/user}","branches_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/branches{/branch}","tags_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/tags","blobs_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/git/refs{/sha}","trees_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/git/trees{/sha}","statuses_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/statuses/{sha}","languages_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/languages","stargazers_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/stargazers","contributors_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/contributors","subscribers_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/subscribers","subscription_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/subscription","commits_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/commits{/sha}","git_commits_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/git/commits{/sha}","comments_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/comments{/number}","issue_comment_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/issues/comments{/number}","contents_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/contents/{+path}","compare_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/compare/{base}...{head}","merges_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/merges","archive_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/downloads","issues_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/issues{/number}","pulls_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/pulls{/number}","milestones_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/milestones{/number}","notifications_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/labels{/name}","releases_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/releases{/id}","created_at":"2015-02-17T16:02:26Z","updated_at":"2015-03-03T15:50:27Z","pushed_at":"2015-03-10T15:17:02Z","git_url":"git://github.com/the-t-in-rtf/gpii-express.git","ssh_url":"git@github.com:the-t-in-rtf/gpii-express.git","clone_url":"https://github.com/the-t-in-rtf/gpii-express.git","svn_url":"https://github.com/the-t-in-rtf/gpii-express","homepage":null,"size":163,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":false,"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":"GPII:master","ref":"master","sha":"bb88b9306593c8cec5189f0227c6899b9d346a03","user":{"login":"GPII","id":1343050,"avatar_url":"https://avatars.githubusercontent.com/u/1343050?v=3","gravatar_id":"","url":"https://api.github.com/users/GPII","html_url":"https://github.com/GPII","followers_url":"https://api.github.com/users/GPII/followers","following_url":"https://api.github.com/users/GPII/following{/other_user}","gists_url":"https://api.github.com/users/GPII/gists{/gist_id}","starred_url":"https://api.github.com/users/GPII/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GPII/subscriptions","organizations_url":"https://api.github.com/users/GPII/orgs","repos_url":"https://api.github.com/users/GPII/repos","events_url":"https://api.github.com/users/GPII/events{/privacy}","received_events_url":"https://api.github.com/users/GPII/received_events","type":"Organization","site_admin":false},"repo":{"id":30625709,"name":"gpii-express","full_name":"GPII/gpii-express","owner":{"login":"GPII","id":1343050,"avatar_url":"https://avatars.githubusercontent.com/u/1343050?v=3","gravatar_id":"","url":"https://api.github.com/users/GPII","html_url":"https://github.com/GPII","followers_url":"https://api.github.com/users/GPII/followers","following_url":"https://api.github.com/users/GPII/following{/other_user}","gists_url":"https://api.github.com/users/GPII/gists{/gist_id}","starred_url":"https://api.github.com/users/GPII/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GPII/subscriptions","organizations_url":"https://api.github.com/users/GPII/orgs","repos_url":"https://api.github.com/users/GPII/repos","events_url":"https://api.github.com/users/GPII/events{/privacy}","received_events_url":"https://api.github.com/users/GPII/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/GPII/gpii-express","description":"A fluid module to load express.js","fork":false,"url":"https://api.github.com/repos/GPII/gpii-express","forks_url":"https://api.github.com/repos/GPII/gpii-express/forks","keys_url":"https://api.github.com/repos/GPII/gpii-express/keys{/key_id}","collaborators_url":"https://api.github.com/repos/GPII/gpii-express/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/GPII/gpii-express/teams","hooks_url":"https://api.github.com/repos/GPII/gpii-express/hooks","issue_events_url":"https://api.github.com/repos/GPII/gpii-express/issues/events{/number}","events_url":"https://api.github.com/repos/GPII/gpii-express/events","assignees_url":"https://api.github.com/repos/GPII/gpii-express/assignees{/user}","branches_url":"https://api.github.com/repos/GPII/gpii-express/branches{/branch}","tags_url":"https://api.github.com/repos/GPII/gpii-express/tags","blobs_url":"https://api.github.com/repos/GPII/gpii-express/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/GPII/gpii-express/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/GPII/gpii-express/git/refs{/sha}","trees_url":"https://api.github.com/repos/GPII/gpii-express/git/trees{/sha}","statuses_url":"https://api.github.com/repos/GPII/gpii-express/statuses/{sha}","languages_url":"https://api.github.com/repos/GPII/gpii-express/languages","stargazers_url":"https://api.github.com/repos/GPII/gpii-express/stargazers","contributors_url":"https://api.github.com/repos/GPII/gpii-express/contributors","subscribers_url":"https://api.github.com/repos/GPII/gpii-express/subscribers","subscription_url":"https://api.github.com/repos/GPII/gpii-express/subscription","commits_url":"https://api.github.com/repos/GPII/gpii-express/commits{/sha}","git_commits_url":"https://api.github.com/repos/GPII/gpii-express/git/commits{/sha}","comments_url":"https://api.github.com/repos/GPII/gpii-express/comments{/number}","issue_comment_url":"https://api.github.com/repos/GPII/gpii-express/issues/comments{/number}","contents_url":"https://api.github.com/repos/GPII/gpii-express/contents/{+path}","compare_url":"https://api.github.com/repos/GPII/gpii-express/compare/{base}...{head}","merges_url":"https://api.github.com/repos/GPII/gpii-express/merges","archive_url":"https://api.github.com/repos/GPII/gpii-express/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/GPII/gpii-express/downloads","issues_url":"https://api.github.com/repos/GPII/gpii-express/issues{/number}","pulls_url":"https://api.github.com/repos/GPII/gpii-express/pulls{/number}","milestones_url":"https://api.github.com/repos/GPII/gpii-express/milestones{/number}","notifications_url":"https://api.github.com/repos/GPII/gpii-express/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/GPII/gpii-express/labels{/name}","releases_url":"https://api.github.com/repos/GPII/gpii-express/releases{/id}","created_at":"2015-02-11T02:12:46Z","updated_at":"2015-02-11T02:12:46Z","pushed_at":"2015-02-13T16:56:06Z","git_url":"git://github.com/GPII/gpii-express.git","ssh_url":"git@github.com:GPII/gpii-express.git","clone_url":"https://github.com/GPII/gpii-express.git","svn_url":"https://github.com/GPII/gpii-express","homepage":null,"size":117,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":1,"forks":2,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/GPII/gpii-express/pulls/2"},"html":{"href":"https://github.com/GPII/gpii-express/pull/2"},"issue":{"href":"https://api.github.com/repos/GPII/gpii-express/issues/2"},"comments":{"href":"https://api.github.com/repos/GPII/gpii-express/issues/2/comments"},"review_comments":{"href":"https://api.github.com/repos/GPII/gpii-express/pulls/2/comments"},"review_comment":{"href":"https://api.github.com/repos/GPII/gpii-express/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/GPII/gpii-express/pulls/2/commits"},"statuses":{"href":"https://api.github.com/repos/GPII/gpii-express/statuses/60aa3444cf15dbccfa7727c957b4ac8c55bfd39f"}}}}