define([
'module',
'bop/js/BOPSelectionInterceptor',
'bop/js/api/BOPInterceptors',
'bop/js/api/BOPRegistry',
'core/js/api/utils/StringUtils',
'extensions.dt/js/api/ExtensionOperations',
'text!bop/templates/BOPInitializer.js'
], function (
module,
BOPSelectionInterceptor,
BOPInterceptors,
BOPRegistry,
StringUtils,
ExtensionOperations,
BOPInitializerTemplate
) {
'use strict';
/**
* Wraps an instance of {@link bop/js/spi/SimpleBOP SimpleBOP} as an implementation of {@link extensions.dt/js/spi/ExtensionManager ExtensionManager}.
*
* <p>
* It takes care of few aspects that you would have to do manually otherwise (resp. if implemented as pure {@link bop/js/spi/BOP BOP}). In summary:
*
* <ul>
* <li>
* No need to take care of {@link extensions.dt/js/spi/ExtensionManager ExtensionManager} lifecycle manually.
* </li>
* <li>
* No need to write method generating RT code manually.
* </li>
* <li>
* No need to take care of {@link bop.dt/js/spi/BOPExtensionManager~BOPExtensionDependencyFormat BOPExtensionDependencyFormat} to register only selected
* {@link entity/js/api/Entity Entities} and {@link entity/js/api/Property Properties} into the Application Builder data model.
* </li>
* </ul>
* </p>
*
* @AbcsExtension stable
* @version 17.1.1
* @exports bop.dt/js/api/SimpleBOPExtensionManager
*
* @constructor
* @public
*
* @see {@link bop/js/spi/SimpleBOP SimpleBOP}
* @see {@link extensions.dt/js/spi/ExtensionManager ExtensionManager}
*
* @param {bop/js/spi/SimpleBOP} simpleBOP
*
* @example
* <caption>
* Typical implementation creating <code>SimpleBOPExtensionManager<code> and passing custom {@link bop/js/spi/SimpleBOP SimpleBOP} into it.
* </caption>
*
* define([
* 'bop.dt/js/api/SimpleBOPExtensionManager'
* ], function (
* SimpleBOPExtensionManager
* ) {
*
* var CustomBOP = function () {
* };
*
* CustomBOP.prototype.getEntityProviderPath = function () {
* return '{{package}}/js/CustomEntityProvider';
* };
*
* CustomBOP.prototype.getOperationProviderPath = function () {
* return '{{package}}/js/CustomOperationProvider';
* };
*
* return new SimpleBOPExtensionManager(new CustomBOP());
* });
*/
var SimpleBOPExtensionManager = function (simpleBOP) {
AbcsLib.checkThis(this);
this._simpleBOP = simpleBOP;
};
SimpleBOPExtensionManager._LOGGER = Logger.get(module.id);
SimpleBOPExtensionManager.prototype.initialise = function (dependencies) {
var self = this;
return new Promise(function (fulfil, reject) {
var entityProviderPath = self._getEntityProviderPath();
var operationProviderPath = self._getOperationProviderPath();
var shareable = ExtensionOperations._findShareableForEM(self);
require([
entityProviderPath,
operationProviderPath
], function (
EntityProviderImpl,
OperationProviderImpl
) {
var BOPImpl = function() {
this._entityProvider = undefined;
this._operationProvider = undefined;
};
BOPImpl.prototype.getEntityProvider = function() {
try {
if (!this._entityProvider) {
this._entityProvider = new EntityProviderImpl();
}
} catch (error) {
SimpleBOPExtensionManager._LOGGER.error('Couldn\'t initialize EntityProvider with path: "' + entityProviderPath + '".');
if (error) {
SimpleBOPExtensionManager._LOGGER.error(error.stack ? error.stack : error);
}
}
return this._entityProvider;
};
BOPImpl.prototype.getOperationProvider = function() {
try {
if (!this._operationProvider) {
this._operationProvider = new OperationProviderImpl(dependencies);
}
} catch (error) {
SimpleBOPExtensionManager._LOGGER.error('Couldn\'t initialize OperationProvider with path: "' + operationProviderPath + '"');
if (error) {
SimpleBOPExtensionManager._LOGGER.error(error.stack ? error.stack : error);
}
}
return this._operationProvider;
};
BOPImpl.prototype.getId = function() {
return shareable.getId();
};
self._bop = new BOPImpl();
var selectionInterceptor = new BOPSelectionInterceptor(dependencies);
BOPInterceptors.addInterceptor(selectionInterceptor);
try {
BOPRegistry.register(self._bop, self).then(function() {
SimpleBOPExtensionManager._LOGGER.info('SimpleBOP initialised');
BOPInterceptors.removeInterceptor(selectionInterceptor);
fulfil();
}).catch(function(error) {
SimpleBOPExtensionManager._LOGGER.warn('SimpleBOP NOT properly initialised.');
BOPInterceptors.removeInterceptor(selectionInterceptor);
reject(error);
});
} catch (exception) {
reject(exception);
}
}, function(error) {
var unloadedModules = error.requireModules;
if (unloadedModules) {
reject(new Error(AbcsLib.i18n('bopDt.unloadedModules', {
unloadedModules: unloadedModules
})));
} else {
reject(error);
}
});
});
};
SimpleBOPExtensionManager.prototype.destroy = function () {
var self = this;
return BOPRegistry.deregister(self._bop, self).then(function() {
self._bop = undefined;
});
};
SimpleBOPExtensionManager.prototype.generateRuntimeCode = function(dependencies, extension) {
var self = this;
var map = {
entityProviderPath: self._getEntityProviderPath(),
operationProviderPath: self._getOperationProviderPath(),
shareableID: extension.getId(),
dependencies : AbcsLib.stringify(dependencies.map(function(dependency) {
return dependency.getDefinition();
}))
};
return StringUtils.resolveTemplate(BOPInitializerTemplate, map, ['$', '$']);
};
/**
* If the path is not defined as a String, don't even attempt to require it.
*
* @returns {String}
*/
SimpleBOPExtensionManager.prototype._getEntityProviderPath = function() {
var self = this;
var entityProviderPath = self._simpleBOP.getEntityProviderPath();
AbcsLib.checkDefined(entityProviderPath, 'entityProviderPath');
AbcsLib.checkDataType(entityProviderPath, AbcsLib.Type.STRING);
return entityProviderPath;
};
/**
* If the path is not defined as a String, don't even attempt to require it.
*
* @returns {String}
*/
SimpleBOPExtensionManager.prototype._getOperationProviderPath = function() {
var self = this;
var operationProviderPath = self._simpleBOP.getOperationProviderPath();
AbcsLib.checkDefined(operationProviderPath, 'operationProviderPath');
AbcsLib.checkDataType(operationProviderPath, AbcsLib.Type.STRING);
return operationProviderPath;
};
return SimpleBOPExtensionManager;
});