From dbd5b148e2df4ba8d12305fe3c0c7df29e3fb43f Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 4 Nov 2014 17:17:35 -0800 Subject: [PATCH] [Framework] Add comments, logging Add additional comments and logging to components of the framework layer. WTD-518. --- .../framework/src/ApplicationBootstrapper.js | 2 ++ platform/framework/src/Bundle.js | 15 +++++++-- platform/framework/src/BundleLoader.js | 22 +++++++++++++ platform/framework/src/BundleResolver.js | 27 +++++++++++++++- platform/framework/src/Constants.js | 2 +- platform/framework/src/CustomRegistrars.js | 13 +++++++- platform/framework/src/Extension.js | 25 +++++++++++++-- platform/framework/src/ExtensionRegistrar.js | 32 ++++++++++++++++++- .../framework/src/FrameworkInitializer.js | 30 ++++------------- platform/framework/src/Main.js | 2 +- 10 files changed, 136 insertions(+), 34 deletions(-) diff --git a/platform/framework/src/ApplicationBootstrapper.js b/platform/framework/src/ApplicationBootstrapper.js index b8357d373f..c77026f93c 100644 --- a/platform/framework/src/ApplicationBootstrapper.js +++ b/platform/framework/src/ApplicationBootstrapper.js @@ -22,6 +22,8 @@ define( function ApplicationBootstrapper(angular, document, $log) { return { /** + * Bootstrap the application. + * * @method * @memberof ApplicationBootstrapper# * @param {angular.Module} app the Angular application to diff --git a/platform/framework/src/Bundle.js b/platform/framework/src/Bundle.js index 6ea29289df..8f8e244d2d 100644 --- a/platform/framework/src/Bundle.js +++ b/platform/framework/src/Bundle.js @@ -58,9 +58,9 @@ define( logName += ")"; } - return (self = { + self = { /** - * + * Get the path to this bundle. * @memberof Bundle# * @returns {string} */ @@ -112,6 +112,8 @@ define( return logName; }, /** + * Get all extensions exposed by this bundle of a given + * category. * * @param category * @memberof Bundle# @@ -125,6 +127,9 @@ define( }); }, /** + * Get a list of all categories of extension exposed by + * this bundle. + * * @memberof Bundle# * @returns {Array} */ @@ -132,6 +137,8 @@ define( return Object.keys(definition.extensions); }, /** + * Get the plain definition of this bundle, as read from + * its JSON declaration. * * @memberof Bundle# * @returns {BundleDefinition} the raw definition of this bundle @@ -139,7 +146,9 @@ define( getDefinition: function () { return definition; } - }); + }; + + return self; } return Bundle; diff --git a/platform/framework/src/BundleLoader.js b/platform/framework/src/BundleLoader.js index cac1e29bbd..f6d7b0f0c6 100644 --- a/platform/framework/src/BundleLoader.js +++ b/platform/framework/src/BundleLoader.js @@ -14,6 +14,9 @@ define( LOAD_ERROR_PREFIX = "Failed to load bundle "; /** + * Loads bundle definitions and wraps them in interfaces which are + * useful to the framework. This provides the base information which + * will be used by later phases of framework layer initialization. * * @constructor * @param {object} $http Angular's HTTP requester @@ -53,12 +56,16 @@ define( ); } + // Load an individual bundle, as a Bundle object. + // Returns undefined if the definition could not be loaded. function loadBundle(bundlePath) { return loadBundleDefinition(bundlePath).then(function (definition) { return definition && (new Bundle(bundlePath, definition)); }); } + // Load all named bundles from the array, returned as an array + // of Bundle objects. function loadBundlesFromArray(bundleArray) { var bundlePromises = bundleArray.map(loadBundle); @@ -66,10 +73,16 @@ define( .then(filterBundles); } + // Load all bundles named in the referenced file. The file is + // presumed to be a JSON file function loadBundlesFromFile(listFile) { return getJSON(listFile).then(loadBundlesFromArray); } + // Load all indicated bundles. If the argument is an array, + // this is taken to be a list of all bundles to load; if it + // is a string, then it is treated as the name of a JSON + // file containing the list of bundles to load. function loadBundles(bundles) { return Array.isArray(bundles) ? loadBundlesFromArray(bundles) : (typeof bundles === 'string') ? loadBundlesFromFile(bundles) : @@ -78,6 +91,15 @@ define( return { + /** + * Load a group of bundles, to be used to constitute the + * application by later framework initialization phases. + * + * @memberof BundleLoader# + * @param {string|string[]} an array of bundle names to load, or + * the name of a JSON file containing that array + * @returns {Promise.} + */ loadBundles: loadBundles }; } diff --git a/platform/framework/src/BundleResolver.js b/platform/framework/src/BundleResolver.js index 7f12952cd4..c08ae27ab6 100644 --- a/platform/framework/src/BundleResolver.js +++ b/platform/framework/src/BundleResolver.js @@ -9,12 +9,20 @@ define( "use strict"; /** + * Responsible for the extension resolution phase of framework + * initialization. During this phase, any scripts implementing + * extensions provided by bundles are loaded. * * @constructor */ - function BundleResolver(extensionResolver) { + function BundleResolver(extensionResolver, $log) { /** + * Merge resolved bundles (where each is expressed as an + * object containing key-value pairs, where keys are extension + * categories and values are arrays of resolved extensions) + * into one large object containing resolved extensions from + * all bundles (in the same form.) * * @param {Object.[]} resolvedBundles * @returns {Object.} @@ -31,6 +39,9 @@ define( return result; } + // Resolve a bundle; resolve all extensions, and return + // the resolved extensions in an object in the format described + // for mergeResolvedBundles above function resolveBundle(bundle) { var categories = bundle.getExtensionCategories(), result = {}; @@ -56,11 +67,25 @@ define( return result; } + // Log the large-scale task + $log.info( + "Resolving extensions for bundle " + bundle.getLogName() + ); + return Promise.all(categories.map(resolveCategory)) .then(giveResult); } return { + /** + * Resolve all extensions exposed by these bundles. + * + * @param {Bundle[]} bundles the bundles to resolve + * @returns {Object.} an object containing + * key-value pairs, where keys are extension + * categories and values are arrays of resolved + * extensions belonging to those categories + */ resolveBundles: function (bundles) { return Promise.all(bundles.map(resolveBundle)) .then(mergeResolvedBundles); diff --git a/platform/framework/src/Constants.js b/platform/framework/src/Constants.js index c2d8170fd8..b40e77756d 100644 --- a/platform/framework/src/Constants.js +++ b/platform/framework/src/Constants.js @@ -1,7 +1,7 @@ /*global define*/ /** - * Constants used by the framework. + * Constants used by the framework layer. */ define({ MODULE_NAME: "OpenMCTWeb", diff --git a/platform/framework/src/CustomRegistrars.js b/platform/framework/src/CustomRegistrars.js index f366c4465f..516c755152 100644 --- a/platform/framework/src/CustomRegistrars.js +++ b/platform/framework/src/CustomRegistrars.js @@ -15,6 +15,10 @@ define( * @constructor */ function CustomRegistrars(app, $log) { + + // Used to create custom registration functions which map to + // named methods on Angular modules, which follow the normal + // app.method(key, [ deps..., function ]) pattern. function CustomRegistrar(angularFunction) { return function (extension, index) { var key = extension.key, @@ -45,7 +49,8 @@ define( }; } - function registerRoute(extension, index) { + // Custom registration function for extensions of category "route" + function registerRoute(extension) { var route = Object.create(extension); // Adjust path for bundle @@ -57,6 +62,9 @@ define( ].join(Constants.SEPARATOR); } + // Log the registration + $log.info("Registering route: " + (route.key || route.when)); + // Register the route with Angular app.config(['$routeProvider', function ($routeProvider) { if (route.when) { @@ -67,6 +75,9 @@ define( }]); } + // More like key-value pairs than methods; key is the + // name of the extension category to be handled, and the value + // is the function which handles it. return { routes: registerRoute, directives: new CustomRegistrar("directive"), diff --git a/platform/framework/src/Extension.js b/platform/framework/src/Extension.js index b1a4b340ec..b65ed1ccc0 100644 --- a/platform/framework/src/Extension.js +++ b/platform/framework/src/Extension.js @@ -57,12 +57,16 @@ define( return { /** + * Get the machine-readable identifier for this extension. + * * @returns {string} */ getKey: function () { return definition.key || "undefined"; }, /** + * Get the bundle which declared this extension. + * * @memberof Extension# * @returns {Bundle} */ @@ -70,6 +74,9 @@ define( return bundle; }, /** + * Get the category into which this extension falls. + * (e.g. "directives") + * * @memberof Extension# * @returns {string} */ @@ -77,8 +84,12 @@ define( return category; }, /** - * Check whether or not this - * @returns {boolean} + * Check whether or not this extension should have an + * associated implementation module which may need to + * be loaded. + * + * @returns {boolean} true if an implementation separate + * from this definition should also be loaded */ hasImplementation: function () { return definition.implementation !== undefined; @@ -107,8 +118,16 @@ define( return logName; }, /** + * Get the plain definition of the extension. + * + * Note that this definition will have an additional "bundle" + * field which points back to the bundle which defined the + * extension, as a convenience. + * * @memberof Extension# - * @returns {ExtensionDefinition} + * @returns {ExtensionDefinition} the plain definition of + * this extension, as read from the bundle + * declaration. */ getDefinition: function () { return extensionDefinition; diff --git a/platform/framework/src/ExtensionRegistrar.js b/platform/framework/src/ExtensionRegistrar.js index 8159476bce..8a527fdf88 100644 --- a/platform/framework/src/ExtensionRegistrar.js +++ b/platform/framework/src/ExtensionRegistrar.js @@ -9,8 +9,15 @@ define( "use strict"; /** + * Responsible for registering extensions with Angular. * * @constructor + * @param {angular.Module} the Angular application with which + * extensions should be registered + * @param {Object.} customRegistrars an object + * containing custom registration functions, primarily for + * Angular built-ins. + * @param {*} $log Angular's logging service */ function ExtensionRegistrar(app, customRegistrars, $log) { // Track which extension categories have already been registered. @@ -18,6 +25,8 @@ define( // registered twice. var registeredCategories = {}; + // Used to build unique identifiers for individual extensions, + // so that these can be registered separately with Angular function identify(category, extension, index) { var name = extension.key ? (extension.key + "-" + index) : @@ -25,10 +34,14 @@ define( return category + "[" + name + "]"; } + // Echo arguments; used to represent groups of non-built-in + // extensions as a single dependency. function echo() { - return arguments.slice; + return arguments.slice(); } + // Always return a static value; used to represent plain + // metadata as a single dependency in Angular. function staticFunction(value) { return function () { return value; }; } @@ -45,6 +58,8 @@ define( return dependencies.concat([factory]); } + // Register extension arrays with Angular under an appropriately + // suffixed name, e.g. "types[]" function registerExtensionArraysForCategory(category, names) { var name = category + Constants.EXTENSION_SUFFIX; app.factory(name, names.concat([echo])); @@ -102,6 +117,21 @@ define( customRegistrars = customRegistrars || {}; return { + /** + * Register a group of resolved extensions with the Angular + * module managed by this registrar. + * + * For convenient chaining (particularly from the framework + * initializer's perspective), this returns the Angular + * module with which extensions were registered. + * + * @param {Object.} extensionGroup an object + * containing key-value pairs, where keys are extension + * categories and values are arrays of resolved + * extensions + * @returns {angular.Module} the application module with + * which extensions were registered + */ registerExtensions: registerExtensionGroup }; } diff --git a/platform/framework/src/FrameworkInitializer.js b/platform/framework/src/FrameworkInitializer.js index 75e88abee1..dd898ced38 100644 --- a/platform/framework/src/FrameworkInitializer.js +++ b/platform/framework/src/FrameworkInitializer.js @@ -9,6 +9,13 @@ define( "use strict"; /** + * Responsible for managing the four stages of framework + * initialization: + * + * * Loading bundle metadata (JSON files) + * * Resolving extension implementations with Require + * * Registering extensions with Angular + * * Bootstrapping the Angular application. * * @constructor * @param {BundleLoader} loader @@ -18,35 +25,12 @@ define( */ function FrameworkInitializer(loader, resolver, registrar, bootstrapper) { - function registerExtensions(resolvedExtensions) { - Object.keys(resolvedExtensions).forEach(function (category) { - registrar.registerExtensions( - category, - resolvedExtensions[category] - ); - }); - } - - /** - * - * @param {Bundle[]} bundles - * @returns {Object.} an object mapping - */ - function resolveExtensions(bundles) { - return resolver.resolveBundles(bundles); - } - - function loadBundles(bundleList) { - return loader.loadBundles(bundleList); - } - return { runApplication: function (bundleList) { return loader.loadBundles(bundleList) .then(resolver.resolveBundles) .then(registrar.registerExtensions) .then(bootstrapper.bootstrap); - } }; diff --git a/platform/framework/src/Main.js b/platform/framework/src/Main.js index d1acac152f..0ec4f78198 100644 --- a/platform/framework/src/Main.js +++ b/platform/framework/src/Main.js @@ -58,7 +58,7 @@ define( resolver = new BundleResolver(new ExtensionResolver( new ImplementationLoader(require), $log - )), + ), $log), registrar = new ExtensionRegistrar( app, new CustomRegistrars(app, $log),