/// <summary> /// Method to execute the command class method with the user input parameters. /// </summary> /// <param name="classData">Command class data.</param> /// <param name="inputData">User command input data.</param> /// <param name="assembly">Assembly.</param> /// <returns>String representation of the executed method.</returns> public static string ExecuteMethod(CommandClassData classData, CommandInputData inputData, Assembly assembly) { if (classData == null || assembly == null) { throw new FatalException(Constants.ErrorMessages.FatalError); } try { var parameterValues = SetParameterValues(classData, inputData); var classType = assembly.GetType($"{Constants.Commands.CommandNamespace}.{classData.Name}"); object[] methodParameterValues = null; if (parameterValues != null && parameterValues.Any()) { methodParameterValues = parameterValues.ToArray(); } return (classType.InvokeMember(inputData.MethodName, BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public, null, null, methodParameterValues).ToString()); } catch (InputException ex) { throw ex; } catch (TargetInvocationException ex) { if (ex.InnerException != null) { throw new InputException(ex.InnerException.Message); } throw new FatalException(ex.Message); } }
/// <summary> /// Parses user input to a CommandInputData object. /// </summary> /// <param name="inputCmdText"></param> /// <param name="cmdClassName"></param> /// <returns></returns> public static CommandInputData ParseInputData(string inputCmdText, string cmdClassName) { try { var result = new CommandInputData(cmdClassName); var splitted = SplitInputText(inputCmdText).ToList(); var argumentName = string.Empty; for (var i = 0; i < splitted.Count(); i++) { var split = splitted[i].Trim(); if (i == 0) //Assume that the first input argument is always the command method. { result.MethodName = split; } else { split = split.ToLower(); //Assume that the argument values are the text between less than & lt; and greater than & gt; characters. //Assume that the previous input is the argument name. if (IsArgumentValue(split, argumentName)) { split = RemoveExtraChars(split); result.Arguments.Add(argumentName, split); argumentName = string.Empty; } //If argument name is not empty and it does not have value. else if (!string.IsNullOrEmpty(argumentName)) { result.Arguments.Add(argumentName, string.Empty); argumentName = split; } else { //Set the argument name. argumentName = split; } //If last split is not empty add it as an argument. if (i == splitted.Count() - 1 && !string.IsNullOrEmpty(argumentName)) { result.Arguments.Add(argumentName, string.Empty); } } } return(result); } catch (Exception) { throw new FatalException(Constants.ErrorMessages.FatalError); } }
/// <summary> /// Validate the command input against the available command classes. /// </summary> /// <param name="cmdClasses">Command classes.</param> /// <param name="cmdInput">Command input.</param> public static void Validate(IEnumerable <CommandClassData> cmdClasses, CommandInputData cmdInput) { if (cmdClasses == null) { throw new InputException(string.Format(Constants.ErrorMessages.UnrecognizedCommandError, cmdInput.MethodName)); } var correctClass = cmdClasses.FirstOrDefault(c => c.Name == cmdInput.ClassName); if (correctClass == null) { throw new InputException(string.Format(Constants.ErrorMessages.UnrecognizedCommandError, cmdInput.MethodName)); } if (correctClass.CommandMethodData.All(cmd => cmd.MethodName != cmdInput.MethodName)) { throw new InputException(string.Format(Constants.ErrorMessages.UnrecognizedCommand, cmdInput.MethodName)); } //Get corresponding class data. var classMethod = correctClass.CommandMethodData.First(cmd => cmd.MethodName == cmdInput.MethodName); var classMethodParams = classMethod.Parameters; var requiredParams = classMethodParams.Where(p => !p.IsOptional).ToList(); var optionalParams = classMethodParams.Where(p => p.IsOptional).ToList(); //Check if values are given for arguments which require them. cmdInput.Arguments.ToList().ForEach(a => { if (classMethod.RequiredValueParams.Contains(a.Key) && string.IsNullOrEmpty(a.Value)) { throw new InputException(string.Format(Constants.ErrorMessages.ArgValueRequired, a.Key)); } }); //Check if number of given arguments is not bigger than accepted parameter count. if (cmdInput.Arguments.Count() > classMethodParams.Count) { throw new InputException(Constants.ErrorMessages.TooManyParams); } //Check if required parameters are missing. if (requiredParams.Any()) { var missingRequiredParam = ValidateRequiredParams(requiredParams, cmdInput.Arguments); if (!string.IsNullOrEmpty(missingRequiredParam)) { throw new InputException(string.Format(Constants.ErrorMessages.MissingRequiredParam, missingRequiredParam)); } } if (!requiredParams.Any() && !optionalParams.Any()) { return; } //Check if any invalid parameters exists. var invalidParameters = GetInvalidParams(optionalParams, requiredParams, cmdInput.Arguments); if (invalidParameters.Any()) { var errorMsg = CreateInvalidParameterErrorMsg(invalidParameters); throw new InputException(errorMsg); } }
public void Init() { _classData = CommandParser.ParseClassData(Constants.Commands.CommandNamespace); var arguments = new Dictionary <string, string>() { { "file", "test" }, { "project", "1" }, { "sortbystartdate", string.Empty } }; _cmdInputDataValid = new CommandInputData("Commands") { MethodName = "Read", Arguments = arguments }; _cmdInputDataInvalidClassName = new CommandInputData("Commando"); _cmdInputDataInvalidMethodName = new CommandInputData("Commands") { MethodName = "Write" }; var argumentsTwo = new Dictionary <string, string> { { "file", "test" }, { "project", "1" }, { "test", "test" }, { "test2", "test2" } }; _cmdInputDataTooManyArguments = new CommandInputData("Commands") { MethodName = "Read", Arguments = argumentsTwo }; var argumentsThree = new Dictionary <string, string> { { "file", string.Empty } }; _cmdInputDataArgumentValueMissing = new CommandInputData("Commands") { MethodName = "Read", Arguments = argumentsThree }; var argumentsFour = new Dictionary <string, string> { { "SortByStartDate", string.Empty } }; _cmdInputDataRequiredArgumentMissing = new CommandInputData("Commands") { MethodName = "Read", Arguments = argumentsFour }; var argumentsFive = new Dictionary <string, string>() { { "file", "test" }, { "project", "1" }, { "test", "test" } }; _cmdInputDataInvalidArgument = new CommandInputData("Commands") { MethodName = "Read", Arguments = argumentsFive }; }
/// <summary> /// Sets the parameter values to a command method. /// </summary> /// <param name="classData"></param> /// <param name="inputData"></param> /// <returns></returns> private static IEnumerable <object> SetParameterValues(CommandClassData classData, CommandInputData inputData) { var parameterValues = new Dictionary <string, object>(); //Get the command method data. var methodData = classData.CommandMethodData.FirstOrDefault(cmd => cmd.MethodName == inputData.MethodName); if (methodData == null) { throw new InputException(string.Format(Constants.ErrorMessages.InvalidCommand, inputData.MethodName)); } if (!methodData.Parameters.Any()) { return(null); } //Set the method parameter default values. methodData.Parameters.ForEach(mp => { parameterValues.Add(mp.Name, mp.DefaultValue); }); //Try to set method parameter values. foreach (var methodParam in methodData.Parameters) { string inputDataValue; if (!inputData.Arguments.TryGetValue(methodParam.Name, out inputDataValue)) { continue; } var paramType = methodParam.ParameterType; var value = (paramType.IsGenericType && paramType.GetGenericTypeDefinition() == typeof(Nullable <>) && string.IsNullOrEmpty(inputDataValue)) ? null : ParseParameterValue(paramType, inputDataValue); parameterValues[methodParam.Name] = value; } return(parameterValues.Values.ToList()); }