CommandFactory = require("./commandFactory");
/**
* @class Controller
* @author ruckola
* @classdesc The controller does multiple things in two phases:
* <pre>
* When instantiated:
* 1) It creates a new commandContext.
* (So the kickstarter can change or add parameters to the context.)
*
* When processing:
* 2) It delegates the resolving of the action parameter to a real Command object,
* to the commandFactory.
* 4) It passes the commandContext as a parameter value into the command.
* 5) It executes the command.
* 6) It returns the result to the kickstarter.
* </pre>
* When in 'single command mode', the controller will also search for an optional config file in config dir.<br>
* This filename must be equal to the command-name, except for the extension. (myCmd.js --> myCmd.json)<br>
* Any subdirectories are ommitted.
* For macro's the configuration is loaded by the build-in {@link Macro} command.<br>
* The loading for single commands is synchronous and blocking, so it can be done here.
* For macro's it happens to be async and therefore a different strategy is needed.
* @property {CommandContext} this.context - A new instance of the CommandContext class.
*/
class Controller {
/**
* @constructor
* @description Creates a new instance of the CommandContext class.
*/
constructor() {
var CommandContext = require("./commandContext");
this.context = new CommandContext();
}
/**
* @method
* @returns {CommandContext} this.context
*/
getContext() {
return this.context;
}
/**
* @method
* @description Calls the CommandFactory to return a command. If a command is
* returned, it will try to execute the command.
*/
process() {
if (this.context.get('action') === undefined) {
throw new RangeError("No action parameter available in commandContext.");
}
if (!(typeof this.context.get('action') === 'string')) {
throw new Error("Action must be of type 'string'", 1);
}
if ((this.context.parameters.action == 'macro') &&
(typeof (this.context.parameters.macroID) === 'number')) {
var action = 'macro';
} else {
var action = this.context.get('action');
}
var cmd = CommandFactory.getCommand(action,
this.context.parameters.userCommandsRootDir);
//load any available configuration upfront.
//in single mode this is blocking code and therefore
//it can be done here.
//For macros this is done asynchronous in the macro class
//and handled with a separate promise.
if (!this.context.parameters.macroID) {//it is a single command
//get single command configuration (optional)
try {
var path = require('path');
var cfgFileDir = path.dirname(this.context.parameters.userConfigFile);
var cfgFileName = this.context.parameters.action + ".json";
var cfgFilePath = path.join(cfgFileDir, cfgFileName);
var cfg = require(cfgFilePath);
this.context.parameters.cmdConfiguration = cfg;
} catch (error) {
console.warn("Warning! - No config file found for %s-command at: %s ", action, cfgFilePath);
}
}
return cmd.execute(this.context);
}
}
module.exports = Controller;