diff --git a/platform/core/bundle.json b/platform/core/bundle.json index 4b33f48f35..74d85c3c25 100644 --- a/platform/core/bundle.json +++ b/platform/core/bundle.json @@ -149,7 +149,7 @@ { "key": "composition", "implementation": "capabilities/CompositionCapability.js", - "depends": [ "$injector" ] + "depends": [ "$injector", "contextualize" ] }, { "key": "relationship", @@ -204,6 +204,11 @@ { "key": "topic", "implementation": "services/Topic.js" + }, + { + "key": "contextualize", + "implementation": "services/Contextualize.js", + "depends": [ "$log" ] } ], "roots": [ diff --git a/platform/core/src/capabilities/CompositionCapability.js b/platform/core/src/capabilities/CompositionCapability.js index f1b2532040..4204eddd39 100644 --- a/platform/core/src/capabilities/CompositionCapability.js +++ b/platform/core/src/capabilities/CompositionCapability.js @@ -25,8 +25,7 @@ * Module defining CompositionCapability. Created by vwoeltje on 11/7/14. */ define( - ["./ContextualDomainObject"], - function (ContextualDomainObject) { + function () { "use strict"; /** @@ -41,12 +40,13 @@ define( * @constructor * @implements {Capability} */ - function CompositionCapability($injector, domainObject) { + function CompositionCapability($injector, contextualize, domainObject) { // Get a reference to the object service from $injector this.injectObjectService = function () { this.objectService = $injector.get("objectService"); }; + this.contextualize = contextualize; this.domainObject = domainObject; } @@ -58,19 +58,17 @@ define( CompositionCapability.prototype.invoke = function () { var domainObject = this.domainObject, model = domainObject.getModel(), + contextualize = this.contextualize, ids; // Then filter out non-existent objects, // and wrap others (such that they expose a // "context" capability) - function contextualize(objects) { + function contextualizeObjects(objects) { return ids.filter(function (id) { return objects[id]; }).map(function (id) { - return new ContextualDomainObject( - objects[id], - domainObject - ); + return contextualize(objects[id], domainObject); }); } @@ -86,7 +84,7 @@ define( this.lastModified = model.modified; // Load from the underlying object service this.lastPromise = this.objectService.getObjects(ids) - .then(contextualize); + .then(contextualizeObjects); } return this.lastPromise; diff --git a/platform/core/src/capabilities/ContextCapability.js b/platform/core/src/capabilities/ContextCapability.js index 9ffaf4a5bb..39770f9b5b 100644 --- a/platform/core/src/capabilities/ContextCapability.js +++ b/platform/core/src/capabilities/ContextCapability.js @@ -84,7 +84,7 @@ define( parentContext = parentObject && parentObject.getCapability('context'), parentPath = parentContext ? - parentContext.getPath() : [ this.parentObject ]; + parentContext.getPath() : [ this.parentObject ]; return parentPath.concat([this.domainObject]); }; diff --git a/platform/core/src/services/Contextualize.js b/platform/core/src/services/Contextualize.js new file mode 100644 index 0000000000..d231557369 --- /dev/null +++ b/platform/core/src/services/Contextualize.js @@ -0,0 +1,78 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +/*global define*/ + +define( + ['../capabilities/ContextualDomainObject'], + function (ContextualDomainObject) { + "use strict"; + + /** + * Wrap a domain object such that it has a `context` capability + * referring to a specific parent. + * + * Usage: + * + * contextualize(domainObject, parentObject) + * + * Attempting to contextualize an object with a parent that does + * not include that object in its composition may have + * unpredictable results; a warning will be logged if this occurs. + * + * @returns {Function} + * @memberof platform/core + */ + function Contextualize($log) { + function validate(id, parentObject) { + var model = parentObject && parentObject.getModel(), + composition = (model || {}).composition || []; + if (composition.indexOf(id) === -1) { + $log.warn([ + "Attempted to contextualize", + id, + "in", + parentObject && parentObject.getId(), + "but that object does not contain", + id, + "in its composition.", + "Unexpected behavior may follow." + ].join(" ")); + } + } + + /** + * Contextualize this domain object. + * @param {DomainObject} domainObject the domain object + * to wrap with a context + * @param {DomainObject} parentObject the domain object + * which should appear as the contextual parent + */ + return function (domainObject, parentObject) { + validate(domainObject.getId(), parentObject); + return new ContextualDomainObject(domainObject, parentObject); + }; + } + + return Contextualize; + } +); +