mirror of
https://github.com/nasa/openmct.git
synced 2025-01-31 08:25:31 +00:00
[Containment] Add general policy for containment rules
Add general policy for supporting containment rules, WTD-962.
This commit is contained in:
parent
3c3dd0ad17
commit
3c00eb86ea
2
platform/containment/README.md
Normal file
2
platform/containment/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
Implements support for rules which determine which objects are allowed
|
||||
to contain other objects, typically by type.
|
53
platform/containment/src/CapabilityTable.js
Normal file
53
platform/containment/src/CapabilityTable.js
Normal file
@ -0,0 +1,53 @@
|
||||
/*global define*/
|
||||
|
||||
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Build a table indicating which types are expected to expose
|
||||
* which capabilities.
|
||||
*/
|
||||
function CapabilityTable(typeService, capabilityService) {
|
||||
var table = {};
|
||||
|
||||
// Build an initial model for a type
|
||||
function buildModel(type) {
|
||||
var model = Object.create(type.getInitialModel() || {});
|
||||
model.type = type.getKey();
|
||||
return model;
|
||||
}
|
||||
|
||||
// Get capabilities expected for this type
|
||||
function getCapabilities(type) {
|
||||
return capabilityService.getCapabilities(buildModel(type));
|
||||
}
|
||||
|
||||
// Populate the lookup table for this type's capabilities
|
||||
function addToTable(type) {
|
||||
var typeKey = type.getKey();
|
||||
Object.keys(getCapabilities(type)).forEach(function (key) {
|
||||
table[key] = table[key] || {};
|
||||
table[key][typeKey] = true;
|
||||
});
|
||||
}
|
||||
|
||||
// Build the table
|
||||
(typeService.listTypes() || []).forEach(addToTable);
|
||||
|
||||
return {
|
||||
/**
|
||||
* Check if a type is expected to expose a specific
|
||||
* capability.
|
||||
*/
|
||||
hasCapability: function (typeKey, capabilityKey) {
|
||||
return (table[capabilityKey] || {})[typeKey];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return CapabilityTable;
|
||||
}
|
||||
);
|
29
platform/containment/src/CompositionPolicy.js
Normal file
29
platform/containment/src/CompositionPolicy.js
Normal file
@ -0,0 +1,29 @@
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
['./ContainmentTable'],
|
||||
function (ContainmentTable) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Defines composition policy as driven by type metadata.
|
||||
*/
|
||||
function CompositionPolicy(typeService, capabilityService) {
|
||||
// We're really just wrapping the containment table and rephrasing
|
||||
// it as a policy decision.
|
||||
var table = new ContainmentTable(typeService, capabilityService);
|
||||
|
||||
return {
|
||||
/**
|
||||
* Is the type identified by the candidate allowed to
|
||||
* contain the type described by the context?
|
||||
*/
|
||||
allow: function (candidate, context) {
|
||||
return table.canContain(candidate, context);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return CompositionPolicy;
|
||||
}
|
||||
);
|
98
platform/containment/src/ContainmentTable.js
Normal file
98
platform/containment/src/ContainmentTable.js
Normal file
@ -0,0 +1,98 @@
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
['./CapabilityTable'],
|
||||
function (CapabilityTable) {
|
||||
"use strict";
|
||||
|
||||
// Symbolic value for the type table for cases when any type
|
||||
// is allowed to be contained.
|
||||
var ANY = true;
|
||||
|
||||
/**
|
||||
* Supports composition policy by maintaining a table of
|
||||
* domain object types, to determine if they can contain
|
||||
* other domain object types. This is determined at application
|
||||
* start time (plug-in support means this cannot be determined
|
||||
* prior to that, but we don't want to redo these calculations
|
||||
* every time policy is checked.)
|
||||
*/
|
||||
function ContainmentTable(typeService, capabilityService) {
|
||||
var types = typeService.listTypes(),
|
||||
capabilityTable = new CapabilityTable(typeService, capabilityService),
|
||||
table = {};
|
||||
|
||||
// Check if one type can contain another
|
||||
function canContain(containerType, containedType) {
|
||||
}
|
||||
|
||||
// Add types which have all these capabilities to the set
|
||||
// of allowed types
|
||||
function addToSetByCapability(set, has) {
|
||||
has = Array.isArray(has) ? has : [has];
|
||||
types.forEach(function (type) {
|
||||
var typeKey = type.getKey();
|
||||
set[typeKey] = has.map(function (capabilityKey) {
|
||||
return capabilityTable.hasCapability(typeKey, capabilityKey);
|
||||
}).reduce(function (a, b) {
|
||||
return a && b;
|
||||
}, true);
|
||||
});
|
||||
}
|
||||
|
||||
// Add this type (or type description) to the set of allowed types
|
||||
function addToSet(set, type) {
|
||||
// Is this a simple case of an explicit type identifier?
|
||||
if (typeof type === 'string') {
|
||||
// If so, add it to the set of allowed types
|
||||
set[type] = true;
|
||||
} else {
|
||||
// Otherwise, populate that set based on capabilities
|
||||
addToSetByCapability(set, (type || {}).has || []);
|
||||
}
|
||||
}
|
||||
|
||||
// Add to the lookup table for this type
|
||||
function addToTable(type) {
|
||||
var key = type.getKey(),
|
||||
definition = type.getDefinition() || {},
|
||||
contains = definition.contains;
|
||||
|
||||
// Check for defined containment restrictions
|
||||
if (contains === undefined) {
|
||||
// If not, accept anything
|
||||
table[key] = ANY;
|
||||
} else {
|
||||
// Start with an empty set...
|
||||
table[key] = {};
|
||||
// ...cast accepted types to array if necessary...
|
||||
contains = Array.isArray(contains) ? contains : [contains];
|
||||
// ...and add all containment rules to that set
|
||||
contains.forEach(function (c) {
|
||||
addToSet(table[key], c);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Build the table
|
||||
types.forEach(addToTable);
|
||||
|
||||
return {
|
||||
/**
|
||||
* Check if domain objects of one type can contain domain
|
||||
* objects of another type.
|
||||
* @returns {boolean} true if allowable
|
||||
*/
|
||||
canContain: function (containerType, containedType) {
|
||||
var set = table[containerType.getKey()] || {};
|
||||
// Recognize either the symbolic value for "can contain
|
||||
// anything", or lookup the specific type from the set.
|
||||
return (set === ANY) || set[containedType.getKey()];
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
return ContainmentTable;
|
||||
}
|
||||
);
|
Loading…
x
Reference in New Issue
Block a user