From a233856bacd2a49d512b7d00ff053cf2cfd76364 Mon Sep 17 00:00:00 2001
From: Victor Woeltjen <victor.woeltjen@nasa.gov>
Date: Thu, 17 Sep 2015 13:15:42 -0700
Subject: [PATCH] [Core] Separate out contextualize

Separate out contextualize function to facilitate
reuse from entanglement bundle. nasa/openmctweb#84
---
 platform/core/bundle.json                     |  7 +-
 .../src/capabilities/CompositionCapability.js | 16 ++--
 .../src/capabilities/ContextCapability.js     |  2 +-
 platform/core/src/services/Contextualize.js   | 78 +++++++++++++++++++
 4 files changed, 92 insertions(+), 11 deletions(-)
 create mode 100644 platform/core/src/services/Contextualize.js

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;
+    }
+);
+