/***************************************************************************** * Open MCT, Copyright (c) 2014-2018, United States Government * as represented by the Administrator of the National Aeronautics and Space * Administration. All rights reserved. * * Open MCT 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 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. *****************************************************************************/ /** * Module defining ExtensionResolver. Created by vwoeltje on 11/3/14. */ define( [], function () { /** * An ExtensionResolver is responsible for loading any implementation * modules associated with specific extensions. * * @param {ImplementationLoader} loader used to load implementations * @param {*} $log Angular's logging service * @memberof platform/framework * @constructor */ function ExtensionResolver(loader, $log) { this.loader = loader; this.$log = $log; } /** * Resolve the provided extension; this will give a promise * for the extension's implementation, if one has been * specified, or for the plain definition of the extension * otherwise. The plain definition will also be given * if the implementation fails to load for some reason. * * All key-value pairs from the extension definition * will additionally be attached to any loaded implementation. * * @param {Extension} extension the extension to resolve * @returns {Promise} a promise for the resolved extension */ ExtensionResolver.prototype.resolve = function (extension) { var loader = this.loader, $log = this.$log; function loadImplementation(ext) { var implPromise = ext.hasImplementationValue() ? Promise.resolve(ext.getImplementationValue()) : loader.load(ext.getImplementationPath()), definition = ext.getDefinition(); // Wrap a constructor function (to avoid modifying the original) function constructorFor(impl) { function Constructor() { return impl.apply(this, arguments); } Constructor.prototype = impl.prototype; return Constructor; } // Attach values from the object definition to the // loaded implementation. function attachDefinition(impl) { var result = (typeof impl === 'function') ? constructorFor(impl) : Object.create(impl); // Copy over static properties Object.keys(impl).forEach(function (k) { result[k] = impl[k]; }); // Copy over definition Object.keys(definition).forEach(function (k) { if (result[k] === undefined) { result[k] = definition[k]; } }); result.definition = definition; // Log that this load was successful $log.info("Resolved " + ext.getLogName()); return result; } // Log any errors in loading the implementation, and // return the plain extension definition instead. function handleError(err) { // Build up a log message from parts var message = [ "Could not load implementation for extension ", ext.getLogName(), " due to ", err.message ].join(""); // Log that the extension was not loaded $log.warn(message); return ext.getDefinition(); } if (!ext.hasImplementationValue()) { // Log that loading has begun $log.info([ "Loading implementation ", ext.getImplementationPath(), " for extension ", ext.getLogName() ].join("")); } return implPromise.then(attachDefinition, handleError); } // Log that loading has begun $log.info([ "Resolving extension ", extension.getLogName() ].join("")); return extension.hasImplementation() ? loadImplementation(extension) : Promise.resolve(extension.getDefinition()); }; return ExtensionResolver; } );