mirror of
https://github.com/nasa/openmct.git
synced 2025-06-19 15:43:48 +00:00
[Framework] Refactor source folder
Refactor framework source folder; move each initialization stage into its own directory. WTD-518.
This commit is contained in:
156
platform/framework/src/load/Bundle.js
Normal file
156
platform/framework/src/load/Bundle.js
Normal file
@ -0,0 +1,156 @@
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
['../Constants', './Extension'],
|
||||
function (Constants, Extension) {
|
||||
"use strict";
|
||||
|
||||
|
||||
/**
|
||||
* A bundle's plain JSON definition.
|
||||
*
|
||||
* @name BundleDefinition
|
||||
* @property {string} name the human-readable name of this bundle
|
||||
* @property {string} sources the name of the directory which
|
||||
* contains source code used by this bundle
|
||||
* @property {string} resources the name of the directory which
|
||||
* contains resource files used by this bundle
|
||||
* @property {Object.<string,ExtensionDefinition[]>} [extensions={}]
|
||||
* all extensions exposed by this bundle
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Instantiate a new reference to a bundle, based on its human-readable
|
||||
* definition.
|
||||
*
|
||||
* @param {string} path the path to the directory containing
|
||||
* this bundle
|
||||
* @param {BundleDefinition} bundleDefinition
|
||||
* @returns {{getDefinition: Function}}
|
||||
* @constructor
|
||||
*/
|
||||
function Bundle(path, bundleDefinition) {
|
||||
// Start with defaults
|
||||
var definition = Object.create(Constants.DEFAULT_BUNDLE),
|
||||
logName = path,
|
||||
self;
|
||||
|
||||
// Utility function for resolving paths in this bundle
|
||||
function resolvePath(elements) {
|
||||
return [path].concat(elements || []).join(Constants.SEPARATOR);
|
||||
}
|
||||
|
||||
// Override defaults with specifics from bundle definition
|
||||
Object.keys(bundleDefinition).forEach(function (k) {
|
||||
definition[k] = bundleDefinition[k];
|
||||
});
|
||||
|
||||
// Record path to bundle in definition
|
||||
definition.path = path;
|
||||
|
||||
// Build up the log-friendly name for this bundle
|
||||
if (definition.key || definition.name) {
|
||||
logName += "(";
|
||||
logName += definition.key || "";
|
||||
logName += (definition.key && definition.name) ? " " : "";
|
||||
logName += definition.name || "";
|
||||
logName += ")";
|
||||
}
|
||||
|
||||
self = {
|
||||
/**
|
||||
* Get the path to this bundle.
|
||||
* @memberof Bundle#
|
||||
* @returns {string}
|
||||
*/
|
||||
getPath: function () {
|
||||
return path;
|
||||
},
|
||||
/**
|
||||
* Get the path to this bundle's source folder. If an
|
||||
* argument is provided, the path will be to the source
|
||||
* file within the bundle's source file.
|
||||
*
|
||||
* @memberof Bundle#
|
||||
* @param {string} [sourceFile] optionally, give a path to
|
||||
* a specific source file in the bundle.
|
||||
* @returns {string}
|
||||
*/
|
||||
getSourcePath: function (sourceFile) {
|
||||
var subpath = sourceFile ?
|
||||
[ definition.sources, sourceFile ] :
|
||||
[ definition.sources ];
|
||||
|
||||
return resolvePath(subpath);
|
||||
},
|
||||
/**
|
||||
* Get the path to this bundle's resource folder. If an
|
||||
* argument is provided, the path will be to the resource
|
||||
* file within the bundle's resource file.
|
||||
*
|
||||
* @memberof Bundle#
|
||||
* @param {string} [resourceFile] optionally, give a path to
|
||||
* a specific resource file in the bundle.
|
||||
* @returns {string}
|
||||
*/
|
||||
getResourcePath: function (resourceFile) {
|
||||
var subpath = resourceFile ?
|
||||
[ definition.resources, resourceFile ] :
|
||||
[ definition.resources ];
|
||||
|
||||
return resolvePath(subpath);
|
||||
},
|
||||
/**
|
||||
* Get a log-friendly name for this bundle; this will
|
||||
* include both the key (machine-readable name for this
|
||||
* bundle) and the name (human-readable name for this
|
||||
* bundle.)
|
||||
* @returns {string} log-friendly name for this bundle
|
||||
*/
|
||||
getLogName: function () {
|
||||
return logName;
|
||||
},
|
||||
/**
|
||||
* Get all extensions exposed by this bundle of a given
|
||||
* category.
|
||||
*
|
||||
* @param category
|
||||
* @memberof Bundle#
|
||||
* @returns {Array}
|
||||
*/
|
||||
getExtensions: function (category) {
|
||||
var extensions = definition.extensions[category] || [];
|
||||
|
||||
return extensions.map(function objectify(extDefinition) {
|
||||
return new Extension(self, category, extDefinition);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Get a list of all categories of extension exposed by
|
||||
* this bundle.
|
||||
*
|
||||
* @memberof Bundle#
|
||||
* @returns {Array}
|
||||
*/
|
||||
getExtensionCategories: function () {
|
||||
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
|
||||
*/
|
||||
getDefinition: function () {
|
||||
return definition;
|
||||
}
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
return Bundle;
|
||||
}
|
||||
);
|
109
platform/framework/src/load/BundleLoader.js
Normal file
109
platform/framework/src/load/BundleLoader.js
Normal file
@ -0,0 +1,109 @@
|
||||
/*global define,Promise*/
|
||||
|
||||
/**
|
||||
* Module defining BundleLoader.js. Created by vwoeltje on 10/31/14.
|
||||
*/
|
||||
define(
|
||||
['../Constants', './Bundle'],
|
||||
function (Constants, Bundle) {
|
||||
"use strict";
|
||||
|
||||
var INVALID_ARGUMENT_MESSAGE = "Malformed loadBundles argument; " +
|
||||
"expected string or array",
|
||||
BAD_CONTENTS_PREFIX = "Invalid bundle contents for ",
|
||||
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
|
||||
* @param {object} $log Angular's logging service
|
||||
*/
|
||||
function BundleLoader($http, $log) {
|
||||
|
||||
// Utility function; load contents of JSON file using $http
|
||||
function getJSON(file) {
|
||||
return $http.get(file).then(function (response) {
|
||||
return response.data;
|
||||
});
|
||||
}
|
||||
|
||||
// Remove bundles which failed to load properly.
|
||||
// These should have been logged when loaded by
|
||||
// loadBundleDefinition, so at this point they are safe
|
||||
// to discard.
|
||||
function filterBundles(array) {
|
||||
return array.filter(function (x) { return x !== undefined; });
|
||||
}
|
||||
|
||||
// Load a definition for a bundle
|
||||
function loadBundleDefinition(bundlePath) {
|
||||
return getJSON(bundlePath + "/" + Constants.BUNDLE_FILE).then(
|
||||
function (x) {
|
||||
if (x === null || typeof x !== 'object') {
|
||||
$log.warn(BAD_CONTENTS_PREFIX + bundlePath);
|
||||
return undefined;
|
||||
}
|
||||
return x;
|
||||
},
|
||||
function () {
|
||||
$log.warn(LOAD_ERROR_PREFIX + bundlePath);
|
||||
return undefined;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
return Promise.all(bundlePromises)
|
||||
.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) :
|
||||
Promise.reject(new Error(INVALID_ARGUMENT_MESSAGE));
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
};
|
||||
}
|
||||
|
||||
return BundleLoader;
|
||||
}
|
||||
);
|
142
platform/framework/src/load/Extension.js
Normal file
142
platform/framework/src/load/Extension.js
Normal file
@ -0,0 +1,142 @@
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* An extension's plain JSON definition.
|
||||
*
|
||||
* @name ExtensionDefinition
|
||||
* @property {string} [key] the machine-readable identifier for this
|
||||
* extension
|
||||
* @property {string} [implementation] the path to the AMD module
|
||||
* which implements this extension; this path is relative
|
||||
* to the containing bundle's source folder.
|
||||
* @property {string[]} [depends=[]] the dependencies needed by this
|
||||
* extension; these are strings as shall be passed to
|
||||
* Angular's dependency resolution mechanism.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Instantiate a new extension based on its definition. This serves
|
||||
* primarily as a wrapper around the extension's definition to expose
|
||||
* a useful interface.
|
||||
*
|
||||
* An extension
|
||||
*
|
||||
* @param {Bundle} bundle the bundle which exposed this extension
|
||||
* @param {string} category the type of extension being exposed
|
||||
* @param {ExtensionDefinition} definition the plain definition of
|
||||
* this extension
|
||||
* @constructor
|
||||
*/
|
||||
function Extension(bundle, category, definition) {
|
||||
var logName = category,
|
||||
extensionDefinition = {};
|
||||
|
||||
// Build up the log-friendly name for this bundle
|
||||
if (definition.key || definition.name) {
|
||||
logName += "(";
|
||||
logName += definition.key || "";
|
||||
logName += (definition.key && definition.name) ? " " : "";
|
||||
logName += definition.name || "";
|
||||
logName += ")";
|
||||
}
|
||||
logName += " from " + bundle.getLogName();
|
||||
|
||||
// Copy over definition. This allows us to attach the bundle
|
||||
// definition without modifying the original definition object.
|
||||
Object.keys(definition).forEach(function (k) {
|
||||
extensionDefinition[k] = definition[k];
|
||||
});
|
||||
|
||||
// Attach bundle metadata
|
||||
extensionDefinition.bundle = bundle.getDefinition();
|
||||
|
||||
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}
|
||||
*/
|
||||
getBundle: function () {
|
||||
return bundle;
|
||||
},
|
||||
/**
|
||||
* Get the category into which this extension falls.
|
||||
* (e.g. "directives")
|
||||
*
|
||||
* @memberof Extension#
|
||||
* @returns {string}
|
||||
*/
|
||||
getCategory: function () {
|
||||
return category;
|
||||
},
|
||||
/**
|
||||
* 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;
|
||||
},
|
||||
/**
|
||||
* Get the path to the AMD module which implements this
|
||||
* extension. Will return undefined if there is no
|
||||
* implementation associated with this extension.
|
||||
*
|
||||
* @memberof Extension#
|
||||
* @returns {string} path to implementation, or undefined
|
||||
*/
|
||||
getImplementationPath: function () {
|
||||
return definition.implementation ?
|
||||
bundle.getSourcePath(definition.implementation) :
|
||||
undefined;
|
||||
},
|
||||
/**
|
||||
* Get a log-friendly name for this extension; this will
|
||||
* include both the key (machine-readable name for this
|
||||
* extension) and the name (human-readable name for this
|
||||
* extension.)
|
||||
* @returns {string} log-friendly name for this extension
|
||||
*/
|
||||
getLogName: function () {
|
||||
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} the plain definition of
|
||||
* this extension, as read from the bundle
|
||||
* declaration.
|
||||
*/
|
||||
getDefinition: function () {
|
||||
return extensionDefinition;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
return Extension;
|
||||
|
||||
}
|
||||
);
|
Reference in New Issue
Block a user