diff --git a/src/Orchard.Tests.Modules/Recipes/Services/FoldersData/Sample1/Recipes/cms.recipe.xml b/src/Orchard.Tests.Modules/Recipes/Services/FoldersData/Sample1/Recipes/cms.recipe.xml index 5c8e77942..e32567891 100644 --- a/src/Orchard.Tests.Modules/Recipes/Services/FoldersData/Sample1/Recipes/cms.recipe.xml +++ b/src/Orchard.Tests.Modules/Recipes/Services/FoldersData/Sample1/Recipes/cms.recipe.xml @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ - + command1 @@ -40,6 +40,8 @@ + + diff --git a/src/Orchard.Tests.Modules/Recipes/Services/RecipeManagerTests.cs b/src/Orchard.Tests.Modules/Recipes/Services/RecipeManagerTests.cs index 81344a7eb..52a775b08 100644 --- a/src/Orchard.Tests.Modules/Recipes/Services/RecipeManagerTests.cs +++ b/src/Orchard.Tests.Modules/Recipes/Services/RecipeManagerTests.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.IO; +using System.Linq; using System.Xml; using Autofac; using NUnit.Framework; @@ -66,6 +67,7 @@ namespace Orchard.Tests.Modules.Recipes.Services { builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); + builder.RegisterType().As(); _container = builder.Build(); _recipeManager = _container.Resolve(); @@ -112,12 +114,36 @@ namespace Orchard.Tests.Modules.Recipes.Services { var sampleRecipe = recipes[0]; var recipeSteps = (List) sampleRecipe.RecipeSteps; - Assert.That(recipeSteps.Count, Is.EqualTo(11)); + Assert.That(recipeSteps.Count, Is.EqualTo(12)); } [Test] public void ParseRecipeThrowsOnInvalidXml() { Assert.Throws(typeof(XmlException), () => _recipeParser.ParseRecipe("")); } + + [Test] + public void ExecuteInvokesHandlersWithSteps() { + var recipes = (List)_recipeManager.DiscoverRecipes("Sample1"); + Assert.That(recipes.Count, Is.EqualTo(1)); + + var sampleRecipe = recipes[0]; + _recipeManager.Execute(sampleRecipe); + + Assert.That(CustomRecipeHandler.AttributeValue == "value1"); + } + } + + public class CustomRecipeHandler : IRecipeHandler { + public static string AttributeValue; + + public void ExecuteRecipeStep(RecipeContext recipeContext) { + if (recipeContext.RecipeStep.Name == "Custom1") { + foreach (var attribute in recipeContext.RecipeStep.Step.Attributes().Where(attribute => attribute.Name == "attr1")) { + AttributeValue = attribute.Value; + recipeContext.Executed = true; + } + } + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/Orchard.Recipes.csproj b/src/Orchard.Web/Modules/Orchard.Recipes/Orchard.Recipes.csproj index 8ecc26e8d..119a0768d 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/Orchard.Recipes.csproj +++ b/src/Orchard.Web/Modules/Orchard.Recipes/Orchard.Recipes.csproj @@ -52,6 +52,14 @@ + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/CleanUpInactiveRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/CleanUpInactiveRecipeHandler.cs new file mode 100644 index 000000000..c779ddae8 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/CleanUpInactiveRecipeHandler.cs @@ -0,0 +1,20 @@ +using Orchard.Localization; +using Orchard.Logging; +using Orchard.Recipes.Models; +using Orchard.Recipes.Services; + +namespace Orchard.Recipes.RecipeHandlers { + public class CleanUpInactiveRecipeHandler : IRecipeHandler { + public CleanUpInactiveRecipeHandler() { + Logger = NullLogger.Instance; + T = NullLocalizer.Instance; + } + + public Localizer T { get; set; } + ILogger Logger { get; set; } + + // handles the step + public void ExecuteRecipeStep(RecipeContext recipeContext) { + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/CommandRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/CommandRecipeHandler.cs new file mode 100644 index 000000000..4df974d79 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/CommandRecipeHandler.cs @@ -0,0 +1,20 @@ +using Orchard.Localization; +using Orchard.Logging; +using Orchard.Recipes.Models; +using Orchard.Recipes.Services; + +namespace Orchard.Recipes.RecipeHandlers { + public class CommandRecipeHandler : IRecipeHandler { + public CommandRecipeHandler () { + Logger = NullLogger.Instance; + T = NullLocalizer.Instance; + } + + public Localizer T { get; set; } + ILogger Logger { get; set; } + + // handles the step + public void ExecuteRecipeStep(RecipeContext recipeContext) { + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/FeatureRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/FeatureRecipeHandler.cs new file mode 100644 index 000000000..47d899c62 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/FeatureRecipeHandler.cs @@ -0,0 +1,20 @@ +using Orchard.Localization; +using Orchard.Logging; +using Orchard.Recipes.Models; +using Orchard.Recipes.Services; + +namespace Orchard.Recipes.RecipeHandlers { + public class FeatureRecipeHandler : IRecipeHandler { + public FeatureRecipeHandler() { + Logger = NullLogger.Instance; + T = NullLocalizer.Instance; + } + + public Localizer T { get; set; } + ILogger Logger { get; set; } + + // handles the step + public void ExecuteRecipeStep(RecipeContext recipeContext) { + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/MetaDataRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/MetaDataRecipeHandler.cs new file mode 100644 index 000000000..f93c034c5 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/MetaDataRecipeHandler.cs @@ -0,0 +1,20 @@ +using Orchard.Localization; +using Orchard.Logging; +using Orchard.Recipes.Models; +using Orchard.Recipes.Services; + +namespace Orchard.Recipes.RecipeHandlers { + public class MetaDataRecipeHandler : IRecipeHandler { + public MetaDataRecipeHandler() { + Logger = NullLogger.Instance; + T = NullLocalizer.Instance; + } + + public Localizer T { get; set; } + ILogger Logger { get; set; } + + // handles the step + public void ExecuteRecipeStep(RecipeContext recipeContext) { + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/MigrationRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/MigrationRecipeHandler.cs new file mode 100644 index 000000000..c5bed473a --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/MigrationRecipeHandler.cs @@ -0,0 +1,20 @@ +using Orchard.Localization; +using Orchard.Logging; +using Orchard.Recipes.Models; +using Orchard.Recipes.Services; + +namespace Orchard.Recipes.RecipeHandlers { + public class MigrationRecipeHandler : IRecipeHandler { + public MigrationRecipeHandler() { + Logger = NullLogger.Instance; + T = NullLocalizer.Instance; + } + + public Localizer T { get; set; } + ILogger Logger { get; set; } + + // handles the step + public void ExecuteRecipeStep(RecipeContext recipeContext) { + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/ModuleRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/ModuleRecipeHandler.cs new file mode 100644 index 000000000..0c39ac604 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/ModuleRecipeHandler.cs @@ -0,0 +1,20 @@ +using Orchard.Localization; +using Orchard.Logging; +using Orchard.Recipes.Models; +using Orchard.Recipes.Services; + +namespace Orchard.Recipes.RecipeHandlers { + public class ModuleRecipeHandler : IRecipeHandler { + public ModuleRecipeHandler() { + Logger = NullLogger.Instance; + T = NullLocalizer.Instance; + } + + public Localizer T { get; set; } + ILogger Logger { get; set; } + + // handles the step + public void ExecuteRecipeStep(RecipeContext recipeContext) { + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/SettingsRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/SettingsRecipeHandler.cs new file mode 100644 index 000000000..37dc5f435 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/SettingsRecipeHandler.cs @@ -0,0 +1,20 @@ +using Orchard.Localization; +using Orchard.Logging; +using Orchard.Recipes.Models; +using Orchard.Recipes.Services; + +namespace Orchard.Recipes.RecipeHandlers { + public class SettingsRecipeHandler : IRecipeHandler { + public SettingsRecipeHandler() { + Logger = NullLogger.Instance; + T = NullLocalizer.Instance; + } + + public Localizer T { get; set; } + ILogger Logger { get; set; } + + // handles the step + public void ExecuteRecipeStep(RecipeContext recipeContext) { + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/ThemeRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/ThemeRecipeHandler.cs new file mode 100644 index 000000000..8686cdb20 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/ThemeRecipeHandler.cs @@ -0,0 +1,20 @@ +using Orchard.Localization; +using Orchard.Logging; +using Orchard.Recipes.Models; +using Orchard.Recipes.Services; + +namespace Orchard.Recipes.RecipeHandlers { + public class ThemeRecipeHandler : IRecipeHandler { + public ThemeRecipeHandler() { + Logger = NullLogger.Instance; + T = NullLocalizer.Instance; + } + + public Localizer T { get; set; } + ILogger Logger { get; set; } + + // handles the step + public void ExecuteRecipeStep(RecipeContext recipeContext) { + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeManager.cs b/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeManager.cs index 86001e173..d06aa3922 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeManager.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeManager.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Linq; using Orchard.Environment.Extensions; @@ -33,7 +32,20 @@ namespace Orchard.Recipes.Services { ILogger Logger { get; set; } public void Execute(Recipe recipe) { - throw new NotImplementedException(); + var recipeContext = new RecipeContext { Recipe = recipe }; + + // TODO: Run each step inside a transaction boundary. + // TODO: Output should go into a report. + foreach (var recipeStep in recipe.RecipeSteps) { + recipeContext.RecipeStep = recipeStep; + recipeContext.Executed = false; + foreach (var handler in _recipeHandlers) { + handler.ExecuteRecipeStep(recipeContext); + } + if (!recipeContext.Executed) { + Logger.Error("Could not execute recipe step '{0}' because the recipe handler was not found.", recipeContext.RecipeStep.Name); + } + } } public IEnumerable DiscoverRecipes(string extensionName) { diff --git a/src/Orchard.Web/Modules/Orchard.Setup/Recipes/minimal.recipe.xml b/src/Orchard.Web/Modules/Orchard.Setup/Recipes/minimal.recipe.xml index e36efe1ef..5611a6b17 100644 --- a/src/Orchard.Web/Modules/Orchard.Setup/Recipes/minimal.recipe.xml +++ b/src/Orchard.Web/Modules/Orchard.Setup/Recipes/minimal.recipe.xml @@ -6,4 +6,8 @@ http://orchardproject.net developer 1.0 + + + + \ No newline at end of file