diff --git a/src/Orchard.Tests/Commands/CommandHandlerTests.cs b/src/Orchard.Tests/Commands/CommandHandlerTests.cs index 7c4931e05..54bc64a0c 100644 --- a/src/Orchard.Tests/Commands/CommandHandlerTests.cs +++ b/src/Orchard.Tests/Commands/CommandHandlerTests.cs @@ -1,4 +1,5 @@ -using NUnit.Framework; +using System.Collections.Specialized; +using NUnit.Framework; using Orchard.Commands; using System; @@ -27,20 +28,86 @@ namespace Orchard.Tests.Commands { [Test] public void TestCommandWithCustomAlias() { - CommandContext commandContext = new CommandContext { Command = "bar" }; + CommandContext commandContext = new CommandContext { Command = "Bar" }; _handler.Execute(commandContext); Assert.That(commandContext.Output, Is.EqualTo("Hello World!")); } + + [Test] + public void TestBooleanSwitchForCommand() { + CommandContext commandContext = new CommandContext { Command = "Baz", Switches = new NameValueCollection() }; + commandContext.Switches.Add("Verbose", "true"); + _handler.Execute(commandContext); + Assert.That(commandContext.Output, Is.EqualTo("Command Baz Called : This was a test")); + } + + [Test] + public void TestIntSwitchForCommand() { + CommandContext commandContext = new CommandContext { Command = "Baz", Switches = new NameValueCollection() }; + commandContext.Switches.Add("Level", "2"); + _handler.Execute(commandContext); + Assert.That(commandContext.Output, Is.EqualTo("Command Baz Called : Entering Level 2")); + } + + [Test] + public void TestStringSwitchForCommand() { + CommandContext commandContext = new CommandContext { Command = "Baz", Switches = new NameValueCollection() }; + commandContext.Switches.Add("User", "OrchardUser"); + _handler.Execute(commandContext); + Assert.That(commandContext.Output, Is.EqualTo("Command Baz Called : current user is OrchardUser")); + } + + [Test] + public void TestSwitchForCommandWithoutSupportForIt() { + CommandContext commandContext = new CommandContext { Command = "Foo", Switches = new NameValueCollection() }; + commandContext.Switches.Add("User", "OrchardUser"); + Assert.Throws(() => _handler.Execute(commandContext)); + } + + [Test] + public void TestNotExistingSwitch() { + CommandContext commandContext = new CommandContext { Command = "Foo", Switches = new NameValueCollection() }; + commandContext.Switches.Add("ThisSwitchDoesNotExist", "Insignificant"); + Assert.Throws(() => _handler.Execute(commandContext)); + } } public class StubCommandHandler : DefaultOrchardCommandHandler { + [OrchardSwitch] + public bool Verbose { get; set; } + + [OrchardSwitch] + public int Level { get; set; } + + [OrchardSwitch] + public string User { get; set; } + public string Foo() { return "Command Foo Executed"; } - [OrchardCommand("bar")] + [OrchardCommand("Bar")] public string Hello() { return "Hello World!"; } + + [OrchardSwitches("Verbose, Level, User")] + public string Baz() { + string trace = "Command Baz Called"; + + if (Verbose) { + trace += " : This was a test"; + } + + if (Level == 2) { + trace += " : Entering Level 2"; + } + + if (!String.IsNullOrEmpty(User)) { + trace += " : current user is " + User; + } + + return trace; + } } } diff --git a/src/Orchard/Commands/CommandContext.cs b/src/Orchard/Commands/CommandContext.cs index 1405a2a8b..223ba3542 100644 --- a/src/Orchard/Commands/CommandContext.cs +++ b/src/Orchard/Commands/CommandContext.cs @@ -1,8 +1,10 @@ -namespace Orchard.Commands { +using System.Collections.Specialized; + +namespace Orchard.Commands { public class CommandContext { public string Input { get; set; } public string Output { get; set; } public string Command { get; set; } - public string[] Arguments { get; set; } + public NameValueCollection Switches { get; set; } } } diff --git a/src/Orchard/Commands/DefaultOrchardCommandHandler.cs b/src/Orchard/Commands/DefaultOrchardCommandHandler.cs index 9b3b209ed..227898a66 100644 --- a/src/Orchard/Commands/DefaultOrchardCommandHandler.cs +++ b/src/Orchard/Commands/DefaultOrchardCommandHandler.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Collections.Specialized; using System.Reflection; using Orchard.Localization; @@ -13,14 +15,46 @@ namespace Orchard.Commands { #region Implementation of ICommandHandler public void Execute(CommandContext context) { + if (context.Switches != null && context.Switches.Count > 0) { + foreach (var commandSwitch in context.Switches.AllKeys) { + PropertyInfo propertyInfo = GetType().GetProperty(commandSwitch); + if (propertyInfo == null) { + throw new InvalidOperationException(T("Switch : ") + commandSwitch + T(" was not found")); + } + if (propertyInfo.GetCustomAttributes(typeof(OrchardSwitchAttribute), false).Length == 0) { + throw new InvalidOperationException(T("A property of the name ") + commandSwitch + T(" exists but is not decorated with the OrchardSwitch attribute")); + } + string stringValue = context.Switches[commandSwitch]; + if (propertyInfo.PropertyType.IsAssignableFrom(typeof(bool))) { + bool boolValue; + Boolean.TryParse(stringValue, out boolValue); + propertyInfo.SetValue(this, boolValue, null); + } + else if (propertyInfo.PropertyType.IsAssignableFrom(typeof(int))) { + int intValue; + Int32.TryParse(stringValue, out intValue); + propertyInfo.SetValue(this, intValue, null); + } + else if (propertyInfo.PropertyType.IsAssignableFrom(typeof(string))) { + propertyInfo.SetValue(this, stringValue, null); + } + else { + throw new InvalidOperationException(T("No property named ") + commandSwitch + + T(" found of type bool, int or string")); + } + } + } + foreach (MethodInfo methodInfo in GetType().GetMethods()) { if (String.Equals(methodInfo.Name, context.Command, StringComparison.OrdinalIgnoreCase)) { + CheckMethodForSwitches(methodInfo, context.Switches); context.Output = (string)methodInfo.Invoke(this, null); return; } foreach (OrchardCommandAttribute commandAttribute in methodInfo.GetCustomAttributes(typeof(OrchardCommandAttribute), false)) { if (String.Equals(commandAttribute.Command, context.Command, StringComparison.OrdinalIgnoreCase)) { + CheckMethodForSwitches(methodInfo, context.Switches); context.Output = (string)methodInfo.Invoke(this, null); return; } @@ -30,6 +64,21 @@ namespace Orchard.Commands { throw new InvalidOperationException(T("Command : ") + context.Command + T(" was not found")); } + private void CheckMethodForSwitches(MethodInfo methodInfo, NameValueCollection switches) { + if (switches == null || switches.AllKeys.Length == 0) + return; + List supportedSwitches = new List(); + foreach (OrchardSwitchesAttribute switchesAttribute in methodInfo.GetCustomAttributes(typeof(OrchardSwitchesAttribute), false)) { + supportedSwitches.AddRange(switchesAttribute.SwitchName); + } + foreach (var commandSwitch in switches.AllKeys) { + if (!supportedSwitches.Contains(commandSwitch)) { + throw new InvalidOperationException(T("Method ") + methodInfo.Name + + T(" does not support switch ") + commandSwitch); + } + } + } + #endregion } } diff --git a/src/Orchard/Commands/CommandAttribute.cs b/src/Orchard/Commands/OrchardCommandAttribute.cs similarity index 100% rename from src/Orchard/Commands/CommandAttribute.cs rename to src/Orchard/Commands/OrchardCommandAttribute.cs diff --git a/src/Orchard/Commands/OrchardSwitchAttribute.cs b/src/Orchard/Commands/OrchardSwitchAttribute.cs new file mode 100644 index 000000000..f69f9f4ef --- /dev/null +++ b/src/Orchard/Commands/OrchardSwitchAttribute.cs @@ -0,0 +1,7 @@ +using System; + +namespace Orchard.Commands { + [AttributeUsage(AttributeTargets.Property)] + public class OrchardSwitchAttribute : Attribute { + } +} diff --git a/src/Orchard/Commands/OrchardSwitchesAttribute.cs b/src/Orchard/Commands/OrchardSwitchesAttribute.cs new file mode 100644 index 000000000..b83bb06f5 --- /dev/null +++ b/src/Orchard/Commands/OrchardSwitchesAttribute.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; + +namespace Orchard.Commands { + [AttributeUsage(AttributeTargets.Method)] + public class OrchardSwitchesAttribute : Attribute { + private readonly IEnumerable _switches; + + public OrchardSwitchesAttribute(string switches) { + List switchList = new List(); + foreach (var s in switches.Split(',')) { + switchList.Add(s.Trim()); + } + _switches = switchList; + } + + public IEnumerable SwitchName { + get { return _switches; } + } + + } +} diff --git a/src/Orchard/Orchard.csproj b/src/Orchard/Orchard.csproj index e1761a564..ca785bc74 100644 --- a/src/Orchard/Orchard.csproj +++ b/src/Orchard/Orchard.csproj @@ -129,10 +129,12 @@ - + + +