Source: provider/convention/intentHandlerProviderByFile.js

/**
 * @author Sloan Seaman 
 * @copyright 2016 and on
 * @version .1
 * @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
 */

/** @private */
var AbstractProviderByFile = require('../abstractProviderByFile.js');
var DefaultJSFilenameFormatter = require('../defaultJSFilenameFormatter.js');
var path = require('path');
var svUtil = require('../../util.js');
var providerUtil = require('../providerUtil.js');
var log = require('winston-simple').getLogger('IntentHandlerProviderByFile');

/**
 * Provides an intent from a single file
 * 
 * Intent is loaded asynchronously but if a intent is requested before being loaded 
 * it will be immediately loaded and then skipped by the asychronous processing.
 *
 * @constructor
 * @implements {Provider}
 * @implements {ItemProvider}
 * @see {@link AbstractProviderByFile}
 * @see {@link DefaultJSFilenameFormatter}
 * @param {String} file The file that represnts an intent
 * @param {Object} options Options for the file loading
 * @param {Boolean} [options.preload=false] Should the file be preloaded or only loaded when an intent is requested.  It is generally
 *         more efficient to load only when the intent is requested.
 * @param {FileNameFormatter} [options.filenameFormatter=DefaultJSFilenameFormatter] The FilenameFormmatter to use to parse the 
 *     filenames if there are no intents specified by getIntentsList() (or if getIntentsList is not implemented)
 */
function IntentHandlerProviderByFile(file, options) {
	this._file = file;
	this._loaded = null;

	this._filenameFormatter = (options && options.filenameFormatter) 
		? options.filenameFormatter
		: new DefaultJSFilenameFormatter();

	AbstractProviderByFile.apply(this, [
		file, 
		options]);
}

IntentHandlerProviderByFile.prototype = Object.create(AbstractProviderByFile.prototype);
IntentHandlerProviderByFile.prototype.constructor = IntentHandlerProviderByFile;

/**
 * Load the file and registers it based on the list of intents specified by {@link IntentHandler.getIntentsList}. If 
 * {@link IntentHandler.getIntentsList} does not exist the intent will be registered under the name of the file as
 * parsed by the defined {@link FilenameFormatter}.
 *
 * @function
 * @param {Map} items Map of the items being processed
 * @param {String} itemId The Id of the item to process
 * @param {String} fileName The name of the file being processed
 * @param {Object} options Any options that are being passed to the ItemProcessor (can be null)
 */
IntentHandlerProviderByFile.prototype.processItem = function(items, itemId, fileName, options) {
	/*eslint no-unused-vars: ["error", { "args": "none" }]*/
	try {
		if (!this._loaded) this._loaded = svUtil.instantiate(path.resolve(process.cwd(), fileName));

		providerUtil.addFunctions(this._loaded, { 'name' : path.parse(fileName).name });

		if (svUtil.isFunction(this._loaded.getIntentsList)) {
			var handledIntents = this._loaded.getIntentsList();
			for (var i=0;i<handledIntents.length;i++) {
				if (handledIntents[i] === itemId) {
					items[handledIntents[i]] = this._loaded;
				}
			}
		}
		else {
			items[this._filenameFormatter.parse(fileName)[0]] = this._loaded;
		}
	}
	catch (err) {
		log.error("Error loading intent handler "+path.parse(fileName).base+". Error:"+err);
	}
};

/**
 * Load the file and registers it based on the list of intents specified by {@link IntentHandler.getIntentsList}. If 
 * {@link IntentHandler.getIntentsList} does not exist the intent will be registered under the name of the file as
 * parsed by the defined {@link FilenameFormatter}.
 *
 * @function
 * @param {Map} items Map of the item to process
 * @param {String} fileName The name of the file being processed
 * @param {Object} options Any options that are being passed to the ItemProcessor (can be null)
 */
IntentHandlerProviderByFile.prototype.processItems = function(items, fileName, options) {
	/*eslint no-unused-vars: ["error", { "args": "none" }]*/
	try {
		if (!this._loaded) this._loaded = new (require(path.resolve(process.cwd(), fileName)))();
		if (svUtil.isFunction(this._loaded.getIntentsList)) {
			var handledIntents = this._loaded.getIntentsList();
			for (var i=0;i<handledIntents.length;i++) {
				items[handledIntents[i]] = this._loaded;
			}
		}
		else {
			items[this._filenameFormatter.parse(fileName)[0]] = this._loaded;
		}
	}
	catch (err) {
		log.error("Error loading intent handler "+path.parse(fileName).base+". Error:"+err.stack);
	}
};

module.exports = IntentHandlerProviderByFile;