/***************************************************************************** * 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,Promise*/ /** * Module defining ExtensionResolver. Created by vwoeltje on 11/3/14. */ define( [], function () { "use strict"; /** * 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 * @constructor */ function ExtensionResolver(loader, $log) { function loadImplementation(extension) { var implPath = extension.getImplementationPath(), implPromise = loader.load(implPath), definition = extension.getDefinition(); // Attach values from the object definition to the // loaded implementation. function attachDefinition(impl) { var result = (typeof impl === 'function') ? function () { return impl.apply({}, arguments); } : 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 " + extension.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 ", extension.getLogName(), " due to ", err.message ].join(""); // Log that the extension was not loaded $log.warn(message); return extension.getDefinition(); } // Log that loading has begun $log.info([ "Loading implementation ", implPath, " for extension ", extension.getLogName() ].join("")); return implPromise.then(attachDefinition, handleError); } return { /** * 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 */ resolve: function (extension) { // Log that loading has begun $log.info([ "Resolving extension ", extension.getLogName() ].join("")); return extension.hasImplementation() ? loadImplementation(extension) : Promise.resolve(extension.getDefinition()); } }; } return ExtensionResolver; } );