mirror of
https://github.com/nasa/openmct.git
synced 2025-02-18 16:40:58 +00:00
[Framework] Add extension sorter
Add priority ordering to loaded extensions in each category; this allows control over the resulting order of extensions acquired and used within the application. WTD-590
This commit is contained in:
parent
2bcb6a1a6e
commit
9d8885d48f
@ -16,5 +16,13 @@ define({
|
|||||||
"tests": "test",
|
"tests": "test",
|
||||||
"configuration": {},
|
"configuration": {},
|
||||||
"extensions": {}
|
"extensions": {}
|
||||||
}
|
},
|
||||||
|
PRIORITY_LEVELS: {
|
||||||
|
"fallback": Number.NEGATIVE_INFINITY,
|
||||||
|
"default": 100,
|
||||||
|
"optional": 200,
|
||||||
|
"preferred": 400,
|
||||||
|
"mandatory": Number.POSITIVE_INFINITY
|
||||||
|
},
|
||||||
|
DEFAULT_PRIORITY: 0
|
||||||
});
|
});
|
@ -26,23 +26,26 @@ define(
|
|||||||
'./resolve/RequireConfigurator',
|
'./resolve/RequireConfigurator',
|
||||||
'./register/CustomRegistrars',
|
'./register/CustomRegistrars',
|
||||||
'./register/ExtensionRegistrar',
|
'./register/ExtensionRegistrar',
|
||||||
|
'./register/ExtensionSorter',
|
||||||
'./bootstrap/ApplicationBootstrapper'
|
'./bootstrap/ApplicationBootstrapper'
|
||||||
],
|
],
|
||||||
function (require,
|
function (
|
||||||
es6promise,
|
require,
|
||||||
angular,
|
es6promise,
|
||||||
angularRoute,
|
angular,
|
||||||
Constants,
|
angularRoute,
|
||||||
FrameworkInitializer,
|
Constants,
|
||||||
BundleLoader,
|
FrameworkInitializer,
|
||||||
ImplementationLoader,
|
BundleLoader,
|
||||||
ExtensionResolver,
|
ImplementationLoader,
|
||||||
BundleResolver,
|
ExtensionResolver,
|
||||||
RequireConfigurator,
|
BundleResolver,
|
||||||
CustomRegistrars,
|
RequireConfigurator,
|
||||||
ExtensionRegistrar,
|
CustomRegistrars,
|
||||||
ApplicationBootstrapper
|
ExtensionRegistrar,
|
||||||
) {
|
ExtensionSorter,
|
||||||
|
ApplicationBootstrapper
|
||||||
|
) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// Get a reference to Angular's injector, so we can get $http and $log
|
// Get a reference to Angular's injector, so we can get $http and $log
|
||||||
@ -68,6 +71,7 @@ define(
|
|||||||
registrar = new ExtensionRegistrar(
|
registrar = new ExtensionRegistrar(
|
||||||
app,
|
app,
|
||||||
new CustomRegistrars(app, $log),
|
new CustomRegistrars(app, $log),
|
||||||
|
new ExtensionSorter($log),
|
||||||
$log
|
$log
|
||||||
),
|
),
|
||||||
bootstrapper = new ApplicationBootstrapper(
|
bootstrapper = new ApplicationBootstrapper(
|
||||||
|
@ -17,9 +17,11 @@ define(
|
|||||||
* @param {Object.<string,function>} customRegistrars an object
|
* @param {Object.<string,function>} customRegistrars an object
|
||||||
* containing custom registration functions, primarily for
|
* containing custom registration functions, primarily for
|
||||||
* Angular built-ins.
|
* Angular built-ins.
|
||||||
|
* @param {ExtensionSorter} sorter the sorter which will impose
|
||||||
|
* priority ordering upon extensions
|
||||||
* @param {*} $log Angular's logging service
|
* @param {*} $log Angular's logging service
|
||||||
*/
|
*/
|
||||||
function ExtensionRegistrar(app, customRegistrars, $log) {
|
function ExtensionRegistrar(app, customRegistrars, sorter, $log) {
|
||||||
// Track which extension categories have already been registered.
|
// Track which extension categories have already been registered.
|
||||||
// Exceptions will be thrown if the same extension category is
|
// Exceptions will be thrown if the same extension category is
|
||||||
// registered twice.
|
// registered twice.
|
||||||
@ -163,7 +165,7 @@ define(
|
|||||||
Object.keys(extensionGroup).forEach(function (category) {
|
Object.keys(extensionGroup).forEach(function (category) {
|
||||||
registerExtensionsForCategory(
|
registerExtensionsForCategory(
|
||||||
category,
|
category,
|
||||||
extensionGroup[category]
|
sorter.sort(extensionGroup[category])
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
97
platform/framework/src/register/ExtensionSorter.js
Normal file
97
platform/framework/src/register/ExtensionSorter.js
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/*global define*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
["../Constants"],
|
||||||
|
function (Constants) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Responsible for applying priority order to extensions in a
|
||||||
|
* given category. This will sort in reverse order of the numeric
|
||||||
|
* priority given for extensions in the `priority` priority (such
|
||||||
|
* that large values are registered first.) Extensions may also
|
||||||
|
* specify symbolic properties as strings (instead of numbers),
|
||||||
|
* which will be looked up from the table `Constants.PRIORITY_LEVELS`.
|
||||||
|
* @param $log Angular's logging service
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function ExtensionSorter($log) {
|
||||||
|
|
||||||
|
// Handle unknown or malformed priorities specified by extensions
|
||||||
|
function unrecognizedPriority(extension) {
|
||||||
|
// Issue a warning
|
||||||
|
$log.warn([
|
||||||
|
"Unrecognized priority '",
|
||||||
|
(extension || {}).priority,
|
||||||
|
"' specified for extension from ",
|
||||||
|
((extension || {}).bundle || {}).path,
|
||||||
|
"; defaulting to ",
|
||||||
|
Constants.DEFAULT_PRIORITY
|
||||||
|
].join(''));
|
||||||
|
|
||||||
|
// Provide a return value (default priority) to make this
|
||||||
|
// useful in an expression.
|
||||||
|
return Constants.DEFAULT_PRIORITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPriority(extension) {
|
||||||
|
var priority =
|
||||||
|
(extension || {}).priority || Constants.DEFAULT_PRIORITY;
|
||||||
|
|
||||||
|
// If it's a symbolic priority, look it up
|
||||||
|
if (typeof priority === 'string') {
|
||||||
|
priority = Constants.PRIORITY_LEVELS[priority];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should be a number; otherwise, issue a warning and
|
||||||
|
// fall back to default priority level.
|
||||||
|
return (typeof priority === 'number') ?
|
||||||
|
priority : unrecognizedPriority(extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach a numeric priority to an extension; this is done in
|
||||||
|
// one pass outside of the comparator, mainly because getPriority
|
||||||
|
// may log warnings, and we only want this to happen once
|
||||||
|
// (instead of the many times that might occur during a sort.)
|
||||||
|
function prioritize(extension, index) {
|
||||||
|
return {
|
||||||
|
// The extension itself, for later unwrapping
|
||||||
|
extension: extension,
|
||||||
|
// The index, to provide a stable sort (see compare)
|
||||||
|
index: index,
|
||||||
|
// The numeric priority of the extension
|
||||||
|
priority: getPriority(extension)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unwrap the original extension
|
||||||
|
// (for use after ordering has been applied)
|
||||||
|
function deprioritize(prioritized) {
|
||||||
|
return prioritized.extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare two prioritized extensions
|
||||||
|
function compare(a, b) {
|
||||||
|
// Reverse order by numeric priority; or, original order.
|
||||||
|
return (b.priority - a.priority) || (a.index - b.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
/**
|
||||||
|
* Sort extensions according to priority.
|
||||||
|
*
|
||||||
|
* @param {object[]} extensions array of resolved extensions
|
||||||
|
* @returns {object[]} the same extensions, in priority order
|
||||||
|
*/
|
||||||
|
sort: function (extensions) {
|
||||||
|
return (extensions || [])
|
||||||
|
.map(prioritize)
|
||||||
|
.sort(compare)
|
||||||
|
.map(deprioritize);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return ExtensionSorter;
|
||||||
|
}
|
||||||
|
);
|
Loading…
x
Reference in New Issue
Block a user