[Framework] Add comments, logging

Add additional comments and logging to components
of the framework layer. WTD-518.
This commit is contained in:
Victor Woeltjen 2014-11-04 17:17:35 -08:00
parent 3ed3ee19d7
commit dbd5b148e2
10 changed files with 136 additions and 34 deletions

View File

@ -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

View File

@ -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;

View File

@ -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.<Bundle[]>}
*/
loadBundles: loadBundles
};
}

View File

@ -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.<string, object[]>[]} resolvedBundles
* @returns {Object.<string, 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.<string, 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);

View File

@ -1,7 +1,7 @@
/*global define*/
/**
* Constants used by the framework.
* Constants used by the framework layer.
*/
define({
MODULE_NAME: "OpenMCTWeb",

View File

@ -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"),

View File

@ -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;

View File

@ -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.<string,function>} 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.<string, 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
};
}

View File

@ -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.<string, 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);
}
};

View File

@ -58,7 +58,7 @@ define(
resolver = new BundleResolver(new ExtensionResolver(
new ImplementationLoader(require),
$log
)),
), $log),
registrar = new ExtensionRegistrar(
app,
new CustomRegistrars(app, $log),