From 901c11a1ea5c0866fa8f183257d83e3a1a37c9d2 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Wed, 15 Jul 2015 12:53:19 +0100 Subject: [PATCH] Simplifying recipe step API for implementers. --- .../Orchard.Tests.Modules.csproj | 2 +- ...RecipeHandlerTest.cs => ModuleStepTest.cs} | 504 +++++++++--------- .../RecipeHandlers/ThemeRecipeHandlerTest.cs | 49 +- .../Commands/ImportExportCommands.cs | 2 +- .../Orchard.Recipes/Orchard.Recipes.csproj | 24 +- .../ContentRecipeBuilderStep.cs | 4 +- ...sBuilderStep.cs => SettingsBuilderStep.cs} | 12 +- .../CommandStep.cs} | 408 +++++++------- .../ContentSchemaStep.cs} | 184 +++---- .../ContentStep.cs} | 226 ++++---- .../FeatureStep.cs} | 142 +++-- .../MigrationStep.cs} | 144 +++-- .../ModuleStep.cs} | 206 ++++--- .../SettingsStep.cs} | 189 +++---- .../ThemeStep.cs} | 259 +++++---- .../RecipeExecutionStepHandler.cs | 29 + .../Services/IRecipeExecutionStep.cs | 6 + .../Services/RecipeExecutionContext.cs | 8 + .../Services/RecipeExecutionStep.cs | 6 + .../Orchard.Recipes/Services/RecipeManager.cs | 1 + .../Services/RecipeStepExecutor.cs | 12 +- .../{SiteSettings.cshtml => Settings.cshtml} | 0 22 files changed, 1178 insertions(+), 1239 deletions(-) rename src/Orchard.Tests.Modules/Recipes/RecipeHandlers/{ModuleRecipeHandlerTest.cs => ModuleStepTest.cs} (85%) rename src/Orchard.Web/Modules/Orchard.Recipes/RecipeBuilders/{SiteSettingsBuilderStep.cs => SettingsBuilderStep.cs} (91%) rename src/Orchard.Web/Modules/Orchard.Recipes/{RecipeHandlers/CommandRecipeHandler.cs => RecipeExecutionSteps/CommandStep.cs} (85%) rename src/Orchard.Web/Modules/Orchard.Recipes/{RecipeHandlers/MetaDataRecipeHandler.cs => RecipeExecutionSteps/ContentSchemaStep.cs} (78%) rename src/Orchard.Web/Modules/Orchard.Recipes/{RecipeHandlers/DataRecipeHandler.cs => RecipeExecutionSteps/ContentStep.cs} (67%) rename src/Orchard.Web/Modules/Orchard.Recipes/{RecipeHandlers/FeatureRecipeHandler.cs => RecipeExecutionSteps/FeatureStep.cs} (72%) rename src/Orchard.Web/Modules/Orchard.Recipes/{RecipeHandlers/MigrationRecipeHandler.cs => RecipeExecutionSteps/MigrationStep.cs} (65%) rename src/Orchard.Web/Modules/Orchard.Recipes/{RecipeHandlers/ModuleRecipeHandler.cs => RecipeExecutionSteps/ModuleStep.cs} (75%) rename src/Orchard.Web/Modules/Orchard.Recipes/{RecipeHandlers/SettingsRecipeHandler.cs => RecipeExecutionSteps/SettingsStep.cs} (67%) rename src/Orchard.Web/Modules/Orchard.Recipes/{RecipeHandlers/ThemeRecipeHandler.cs => RecipeExecutionSteps/ThemeStep.cs} (80%) create mode 100644 src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/RecipeExecutionStepHandler.cs create mode 100644 src/Orchard.Web/Modules/Orchard.Recipes/Services/IRecipeExecutionStep.cs create mode 100644 src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeExecutionContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeExecutionStep.cs rename src/Orchard.Web/Modules/Orchard.Recipes/Views/EditorTemplates/ExportSteps/{SiteSettings.cshtml => Settings.cshtml} (100%) diff --git a/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj b/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj index c0b316f4e..f9805895b 100644 --- a/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj +++ b/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj @@ -159,7 +159,7 @@ - + diff --git a/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ModuleRecipeHandlerTest.cs b/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ModuleStepTest.cs similarity index 85% rename from src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ModuleRecipeHandlerTest.cs rename to src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ModuleStepTest.cs index 7d4c86a96..8a4f169e0 100644 --- a/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ModuleRecipeHandlerTest.cs +++ b/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ModuleStepTest.cs @@ -1,252 +1,252 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Xml.Linq; -using Autofac; -using NuGet; -using NUnit.Framework; -using Orchard.Caching; -using Orchard.Core.Settings.Descriptor; -using Orchard.Core.Settings.Descriptor.Records; -using Orchard.Core.Settings.State; -using Orchard.Data.Migration; -using Orchard.Environment.Configuration; -using Orchard.Environment.Descriptor; -using Orchard.Environment.Descriptor.Models; -using Orchard.Environment.Extensions; -using Orchard.Environment.Extensions.Folders; -using Orchard.Environment.Extensions.Models; -using Orchard.Environment.Features; -using Orchard.Environment.State; -using Orchard.Events; -using Orchard.Packaging.GalleryServer; -using Orchard.Packaging.Models; -using Orchard.Packaging.Services; -using Orchard.Recipes.Models; -using Orchard.Recipes.RecipeHandlers; -using Orchard.Recipes.Services; -using Orchard.Tests.Environment.Extensions; -using Orchard.Tests.Environment.Features; -using Orchard.Tests.Stubs; -using IPackageManager = Orchard.Packaging.Services.IPackageManager; -using Orchard.Tests.Modules.Recipes.Services; - -namespace Orchard.Tests.Modules.Recipes.RecipeHandlers { - [TestFixture] - public class ModuleRecipeHandlerTest : DatabaseEnabledTestsBase { - private ExtensionManagerTests.StubFolders _folders; - private StubPackagingSourceManager _packagesInRepository; - private StubPackageManager _packageManager; - - protected override IEnumerable DatabaseTypes { - get { - return new[] { - typeof (ShellDescriptorRecord), - typeof (ShellFeatureRecord), - typeof (ShellParameterRecord), - }; - } - } - - public override void Register(ContainerBuilder builder) { - builder.RegisterInstance(new ShellSettings { Name = "Default" }); - - _folders = new ExtensionManagerTests.StubFolders(); - _packagesInRepository = new StubPackagingSourceManager(); - _packageManager = new StubPackageManager(); - builder.RegisterInstance(_folders).As(); - builder.RegisterType().As(); - builder.RegisterType().As(); - builder.RegisterType().As(); - builder.RegisterType().As(); - builder.RegisterType().As(); - builder.RegisterType().As().SingleInstance(); - builder.RegisterType().As(); - builder.RegisterInstance(_packagesInRepository).As(); - builder.RegisterInstance(_packageManager).As(); - builder.RegisterType().As().SingleInstance(); - builder.RegisterType().As().SingleInstance(); - builder.RegisterType(); - builder.RegisterSource(new EventsRegistrationSource()); - } - - [Test] - public void ExecuteRecipeStepTest() { - _folders.Manifests.Add("SuperWiki", @" -Name: SuperWiki -Version: 1.0.3 -OrchardVersion: 1 -Features: - SuperWiki: - Description: My super wiki module for Orchard. -"); - _packagesInRepository.AddPublishedPackage(new PublishedPackage { - Id = "Orchard.Module.SuperWiki", - PackageType = DefaultExtensionTypes.Module, - Title = "SuperWiki", - Version = "1.0.3", - IsLatestVersion = true, - }); - - IShellDescriptorManager shellDescriptorManager = _container.Resolve(); - // No features enabled - shellDescriptorManager.UpdateShellDescriptor(0, - Enumerable.Empty(), - Enumerable.Empty()); - - ModuleRecipeHandler moduleRecipeHandler = _container.Resolve(); - - RecipeContext recipeContext = new RecipeContext { RecipeStep = new RecipeStep { Name = "Module", Step = new XElement("SuperWiki") } }; - recipeContext.RecipeStep.Step.Add(new XAttribute("packageId", "Orchard.Module.SuperWiki")); - recipeContext.RecipeStep.Step.Add(new XAttribute("repository", "test")); - - IFeatureManager featureManager = _container.Resolve(); - IEnumerable enabledFeatures = featureManager.GetEnabledFeatures(); - Assert.That(enabledFeatures.Count(), Is.EqualTo(0)); - moduleRecipeHandler.ExecuteRecipeStep(recipeContext); - - - var availableFeatures = featureManager.GetAvailableFeatures().Where(x => x.Id == "SuperWiki").FirstOrDefault(); - Assert.That(availableFeatures.Id, Is.EqualTo("SuperWiki")); - Assert.That(recipeContext.Executed, Is.True); - } - - [Test] - public void ExecuteRecipeStepNeedsNameTest() { - _folders.Manifests.Add("SuperWiki", @" -Name: SuperWiki -Version: 1.0.3 -OrchardVersion: 1 -Features: - SuperWiki: - Description: My super wiki module for Orchard. -"); - - ModuleRecipeHandler moduleRecipeHandler = _container.Resolve(); - - RecipeContext recipeContext = new RecipeContext { RecipeStep = new RecipeStep { Name = "Module", Step = new XElement("SuperWiki") } }; - recipeContext.RecipeStep.Step.Add(new XAttribute("repository", "test")); - - Assert.Throws(typeof (InvalidOperationException), () => moduleRecipeHandler.ExecuteRecipeStep(recipeContext)); - } - - [Test] - public void ExecuteRecipeStepWithRepositoryAndVersionNotLatestTest() { - _packagesInRepository.AddPublishedPackage(new PublishedPackage { - Id = "Orchard.Module.SuperWiki", - PackageType = DefaultExtensionTypes.Module, - Title = "SuperWiki", - Version = "1.0.3", - IsLatestVersion = true, - }); - _packagesInRepository.AddPublishedPackage(new PublishedPackage { - Id = "Orchard.Module.SuperWiki", - PackageType = DefaultExtensionTypes.Module, - Title = "SuperWiki", - Version = "1.0.2", - IsLatestVersion = false, - }); - - ModuleRecipeHandler moduleRecipeHandler = _container.Resolve(); - - RecipeContext recipeContext = new RecipeContext { RecipeStep = new RecipeStep { Name = "Module", Step = new XElement("SuperWiki") } }; - recipeContext.RecipeStep.Step.Add(new XAttribute("packageId", "Orchard.Module.SuperWiki")); - recipeContext.RecipeStep.Step.Add(new XAttribute("repository", "test")); - recipeContext.RecipeStep.Step.Add(new XAttribute("version", "1.0.2")); - - moduleRecipeHandler.ExecuteRecipeStep(recipeContext); - - var installedPackage = _packageManager.GetInstalledPackages().FirstOrDefault(info => info.ExtensionName == "Orchard.Module.SuperWiki"); - Assert.That(installedPackage, Is.Not.Null); - Assert.That(installedPackage.ExtensionVersion, Is.EqualTo("1.0.2")); - Assert.That(recipeContext.Executed, Is.True); - } - - internal class StubPackagingSourceManager : IPackagingSourceManager { - private List _publishedPackages = new List(); - - public IEnumerable GetSources() { - return Enumerable.Empty(); - } - - public int AddSource(string feedTitle, string feedUrl) { - throw new NotImplementedException(); - } - - public void RemoveSource(int id) { - throw new NotImplementedException(); - } - - public IEnumerable GetExtensionList(bool includeScreenshots, PackagingSource packagingSource = null, Func, IQueryable> query = null) { - return query(_publishedPackages.AsQueryable()).Select(package => CreatePackagingEntry(package)); - } - - public int GetExtensionCount(PackagingSource packagingSource = null, Func, IQueryable> query = null) { - throw new NotImplementedException(); - } - - public void AddPublishedPackage(PublishedPackage package) { - _publishedPackages.Add(package); - } - - private static PackagingEntry CreatePackagingEntry(PublishedPackage package) { - return new PackagingEntry { - PackageId = package.Id, - Title = package.Title, - Version = package.Version, - }; - } - } - - internal class StubPackageManager : IPackageManager { - private IList _installedPackages = new List(); - - public IEnumerable GetInstalledPackages() { - return _installedPackages; - } - - public PackageData Harvest(string extensionName) { - throw new NotImplementedException(); - } - - public PackageInfo Install(IPackage package, string location, string applicationPath) { - return null; - } - - public PackageInfo Install(string packageId, string version, string location, string applicationPath) { - var package = new PackageInfo { - ExtensionName = packageId, - ExtensionVersion = version, - }; - _installedPackages.Add(package); - return package; - } - - public void Uninstall(string packageId, string applicationPath) { - } - - public ExtensionDescriptor GetExtensionDescriptor(IPackage package, string extensionType) { - throw new NotImplementedException(); - } - } - - internal class StubDataMigrationManager : IDataMigrationManager { - public bool IsFeatureAlreadyInstalled(string feature) { - return true; - } - - public IEnumerable GetFeaturesThatNeedUpdate() { - return Enumerable.Empty(); - } - - public void Update(string feature) { - } - - public void Update(IEnumerable features) { - } - - public void Uninstall(string feature) { - } - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; +using Autofac; +using NuGet; +using NUnit.Framework; +using Orchard.Caching; +using Orchard.Core.Settings.Descriptor; +using Orchard.Core.Settings.Descriptor.Records; +using Orchard.Core.Settings.State; +using Orchard.Data.Migration; +using Orchard.Environment.Configuration; +using Orchard.Environment.Descriptor; +using Orchard.Environment.Descriptor.Models; +using Orchard.Environment.Extensions; +using Orchard.Environment.Extensions.Folders; +using Orchard.Environment.Extensions.Models; +using Orchard.Environment.Features; +using Orchard.Environment.State; +using Orchard.Events; +using Orchard.Packaging.GalleryServer; +using Orchard.Packaging.Models; +using Orchard.Packaging.Services; +using Orchard.Recipes.Models; +using Orchard.Recipes.RecipeExecutionSteps; +using Orchard.Recipes.Services; +using Orchard.Tests.Environment.Extensions; +using Orchard.Tests.Environment.Features; +using Orchard.Tests.Stubs; +using IPackageManager = Orchard.Packaging.Services.IPackageManager; + +namespace Orchard.Tests.Modules.Recipes.RecipeHandlers { + [TestFixture] + public class ModuleStepTest : DatabaseEnabledTestsBase { + private ExtensionManagerTests.StubFolders _folders; + private StubPackagingSourceManager _packagesInRepository; + private StubPackageManager _packageManager; + + protected override IEnumerable DatabaseTypes { + get { + return new[] { + typeof (ShellDescriptorRecord), + typeof (ShellFeatureRecord), + typeof (ShellParameterRecord), + }; + } + } + + public override void Register(ContainerBuilder builder) { + builder.RegisterInstance(new ShellSettings { Name = "Default" }); + + _folders = new ExtensionManagerTests.StubFolders(); + _packagesInRepository = new StubPackagingSourceManager(); + _packageManager = new StubPackageManager(); + builder.RegisterInstance(_folders).As(); + builder.RegisterType().As(); + builder.RegisterType().As(); + builder.RegisterType().As(); + builder.RegisterType().As(); + builder.RegisterType().As(); + builder.RegisterType().As().SingleInstance(); + builder.RegisterType().As(); + builder.RegisterInstance(_packagesInRepository).As(); + builder.RegisterInstance(_packageManager).As(); + builder.RegisterType().As().SingleInstance(); + builder.RegisterType().As().SingleInstance(); + builder.RegisterType(); + builder.RegisterSource(new EventsRegistrationSource()); + } + + [Test] + public void ExecuteRecipeStepTest() { + _folders.Manifests.Add("SuperWiki", @" +Name: SuperWiki +Version: 1.0.3 +OrchardVersion: 1 +Features: + SuperWiki: + Description: My super wiki module for Orchard. +"); + _packagesInRepository.AddPublishedPackage(new PublishedPackage { + Id = "Orchard.Module.SuperWiki", + PackageType = DefaultExtensionTypes.Module, + Title = "SuperWiki", + Version = "1.0.3", + IsLatestVersion = true, + }); + + IShellDescriptorManager shellDescriptorManager = _container.Resolve(); + // No features enabled + shellDescriptorManager.UpdateShellDescriptor(0, + Enumerable.Empty(), + Enumerable.Empty()); + + var moduleStep = _container.Resolve(); + var recipeContext = new RecipeContext { RecipeStep = new RecipeStep { Name = "Module", Step = new XElement("SuperWiki") } }; + var recipeExecutionContext = new RecipeExecutionContext {RecipeStep = recipeContext.RecipeStep}; + recipeContext.RecipeStep.Step.Add(new XAttribute("packageId", "Orchard.Module.SuperWiki")); + recipeContext.RecipeStep.Step.Add(new XAttribute("repository", "test")); + + IFeatureManager featureManager = _container.Resolve(); + IEnumerable enabledFeatures = featureManager.GetEnabledFeatures(); + Assert.That(enabledFeatures.Count(), Is.EqualTo(0)); + moduleStep.Execute(recipeExecutionContext); + + + var availableFeatures = featureManager.GetAvailableFeatures().Where(x => x.Id == "SuperWiki").FirstOrDefault(); + Assert.That(availableFeatures.Id, Is.EqualTo("SuperWiki")); + Assert.That(recipeContext.Executed, Is.True); + } + + [Test] + public void ExecuteRecipeStepNeedsNameTest() { + _folders.Manifests.Add("SuperWiki", @" +Name: SuperWiki +Version: 1.0.3 +OrchardVersion: 1 +Features: + SuperWiki: + Description: My super wiki module for Orchard. +"); + + var moduleStep = _container.Resolve(); + var recipeContext = new RecipeContext { RecipeStep = new RecipeStep { Name = "Module", Step = new XElement("SuperWiki") } }; + var recipeExecutionContext = new RecipeExecutionContext { RecipeStep = recipeContext.RecipeStep }; + recipeContext.RecipeStep.Step.Add(new XAttribute("repository", "test")); + + Assert.Throws(typeof (InvalidOperationException), () => moduleStep.Execute(recipeExecutionContext)); + } + + [Test] + public void ExecuteRecipeStepWithRepositoryAndVersionNotLatestTest() { + _packagesInRepository.AddPublishedPackage(new PublishedPackage { + Id = "Orchard.Module.SuperWiki", + PackageType = DefaultExtensionTypes.Module, + Title = "SuperWiki", + Version = "1.0.3", + IsLatestVersion = true, + }); + _packagesInRepository.AddPublishedPackage(new PublishedPackage { + Id = "Orchard.Module.SuperWiki", + PackageType = DefaultExtensionTypes.Module, + Title = "SuperWiki", + Version = "1.0.2", + IsLatestVersion = false, + }); + + var moduleStep = _container.Resolve(); + var recipeContext = new RecipeContext { RecipeStep = new RecipeStep { Name = "Module", Step = new XElement("SuperWiki") } }; + var recipeExecutionContext = new RecipeExecutionContext { RecipeStep = recipeContext.RecipeStep }; + + recipeContext.RecipeStep.Step.Add(new XAttribute("packageId", "Orchard.Module.SuperWiki")); + recipeContext.RecipeStep.Step.Add(new XAttribute("repository", "test")); + recipeContext.RecipeStep.Step.Add(new XAttribute("version", "1.0.2")); + + moduleStep.Execute(recipeExecutionContext); + + var installedPackage = _packageManager.GetInstalledPackages().FirstOrDefault(info => info.ExtensionName == "Orchard.Module.SuperWiki"); + Assert.That(installedPackage, Is.Not.Null); + Assert.That(installedPackage.ExtensionVersion, Is.EqualTo("1.0.2")); + Assert.That(recipeContext.Executed, Is.True); + } + + internal class StubPackagingSourceManager : IPackagingSourceManager { + private readonly List _publishedPackages = new List(); + + public IEnumerable GetSources() { + return Enumerable.Empty(); + } + + public int AddSource(string feedTitle, string feedUrl) { + throw new NotImplementedException(); + } + + public void RemoveSource(int id) { + throw new NotImplementedException(); + } + + public IEnumerable GetExtensionList(bool includeScreenshots, PackagingSource packagingSource = null, Func, IQueryable> query = null) { + return query(_publishedPackages.AsQueryable()).Select(package => CreatePackagingEntry(package)); + } + + public int GetExtensionCount(PackagingSource packagingSource = null, Func, IQueryable> query = null) { + throw new NotImplementedException(); + } + + public void AddPublishedPackage(PublishedPackage package) { + _publishedPackages.Add(package); + } + + private static PackagingEntry CreatePackagingEntry(PublishedPackage package) { + return new PackagingEntry { + PackageId = package.Id, + Title = package.Title, + Version = package.Version, + }; + } + } + + internal class StubPackageManager : IPackageManager { + private readonly IList _installedPackages = new List(); + + public IEnumerable GetInstalledPackages() { + return _installedPackages; + } + + public PackageData Harvest(string extensionName) { + throw new NotImplementedException(); + } + + public PackageInfo Install(IPackage package, string location, string applicationPath) { + return null; + } + + public PackageInfo Install(string packageId, string version, string location, string applicationPath) { + var package = new PackageInfo { + ExtensionName = packageId, + ExtensionVersion = version, + }; + _installedPackages.Add(package); + return package; + } + + public void Uninstall(string packageId, string applicationPath) { + } + + public ExtensionDescriptor GetExtensionDescriptor(IPackage package, string extensionType) { + throw new NotImplementedException(); + } + } + + internal class StubDataMigrationManager : IDataMigrationManager { + public bool IsFeatureAlreadyInstalled(string feature) { + return true; + } + + public IEnumerable GetFeaturesThatNeedUpdate() { + return Enumerable.Empty(); + } + + public void Update(string feature) { + } + + public void Update(IEnumerable features) { + } + + public void Uninstall(string feature) { + } + } + } +} diff --git a/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ThemeRecipeHandlerTest.cs b/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ThemeRecipeHandlerTest.cs index 115d320b3..66de2afeb 100644 --- a/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ThemeRecipeHandlerTest.cs +++ b/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ThemeRecipeHandlerTest.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Web.Hosting; using System.Xml.Linq; using Autofac; using NUnit.Framework; @@ -23,21 +22,21 @@ using Orchard.FileSystems.VirtualPath; using Orchard.Packaging.GalleryServer; using Orchard.Packaging.Services; using Orchard.Recipes.Models; -using Orchard.Recipes.RecipeHandlers; +using Orchard.Recipes.RecipeExecutionSteps; +using Orchard.Recipes.Services; using Orchard.Tests.DisplayManagement.Descriptors; using Orchard.Tests.Environment.Extensions; using Orchard.Tests.Environment.Features; using Orchard.Tests.Stubs; using Orchard.Tests.UI.Navigation; using Orchard.Themes.Services; -using IPackageManager = Orchard.Packaging.Services.IPackageManager; namespace Orchard.Tests.Modules.Recipes.RecipeHandlers { [TestFixture] public class ThemeRecipeHandlerTest : DatabaseEnabledTestsBase { private ExtensionManagerTests.StubFolders _folders; - private ModuleRecipeHandlerTest.StubPackagingSourceManager _packagesInRepository; - private ModuleRecipeHandlerTest.StubPackageManager _packageManager; + private ModuleStepTest.StubPackagingSourceManager _packagesInRepository; + private ModuleStepTest.StubPackageManager _packageManager; protected override IEnumerable DatabaseTypes { get { @@ -50,13 +49,13 @@ namespace Orchard.Tests.Modules.Recipes.RecipeHandlers { } public override void Register(ContainerBuilder builder) { - var _testVirtualPathProvider = new StylesheetBindingStrategyTests.TestVirtualPathProvider(); + var testVirtualPathProvider = new StylesheetBindingStrategyTests.TestVirtualPathProvider(); builder.RegisterInstance(new ShellSettings { Name = "Default" }); _folders = new ExtensionManagerTests.StubFolders(); - _packagesInRepository = new ModuleRecipeHandlerTest.StubPackagingSourceManager(); - _packageManager = new ModuleRecipeHandlerTest.StubPackageManager(); + _packagesInRepository = new ModuleStepTest.StubPackagingSourceManager(); + _packageManager = new ModuleStepTest.StubPackageManager(); builder.RegisterInstance(_folders).As(); builder.RegisterType().As(); builder.RegisterType().As(); @@ -64,16 +63,16 @@ namespace Orchard.Tests.Modules.Recipes.RecipeHandlers { builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As().SingleInstance(); - builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterInstance(_packagesInRepository).As(); builder.RegisterInstance(_packageManager).As(); builder.RegisterType().As().SingleInstance(); - builder.RegisterInstance(_testVirtualPathProvider).As(); + builder.RegisterInstance(testVirtualPathProvider).As(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); - builder.RegisterType(); + builder.RegisterType(); builder.RegisterSource(new EventsRegistrationSource()); } @@ -101,16 +100,17 @@ Features: Enumerable.Empty(), Enumerable.Empty()); - ThemeRecipeHandler themeRecipeHandler = _container.Resolve(); + var themeStep = _container.Resolve(); + var recipeContext = new RecipeContext { RecipeStep = new RecipeStep { Name = "Theme", Step = new XElement("SuperWiki") } }; + var recipeExecutionContext = new RecipeExecutionContext {RecipeStep = recipeContext.RecipeStep}; - RecipeContext recipeContext = new RecipeContext { RecipeStep = new RecipeStep { Name = "Theme", Step = new XElement("SuperWiki") } }; recipeContext.RecipeStep.Step.Add(new XAttribute("packageId", "Orchard.Theme.SuperWiki")); recipeContext.RecipeStep.Step.Add(new XAttribute("repository", "test")); - IFeatureManager featureManager = _container.Resolve(); - IEnumerable enabledFeatures = featureManager.GetEnabledFeatures(); + var featureManager = _container.Resolve(); + var enabledFeatures = featureManager.GetEnabledFeatures(); Assert.That(enabledFeatures.Count(), Is.EqualTo(0)); - themeRecipeHandler.ExecuteRecipeStep(recipeContext); + themeStep.Execute(recipeExecutionContext); // without setting enable no feature should be activated... featureManager.GetEnabledFeatures(); @@ -118,7 +118,7 @@ Features: // Adding enable the feature should get active recipeContext.RecipeStep.Step.Add(new XAttribute("enable", true)); - themeRecipeHandler.ExecuteRecipeStep(recipeContext); + themeStep.Execute(recipeExecutionContext); enabledFeatures = featureManager.GetEnabledFeatures(); Assert.That(enabledFeatures.FirstOrDefault(feature => feature.Id.Equals("SuperWiki")), Is.Not.Null); @@ -137,12 +137,12 @@ Features: Description: My super wiki module for Orchard. "); - ThemeRecipeHandler themeRecipeHandler = _container.Resolve(); + var themeStep = _container.Resolve(); + var recipeContext = new RecipeContext { RecipeStep = new RecipeStep { Name = "Theme", Step = new XElement("SuperWiki") } }; + var recipeExecutionContext = new RecipeExecutionContext { RecipeStep = recipeContext.RecipeStep }; - RecipeContext recipeContext = new RecipeContext { RecipeStep = new RecipeStep { Name = "Theme", Step = new XElement("SuperWiki") } }; recipeContext.RecipeStep.Step.Add(new XAttribute("repository", "test")); - - Assert.Throws(typeof (InvalidOperationException), () => themeRecipeHandler.ExecuteRecipeStep(recipeContext)); + Assert.Throws(typeof (InvalidOperationException), () => themeStep.Execute(recipeExecutionContext)); } [Test] @@ -162,14 +162,15 @@ Features: IsLatestVersion = false, }); - ThemeRecipeHandler themeRecipeHandler = _container.Resolve(); + var themeStep = _container.Resolve(); + var recipeContext = new RecipeContext { RecipeStep = new RecipeStep { Name = "Theme", Step = new XElement("SuperWiki") } }; + var recipeExecutionContext = new RecipeExecutionContext { RecipeStep = recipeContext.RecipeStep }; - RecipeContext recipeContext = new RecipeContext { RecipeStep = new RecipeStep { Name = "Theme", Step = new XElement("SuperWiki") } }; recipeContext.RecipeStep.Step.Add(new XAttribute("packageId", "Orchard.Theme.SuperWiki")); recipeContext.RecipeStep.Step.Add(new XAttribute("repository", "test")); recipeContext.RecipeStep.Step.Add(new XAttribute("version", "1.0.2")); - themeRecipeHandler.ExecuteRecipeStep(recipeContext); + themeStep.Execute(recipeExecutionContext); var installedPackage = _packageManager.GetInstalledPackages().FirstOrDefault(info => info.ExtensionName == "Orchard.Theme.SuperWiki"); Assert.That(installedPackage, Is.Not.Null); diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/Commands/ImportExportCommands.cs b/src/Orchard.Web/Modules/Orchard.ImportExport/Commands/ImportExportCommands.cs index eb747250d..afe76fcfd 100644 --- a/src/Orchard.Web/Modules/Orchard.ImportExport/Commands/ImportExportCommands.cs +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/Commands/ImportExportCommands.cs @@ -113,7 +113,7 @@ namespace Orchard.ImportExport.Commands { } if (SiteSettings) { - var siteSettingsStep = _orchardServices.WorkContext.Resolve(); + var siteSettingsStep = _orchardServices.WorkContext.Resolve(); recipeBuilderSteps.Add(siteSettingsStep); } diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/Orchard.Recipes.csproj b/src/Orchard.Web/Modules/Orchard.Recipes/Orchard.Recipes.csproj index a33c16a5b..c4801b337 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/Orchard.Recipes.csproj +++ b/src/Orchard.Web/Modules/Orchard.Recipes/Orchard.Recipes.csproj @@ -84,18 +84,22 @@ - - - - - - - - - + + + + + + + + + + + + + @@ -152,7 +156,7 @@ - + 10.0 diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeBuilders/ContentRecipeBuilderStep.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeBuilders/ContentRecipeBuilderStep.cs index d2491ef73..4bc714a90 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeBuilders/ContentRecipeBuilderStep.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeBuilders/ContentRecipeBuilderStep.cs @@ -104,11 +104,11 @@ namespace Orchard.Recipes.RecipeBuilders { partsElement.Add(_contentDefinitionWriter.Export(part)); } - return new XElement("Metadata", typesElement, partsElement); + return new XElement("ContentSchema", typesElement, partsElement); } private XElement ExportData(IEnumerable contentTypes, IEnumerable contentItems, int? batchSize) { - var data = new XElement("Data"); + var data = new XElement("Content"); if (batchSize.HasValue && batchSize.Value > 0) data.SetAttributeValue("BatchSize", batchSize); diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeBuilders/SiteSettingsBuilderStep.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeBuilders/SettingsBuilderStep.cs similarity index 91% rename from src/Orchard.Web/Modules/Orchard.Recipes/RecipeBuilders/SiteSettingsBuilderStep.cs rename to src/Orchard.Web/Modules/Orchard.Recipes/RecipeBuilders/SettingsBuilderStep.cs index bdeb15da5..e37fed5a6 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeBuilders/SiteSettingsBuilderStep.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeBuilders/SettingsBuilderStep.cs @@ -7,23 +7,23 @@ using Orchard.Recipes.Services; using Orchard.Recipes.ViewModels; namespace Orchard.Recipes.RecipeBuilders { - public class SiteSettingsBuilderStep : RecipeBuilderStep { + public class SettingsBuilderStep : RecipeBuilderStep { private readonly IOrchardServices _orchardServices; - public SiteSettingsBuilderStep(IOrchardServices orchardServices) { + public SettingsBuilderStep(IOrchardServices orchardServices) { _orchardServices = orchardServices; } public override string Name { - get { return "SiteSettings"; } + get { return "Settings"; } } public override LocalizedString DisplayName { - get { return T("Site Settings"); } + get { return T("Settings"); } } public override LocalizedString Description { - get { return T("Exports site settings."); } + get { return T("Exports settings."); } } public override int Priority { get { return 20; } } @@ -34,7 +34,7 @@ namespace Orchard.Recipes.RecipeBuilders { public override dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater) { var viewModel = new SiteSettingsStepViewModel(); - return shapeFactory.EditorTemplate(TemplateName: "ExportSteps/SiteSettings", Model: viewModel, Prefix: Prefix); + return shapeFactory.EditorTemplate(TemplateName: "ExportSteps/Settings", Model: viewModel, Prefix: Prefix); } public override void Build(BuildContext context) { diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/CommandRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/CommandStep.cs similarity index 85% rename from src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/CommandRecipeHandler.cs rename to src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/CommandStep.cs index ee3fdae68..f9e5c7f3a 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/CommandRecipeHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/CommandStep.cs @@ -1,212 +1,198 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using Orchard.Commands; -using Orchard.Localization; -using Orchard.Logging; -using Orchard.Recipes.Models; -using Orchard.Recipes.Services; - -namespace Orchard.Recipes.RecipeHandlers { - public class CommandRecipeHandler : IRecipeHandler { - private readonly ICommandManager _commandManager; - private readonly CommandParser _commandParser; - - public CommandRecipeHandler(ICommandManager commandManager) { - _commandManager = commandManager; - _commandParser = new CommandParser(); - Logger = NullLogger.Instance; - T = NullLocalizer.Instance; - } - - public Localizer T { get; set; } - public ILogger Logger { get; set; } - - /* - - command1 - command2 - command3 - - */ - // run Orchard commands. - public void ExecuteRecipeStep(RecipeContext recipeContext) { - if (!String.Equals(recipeContext.RecipeStep.Name, "Command", StringComparison.OrdinalIgnoreCase)) { - return; - } - - Logger.Information("Executing recipe step '{0}'; ExecutionId={1}", recipeContext.RecipeStep.Name, recipeContext.ExecutionId); - - var commands = - recipeContext.RecipeStep.Step.Value - .Split(new[] {"\r\n", "\n"}, StringSplitOptions.RemoveEmptyEntries) - .Select(commandEntry => commandEntry.Trim()); - - foreach (var command in commands) { - if (!String.IsNullOrEmpty(command)) { - Logger.Information("Executing command: {0}", command); - try { - var commandParameters = _commandParser.ParseCommandParameters(command); - var input = new StringReader(""); - var output = new StringWriter(); - _commandManager.Execute(new CommandParameters { Arguments = commandParameters.Arguments, Input = input, Output = output, Switches = commandParameters.Switches }); - } - catch (Exception ex) { - Logger.Error(ex, "Error while executing command: {0}", command); - throw; - } - } - } - - recipeContext.Executed = true; - Logger.Information("Finished executing recipe step '{0}'.", recipeContext.RecipeStep.Name); - } - } - - // Utility class for parsing lines of commands. - // Note: This lexer handles double quotes pretty harshly by design. - // In case you needed them in your arguments, hopefully single quotes work for you as a replacement on the receiving end. - class CommandParser { - public CommandParameters ParseCommandParameters(string command) { - var args = SplitArgs(command); - var arguments = new List(); - var result = new CommandParameters { - Switches = new Dictionary() - }; - - foreach (var arg in args) { - if (arg.StartsWith("/")) { - //If arg is not empty and starts with '/' - - int index = arg.IndexOf(':'); - var switchName = (index < 0 ? arg.Substring(1) : arg.Substring(1, index - 1)); - var switchValue = (index < 0 || index >= arg.Length ? string.Empty : arg.Substring(index + 1)); - - if (string.IsNullOrEmpty(switchName)) - { - throw new ArgumentException(string.Format("Invalid switch syntax: \"{0}\". Valid syntax is /[:].", arg)); - } - - result.Switches.Add(switchName, switchValue); - } - else { - arguments.Add(arg); - } - } - - result.Arguments = arguments; - return result; - } - - class State { - private readonly string _commandLine; - private readonly StringBuilder _stringBuilder; - private readonly List _arguments; - private int _index; - - public State(string commandLine) { - _commandLine = commandLine; - _stringBuilder = new StringBuilder(); - _arguments = new List(); - } - - public StringBuilder StringBuilder { get { return _stringBuilder; } } - public bool EOF { get { return _index >= _commandLine.Length; } } - public char Current { get { return _commandLine[_index]; } } - public IEnumerable Arguments { get { return _arguments; } } - - public void AddArgument() { - _arguments.Add(StringBuilder.ToString()); - StringBuilder.Clear(); - } - - public void AppendCurrent() { - StringBuilder.Append(Current); - } - - public void Append(char ch) { - StringBuilder.Append(ch); - } - - public void MoveNext() { - if (!EOF) - _index++; - } - } - - /// - /// Implement the same logic as found at - /// http://msdn.microsoft.com/en-us/library/17w5ykft.aspx - /// The 3 special characters are quote, backslash and whitespaces, in order - /// of priority. - /// The semantics of a quote is: whatever the state of the lexer, copy - /// all characters verbatim until the next quote or EOF. - /// The semantics of backslash is: If the next character is a backslash or a quote, - /// copy the next character. Otherwise, copy the backslash and the next character. - /// The semantics of whitespace is: end the current argument and move on to the next one. - /// - private static IEnumerable SplitArgs(string commandLine) { - var state = new State(commandLine); - while (!state.EOF) { - switch (state.Current) { - case '"': - ProcessQuote(state); - break; - - case '\\': - ProcessBackslash(state); - break; - - case ' ': - case '\t': - if (state.StringBuilder.Length > 0) - state.AddArgument(); - state.MoveNext(); - break; - - default: - state.AppendCurrent(); - state.MoveNext(); - break; - } - } - if (state.StringBuilder.Length > 0) - state.AddArgument(); - return state.Arguments; - } - - private static void ProcessQuote(State state) { - state.MoveNext(); - while (!state.EOF) { - if (state.Current == '"') { - state.MoveNext(); - break; - } - state.AppendCurrent(); - state.MoveNext(); - } - - state.AddArgument(); - } - - private static void ProcessBackslash(State state) { - state.MoveNext(); - if (state.EOF) { - state.Append('\\'); - return; - } - - if (state.Current == '"') { - state.Append('"'); - state.MoveNext(); - } - else { - state.Append('\\'); - state.AppendCurrent(); - state.MoveNext(); - } - } - } +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using Orchard.Commands; +using Orchard.Logging; +using Orchard.Recipes.Services; + +namespace Orchard.Recipes.RecipeExecutionSteps { + public class CommandStep : RecipeExecutionStep { + private readonly ICommandManager _commandManager; + private readonly CommandParser _commandParser; + + public CommandStep(ICommandManager commandManager) { + _commandManager = commandManager; + _commandParser = new CommandParser(); + } + + public override string Name { get { return "Command"; } } + + /* + + command1 + command2 + command3 + + */ + // Run Orchard commands. + public override void Execute(RecipeExecutionContext context) { + var commands = + context.RecipeStep.Step.Value + .Split(new[] {"\r\n", "\n"}, StringSplitOptions.RemoveEmptyEntries) + .Select(commandEntry => commandEntry.Trim()); + + foreach (var command in commands) { + if (!String.IsNullOrEmpty(command)) { + Logger.Information("Executing command: {0}", command); + try { + var commandParameters = _commandParser.ParseCommandParameters(command); + var input = new StringReader(""); + var output = new StringWriter(); + _commandManager.Execute(new CommandParameters { Arguments = commandParameters.Arguments, Input = input, Output = output, Switches = commandParameters.Switches }); + } + catch (Exception ex) { + Logger.Error(ex, "Error while executing command: {0}", command); + throw; + } + } + } + } + } + + // Utility class for parsing lines of commands. + // Note: This lexer handles double quotes pretty harshly by design. + // In case you needed them in your arguments, hopefully single quotes work for you as a replacement on the receiving end. + class CommandParser { + public CommandParameters ParseCommandParameters(string command) { + var args = SplitArgs(command); + var arguments = new List(); + var result = new CommandParameters { + Switches = new Dictionary() + }; + + foreach (var arg in args) { + if (arg.StartsWith("/")) { + //If arg is not empty and starts with '/' + + int index = arg.IndexOf(':'); + var switchName = (index < 0 ? arg.Substring(1) : arg.Substring(1, index - 1)); + var switchValue = (index < 0 || index >= arg.Length ? string.Empty : arg.Substring(index + 1)); + + if (string.IsNullOrEmpty(switchName)) + { + throw new ArgumentException(string.Format("Invalid switch syntax: \"{0}\". Valid syntax is /[:].", arg)); + } + + result.Switches.Add(switchName, switchValue); + } + else { + arguments.Add(arg); + } + } + + result.Arguments = arguments; + return result; + } + + class State { + private readonly string _commandLine; + private readonly StringBuilder _stringBuilder; + private readonly List _arguments; + private int _index; + + public State(string commandLine) { + _commandLine = commandLine; + _stringBuilder = new StringBuilder(); + _arguments = new List(); + } + + public StringBuilder StringBuilder { get { return _stringBuilder; } } + public bool EOF { get { return _index >= _commandLine.Length; } } + public char Current { get { return _commandLine[_index]; } } + public IEnumerable Arguments { get { return _arguments; } } + + public void AddArgument() { + _arguments.Add(StringBuilder.ToString()); + StringBuilder.Clear(); + } + + public void AppendCurrent() { + StringBuilder.Append(Current); + } + + public void Append(char ch) { + StringBuilder.Append(ch); + } + + public void MoveNext() { + if (!EOF) + _index++; + } + } + + /// + /// Implement the same logic as found at + /// http://msdn.microsoft.com/en-us/library/17w5ykft.aspx + /// The 3 special characters are quote, backslash and whitespaces, in order + /// of priority. + /// The semantics of a quote is: whatever the state of the lexer, copy + /// all characters verbatim until the next quote or EOF. + /// The semantics of backslash is: If the next character is a backslash or a quote, + /// copy the next character. Otherwise, copy the backslash and the next character. + /// The semantics of whitespace is: end the current argument and move on to the next one. + /// + private static IEnumerable SplitArgs(string commandLine) { + var state = new State(commandLine); + while (!state.EOF) { + switch (state.Current) { + case '"': + ProcessQuote(state); + break; + + case '\\': + ProcessBackslash(state); + break; + + case ' ': + case '\t': + if (state.StringBuilder.Length > 0) + state.AddArgument(); + state.MoveNext(); + break; + + default: + state.AppendCurrent(); + state.MoveNext(); + break; + } + } + if (state.StringBuilder.Length > 0) + state.AddArgument(); + return state.Arguments; + } + + private static void ProcessQuote(State state) { + state.MoveNext(); + while (!state.EOF) { + if (state.Current == '"') { + state.MoveNext(); + break; + } + state.AppendCurrent(); + state.MoveNext(); + } + + state.AddArgument(); + } + + private static void ProcessBackslash(State state) { + state.MoveNext(); + if (state.EOF) { + state.Append('\\'); + return; + } + + if (state.Current == '"') { + state.Append('"'); + state.MoveNext(); + } + else { + state.Append('\\'); + state.AppendCurrent(); + state.MoveNext(); + } + } + } } \ 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/RecipeExecutionSteps/ContentSchemaStep.cs similarity index 78% rename from src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/MetaDataRecipeHandler.cs rename to src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/ContentSchemaStep.cs index db412c6fb..774fa8e6f 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/MetaDataRecipeHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/ContentSchemaStep.cs @@ -1,100 +1,86 @@ -using System; -using System.Xml; -using Orchard.ContentManagement.MetaData; -using Orchard.ContentTypes.Events; -using Orchard.Localization; -using Orchard.Logging; -using Orchard.Recipes.Models; -using Orchard.Recipes.Services; - -namespace Orchard.Recipes.RecipeHandlers { - public class MetadataRecipeHandler : IRecipeHandler { - private readonly IContentDefinitionManager _contentDefinitionManager; - private readonly IContentDefinitionReader _contentDefinitionReader; - private readonly IContentDefinitionEventHandler _contentDefinitonEventHandlers; - - public MetadataRecipeHandler( - IContentDefinitionManager contentDefinitionManager, - IContentDefinitionReader contentDefinitionReader, - IContentDefinitionEventHandler contentDefinitonEventHandlers) { - - _contentDefinitionManager = contentDefinitionManager; - _contentDefinitionReader = contentDefinitionReader; - _contentDefinitonEventHandlers = contentDefinitonEventHandlers; - Logger = NullLogger.Instance; - T = NullLocalizer.Instance; - } - - public Localizer T { get; set; } - public ILogger Logger { get; set; } - - /* - - - - - - - - - - */ - // Set type settings and attach parts to types. - // Create dynamic parts. - public void ExecuteRecipeStep(RecipeContext recipeContext) { - if (!String.Equals(recipeContext.RecipeStep.Name, "Metadata", StringComparison.OrdinalIgnoreCase)) { - return; - } - - Logger.Information("Executing recipe step '{0}'; ExecutionId={1}", recipeContext.RecipeStep.Name, recipeContext.ExecutionId); - - foreach (var metadataElement in recipeContext.RecipeStep.Step.Elements()) { - Logger.Debug("Processing element '{0}'.", metadataElement.Name.LocalName); - switch (metadataElement.Name.LocalName) { - case "Types": - foreach (var element in metadataElement.Elements()) { - var typeElement = element; - var typeName = XmlConvert.DecodeName(element.Name.LocalName); - - Logger.Information("Importing content type '{0}'.", typeName); - try { - _contentDefinitonEventHandlers.ContentTypeImporting(new ContentTypeImportingContext { ContentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(typeName), ContentTypeName = typeName }); - _contentDefinitionManager.AlterTypeDefinition(typeName, alteration => _contentDefinitionReader.Merge(typeElement, alteration)); - _contentDefinitonEventHandlers.ContentTypeImported(new ContentTypeImportedContext { ContentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(typeName) }); - } - catch (Exception ex) { - Logger.Error(ex, "Error while importing content type '{0}'.", typeName); - throw; - } - } - break; - - case "Parts": - foreach (var element in metadataElement.Elements()) { - var partElement = element; - var partName = XmlConvert.DecodeName(element.Name.LocalName); - - Logger.Information("Importing content part '{0}'.", partName); - try { - _contentDefinitonEventHandlers.ContentPartImporting(new ContentPartImportingContext { ContentPartDefinition = _contentDefinitionManager.GetPartDefinition(partName), ContentPartName = partName }); - _contentDefinitionManager.AlterPartDefinition(partName, alteration => _contentDefinitionReader.Merge(partElement, alteration)); - _contentDefinitonEventHandlers.ContentPartImported(new ContentPartImportedContext { ContentPartDefinition = _contentDefinitionManager.GetPartDefinition(partName)}); - } - catch (Exception ex) { - Logger.Error(ex, "Error while importing content part '{0}'.", partName); - throw; - } - } - break; - - default: - Logger.Warning("Unrecognized element '{0}' encountered; skipping", metadataElement.Name.LocalName); - break; - } - } - - recipeContext.Executed = true; - Logger.Information("Finished executing recipe step '{0}'.", recipeContext.RecipeStep.Name); - } - } +using System; +using System.Xml; +using Orchard.ContentManagement.MetaData; +using Orchard.ContentTypes.Events; +using Orchard.Logging; +using Orchard.Recipes.Services; + +namespace Orchard.Recipes.RecipeExecutionSteps { + public class ContentSchemaStep : RecipeExecutionStep { + private readonly IContentDefinitionManager _contentDefinitionManager; + private readonly IContentDefinitionReader _contentDefinitionReader; + private readonly IContentDefinitionEventHandler _contentDefinitonEventHandlers; + + public override string Name { get { return "ContentSchema"; } } + + public ContentSchemaStep( + IContentDefinitionManager contentDefinitionManager, + IContentDefinitionReader contentDefinitionReader, + IContentDefinitionEventHandler contentDefinitonEventHandlers) { + + _contentDefinitionManager = contentDefinitionManager; + _contentDefinitionReader = contentDefinitionReader; + _contentDefinitonEventHandlers = contentDefinitonEventHandlers; + } + + /* + + + + + + + + + + */ + // Set type settings and attach parts to types. + // Create dynamic parts. + public override void Execute(RecipeExecutionContext context) { + foreach (var metadataElement in context.RecipeStep.Step.Elements()) { + Logger.Debug("Processing element '{0}'.", metadataElement.Name.LocalName); + switch (metadataElement.Name.LocalName) { + case "Types": + foreach (var element in metadataElement.Elements()) { + var typeElement = element; + var typeName = XmlConvert.DecodeName(element.Name.LocalName); + + Logger.Information("Importing content type '{0}'.", typeName); + try { + _contentDefinitonEventHandlers.ContentTypeImporting(new ContentTypeImportingContext { ContentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(typeName), ContentTypeName = typeName }); + _contentDefinitionManager.AlterTypeDefinition(typeName, alteration => _contentDefinitionReader.Merge(typeElement, alteration)); + _contentDefinitonEventHandlers.ContentTypeImported(new ContentTypeImportedContext { ContentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(typeName) }); + } + catch (Exception ex) { + Logger.Error(ex, "Error while importing content type '{0}'.", typeName); + throw; + } + } + break; + + case "Parts": + foreach (var element in metadataElement.Elements()) { + var partElement = element; + var partName = XmlConvert.DecodeName(element.Name.LocalName); + + Logger.Information("Importing content part '{0}'.", partName); + try { + _contentDefinitonEventHandlers.ContentPartImporting(new ContentPartImportingContext { ContentPartDefinition = _contentDefinitionManager.GetPartDefinition(partName), ContentPartName = partName }); + _contentDefinitionManager.AlterPartDefinition(partName, alteration => _contentDefinitionReader.Merge(partElement, alteration)); + _contentDefinitonEventHandlers.ContentPartImported(new ContentPartImportedContext { ContentPartDefinition = _contentDefinitionManager.GetPartDefinition(partName)}); + } + catch (Exception ex) { + Logger.Error(ex, "Error while importing content part '{0}'.", partName); + throw; + } + } + break; + + default: + Logger.Warning("Unrecognized element '{0}' encountered; skipping", metadataElement.Name.LocalName); + break; + } + } + } + } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/DataRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/ContentStep.cs similarity index 67% rename from src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/DataRecipeHandler.cs rename to src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/ContentStep.cs index c2b49096c..336c1470a 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/DataRecipeHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/ContentStep.cs @@ -1,120 +1,106 @@ -using System; -using System.Collections.Generic; -using System.Xml.Linq; -using Orchard.ContentManagement; -using Orchard.Data; -using Orchard.Localization; -using Orchard.Logging; -using Orchard.Recipes.Models; -using Orchard.Recipes.Services; - -namespace Orchard.Recipes.RecipeHandlers { - public class DataRecipeHandler : IRecipeHandler { - private readonly IOrchardServices _orchardServices; - private readonly ITransactionManager _transactionManager; - - public DataRecipeHandler(IOrchardServices orchardServices, ITransactionManager transactionManager) { - _orchardServices = orchardServices; - _transactionManager = transactionManager; - Logger = NullLogger.Instance; - T = NullLocalizer.Instance; - } - - public Localizer T { get; set; } - public ILogger Logger { get; set; } - - // - // Import Data - public void ExecuteRecipeStep(RecipeContext recipeContext) { - if (!String.Equals(recipeContext.RecipeStep.Name, "Data", StringComparison.OrdinalIgnoreCase)) { - return; - } - - Logger.Information("Executing recipe step '{0}'; ExecutionId={1}", recipeContext.RecipeStep.Name, recipeContext.ExecutionId); - - var importContentSession = new ImportContentSession(_orchardServices.ContentManager); - - // Populate local dictionary with elements and their ids - var elementDictionary = CreateElementDictionary(recipeContext.RecipeStep.Step); - - //Populate import session with all identities to be imported - foreach (var identity in elementDictionary.Keys) { - importContentSession.Set(identity, elementDictionary[identity].Name.LocalName); - } - - //Determine if the import is to be batched in multiple transactions - var startIndex = 0; - int batchSize = GetBatchSizeForDataStep(recipeContext.RecipeStep.Step); - Logger.Debug("Using batch size {0}.", batchSize); - - //Run the import - try { - while (startIndex < elementDictionary.Count) { - Logger.Debug("Importing batch starting at index {0}.", startIndex); - importContentSession.InitializeBatch(startIndex, batchSize); - - //the session determines which items are included in the current batch - //so that dependencies can be managed within the same transaction - var nextIdentity = importContentSession.GetNextInBatch(); - while (nextIdentity != null) { - var itemId = ""; - if (elementDictionary[nextIdentity.ToString()].HasAttributes) { - itemId = elementDictionary[nextIdentity.ToString()].FirstAttribute.Value; - } - Logger.Information("Importing data item '{0}'.", itemId); - try { - _orchardServices.ContentManager.Import( - elementDictionary[nextIdentity.ToString()], - importContentSession); - } - catch (Exception ex) { - Logger.Error(ex, "Error while importing data item '{0}'.", itemId); - throw; - } - nextIdentity = importContentSession.GetNextInBatch(); - } - - startIndex += batchSize; - - //Create a new transaction for each batch - if (startIndex < elementDictionary.Count) { - _transactionManager.RequireNew(); - } - - Logger.Debug("Finished importing batch starting at index {0}.", startIndex); - } - } - catch (Exception) { - //Ensure a failed batch is rolled back - _transactionManager.Cancel(); - throw; - } - - recipeContext.Executed = true; - Logger.Information("Finished executing recipe step '{0}'.", recipeContext.RecipeStep.Name); - } - - private Dictionary CreateElementDictionary(XElement step) { - var elementDictionary = new Dictionary(); - foreach (var element in step.Elements()) { - if (element.Attribute("Id") == null - || string.IsNullOrEmpty(element.Attribute("Id").Value)) - continue; - - var identity = new ContentIdentity(element.Attribute("Id").Value).ToString(); - elementDictionary[identity] = element; - } - return elementDictionary; - } - - private int GetBatchSizeForDataStep(XElement step) { - int batchSize; - if (step.Attribute("BatchSize") == null || - !int.TryParse(step.Attribute("BatchSize").Value, out batchSize) || - batchSize <= 0) { - batchSize = int.MaxValue; - } - return batchSize; - } - } -} +using System; +using System.Collections.Generic; +using System.Xml.Linq; +using Orchard.ContentManagement; +using Orchard.Data; +using Orchard.Logging; +using Orchard.Recipes.Services; + +namespace Orchard.Recipes.RecipeExecutionSteps { + public class ContentStep : RecipeExecutionStep { + private readonly IOrchardServices _orchardServices; + private readonly ITransactionManager _transactionManager; + + public ContentStep(IOrchardServices orchardServices, ITransactionManager transactionManager) { + _orchardServices = orchardServices; + _transactionManager = transactionManager; + } + + public override string Name { get { return "Content"; } } + + // + // Import Data. + public override void Execute(RecipeExecutionContext context) { + var importContentSession = new ImportContentSession(_orchardServices.ContentManager); + + // Populate local dictionary with elements and their ids. + var elementDictionary = CreateElementDictionary(context.RecipeStep.Step); + + // Populate import session with all identities to be imported. + foreach (var identity in elementDictionary.Keys) { + importContentSession.Set(identity, elementDictionary[identity].Name.LocalName); + } + + // Determine if the import is to be batched in multiple transactions. + var startIndex = 0; + var batchSize = GetBatchSizeForDataStep(context.RecipeStep.Step); + Logger.Debug("Using batch size {0}.", batchSize); + + // Run the import. + try { + while (startIndex < elementDictionary.Count) { + Logger.Debug("Importing batch starting at index {0}.", startIndex); + importContentSession.InitializeBatch(startIndex, batchSize); + + // The session determines which items are included in the current batch + // so that dependencies can be managed within the same transaction. + var nextIdentity = importContentSession.GetNextInBatch(); + while (nextIdentity != null) { + var itemId = ""; + if (elementDictionary[nextIdentity.ToString()].HasAttributes) { + itemId = elementDictionary[nextIdentity.ToString()].FirstAttribute.Value; + } + Logger.Information("Importing data item '{0}'.", itemId); + try { + _orchardServices.ContentManager.Import( + elementDictionary[nextIdentity.ToString()], + importContentSession); + } + catch (Exception ex) { + Logger.Error(ex, "Error while importing data item '{0}'.", itemId); + throw; + } + nextIdentity = importContentSession.GetNextInBatch(); + } + + startIndex += batchSize; + + // Create a new transaction for each batch. + if (startIndex < elementDictionary.Count) { + _transactionManager.RequireNew(); + } + + Logger.Debug("Finished importing batch starting at index {0}.", startIndex); + } + } + catch (Exception) { + // Ensure a failed batch is rolled back. + _transactionManager.Cancel(); + throw; + } + } + + private Dictionary CreateElementDictionary(XElement step) { + var elementDictionary = new Dictionary(); + foreach (var element in step.Elements()) { + if (element.Attribute("Id") == null + || string.IsNullOrEmpty(element.Attribute("Id").Value)) + continue; + + var identity = new ContentIdentity(element.Attribute("Id").Value).ToString(); + elementDictionary[identity] = element; + } + return elementDictionary; + } + + private int GetBatchSizeForDataStep(XElement step) { + int batchSize; + if (step.Attribute("BatchSize") == null || + !int.TryParse(step.Attribute("BatchSize").Value, out batchSize) || + batchSize <= 0) { + batchSize = int.MaxValue; + } + return batchSize; + } + } +} diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/FeatureRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/FeatureStep.cs similarity index 72% rename from src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/FeatureRecipeHandler.cs rename to src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/FeatureStep.cs index 8da5b4137..35a367336 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/FeatureRecipeHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/FeatureStep.cs @@ -1,79 +1,65 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Orchard.Environment.Features; -using Orchard.Localization; -using Orchard.Logging; -using Orchard.Recipes.Models; -using Orchard.Recipes.Services; - -namespace Orchard.Recipes.RecipeHandlers { - public class FeatureRecipeHandler : IRecipeHandler { - private readonly IFeatureManager _featureManager; - - public FeatureRecipeHandler(IFeatureManager featureManager) { - _featureManager = featureManager; - Logger = NullLogger.Instance; - T = NullLocalizer.Instance; - } - - public Localizer T { get; set; } - public ILogger Logger { get; set; } - - // - // Enable/Disable features. - public void ExecuteRecipeStep(RecipeContext recipeContext) { - if (!String.Equals(recipeContext.RecipeStep.Name, "Feature", StringComparison.OrdinalIgnoreCase)) { - return; - } - - Logger.Information("Executing recipe step '{0}'; ExecutionId={1}", recipeContext.RecipeStep.Name, recipeContext.ExecutionId); - - var featuresToEnable = new List(); - var featuresToDisable = new List(); - foreach (var attribute in recipeContext.RecipeStep.Step.Attributes()) { - if (String.Equals(attribute.Name.LocalName, "disable", StringComparison.OrdinalIgnoreCase)) { - featuresToDisable = ParseFeatures(attribute.Value); - } - else if (String.Equals(attribute.Name.LocalName, "enable", StringComparison.OrdinalIgnoreCase)) { - featuresToEnable = ParseFeatures(attribute.Value); - } - else { - Logger.Warning("Unrecognized attribute '{0}' encountered; skipping", attribute.Name.LocalName); - } - } - - var availableFeatures = _featureManager.GetAvailableFeatures().Select(x => x.Id).ToArray(); - foreach (var featureName in featuresToDisable) { - if (!availableFeatures.Contains(featureName)) { - throw new InvalidOperationException(string.Format("Could not disable feature {0} because it was not found.", featureName)); - } - } - - foreach (var featureName in featuresToEnable) { - if (!availableFeatures.Contains(featureName)) { - throw new InvalidOperationException(string.Format("Could not enable feature {0} because it was not found.", featureName)); - } - } - - if (featuresToDisable.Any()) { - Logger.Information("Disabling features: {0}", String.Join(";", featuresToDisable)); - _featureManager.DisableFeatures(featuresToDisable, true); - } - if (featuresToEnable.Any()) { - Logger.Information("Enabling features: {0}", String.Join(";", featuresToEnable)); - _featureManager.EnableFeatures(featuresToEnable, true); - } - - recipeContext.Executed = true; - Logger.Information("Finished executing recipe step '{0}'.", recipeContext.RecipeStep.Name); - } - - private static List ParseFeatures(string csv) { - return csv.Split(',') - .Select(value => value.Trim()) - .Where(sanitizedValue => !String.IsNullOrEmpty(sanitizedValue)) - .ToList(); - } - } +using System; +using System.Collections.Generic; +using System.Linq; +using Orchard.Environment.Features; +using Orchard.Logging; +using Orchard.Recipes.Services; + +namespace Orchard.Recipes.RecipeExecutionSteps { + public class FeatureStep : RecipeExecutionStep { + private readonly IFeatureManager _featureManager; + + public FeatureStep(IFeatureManager featureManager) { + _featureManager = featureManager; + } + + public override string Name { get { return "Feature"; } } + + // + // Enable/Disable features. + public override void Execute(RecipeExecutionContext recipeContext) { + var featuresToEnable = new List(); + var featuresToDisable = new List(); + foreach (var attribute in recipeContext.RecipeStep.Step.Attributes()) { + if (String.Equals(attribute.Name.LocalName, "disable", StringComparison.OrdinalIgnoreCase)) { + featuresToDisable = ParseFeatures(attribute.Value); + } + else if (String.Equals(attribute.Name.LocalName, "enable", StringComparison.OrdinalIgnoreCase)) { + featuresToEnable = ParseFeatures(attribute.Value); + } + else { + Logger.Warning("Unrecognized attribute '{0}' encountered; skipping", attribute.Name.LocalName); + } + } + + var availableFeatures = _featureManager.GetAvailableFeatures().Select(x => x.Id).ToArray(); + foreach (var featureName in featuresToDisable) { + if (!availableFeatures.Contains(featureName)) { + throw new InvalidOperationException(string.Format("Could not disable feature {0} because it was not found.", featureName)); + } + } + + foreach (var featureName in featuresToEnable) { + if (!availableFeatures.Contains(featureName)) { + throw new InvalidOperationException(string.Format("Could not enable feature {0} because it was not found.", featureName)); + } + } + + if (featuresToDisable.Any()) { + Logger.Information("Disabling features: {0}", String.Join(";", featuresToDisable)); + _featureManager.DisableFeatures(featuresToDisable, true); + } + if (featuresToEnable.Any()) { + Logger.Information("Enabling features: {0}", String.Join(";", featuresToEnable)); + _featureManager.EnableFeatures(featuresToEnable, true); + } + } + + private static List ParseFeatures(string csv) { + return csv.Split(',') + .Select(value => value.Trim()) + .Where(sanitizedValue => !String.IsNullOrEmpty(sanitizedValue)) + .ToList(); + } + } } \ 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/RecipeExecutionSteps/MigrationStep.cs similarity index 65% rename from src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/MigrationRecipeHandler.cs rename to src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/MigrationStep.cs index 54c9110c5..bfe9cf882 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/MigrationRecipeHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/MigrationStep.cs @@ -1,80 +1,66 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Orchard.Data.Migration; -using Orchard.Localization; -using Orchard.Logging; -using Orchard.Recipes.Models; -using Orchard.Recipes.Services; - -namespace Orchard.Recipes.RecipeHandlers { - public class MigrationRecipeHandler : IRecipeHandler { - private readonly IDataMigrationManager _dataMigrationManager; - - public MigrationRecipeHandler(IDataMigrationManager dataMigrationManager) { - _dataMigrationManager = dataMigrationManager; - Logger = NullLogger.Instance; - T = NullLocalizer.Instance; - } - - public Localizer T { get; set; } - public ILogger Logger { get; set; } - - // - // - // Run migration for features. - public void ExecuteRecipeStep(RecipeContext recipeContext) { - if (!String.Equals(recipeContext.RecipeStep.Name, "Migration", StringComparison.OrdinalIgnoreCase)) { - return; - } - - Logger.Information("Executing recipe step '{0}'; ExecutionId={1}", recipeContext.RecipeStep.Name, recipeContext.ExecutionId); - - bool runAll = false; - var features = new List(); - foreach (var attribute in recipeContext.RecipeStep.Step.Attributes()) { - if (String.Equals(attribute.Name.LocalName, "features", StringComparison.OrdinalIgnoreCase)) { - features = ParseFeatures(attribute.Value); - if (features.Contains("*")) - runAll = true; - } - else { - Logger.Warning("Unrecognized attribute '{0}' encountered; skipping.", attribute.Name.LocalName); - } - } - - if (runAll) { - foreach (var feature in _dataMigrationManager.GetFeaturesThatNeedUpdate()) { - Logger.Information("Updating feature '{0}'.", feature); - try { - _dataMigrationManager.Update(feature); - } - catch (Exception ex) { - Logger.Error(ex, "Error while updating feature '{0}'", feature); - throw; - } - } - } - else { - Logger.Information("Updating features: {0}", String.Join(";", features)); - try { - _dataMigrationManager.Update(features); - } - catch (Exception ex) { - Logger.Error(ex, "Error while updating features: {0}", String.Join(";", features)); - throw; - } - } - - recipeContext.Executed = true; - Logger.Information("Finished executing recipe step '{0}'.", recipeContext.RecipeStep.Name); - } - - private static List ParseFeatures(string csv) { - return csv.Split(',') - .Select(value => value.Trim()) - .Where(sanitizedValue => !String.IsNullOrEmpty(sanitizedValue)) - .ToList(); - } - } +using System; +using System.Collections.Generic; +using System.Linq; +using Orchard.Data.Migration; +using Orchard.Logging; +using Orchard.Recipes.Services; + +namespace Orchard.Recipes.RecipeExecutionSteps { + public class MigrationStep : RecipeExecutionStep { + private readonly IDataMigrationManager _dataMigrationManager; + + public MigrationStep(IDataMigrationManager dataMigrationManager) { + _dataMigrationManager = dataMigrationManager; + } + + public override string Name { get { return "Migration"; } } + + // + // + // Run migration for features. + public override void Execute(RecipeExecutionContext context) { + var runAll = false; + var features = new List(); + foreach (var attribute in context.RecipeStep.Step.Attributes()) { + if (String.Equals(attribute.Name.LocalName, "features", StringComparison.OrdinalIgnoreCase)) { + features = ParseFeatures(attribute.Value); + if (features.Contains("*")) + runAll = true; + } + else { + Logger.Warning("Unrecognized attribute '{0}' encountered; skipping.", attribute.Name.LocalName); + } + } + + if (runAll) { + foreach (var feature in _dataMigrationManager.GetFeaturesThatNeedUpdate()) { + Logger.Information("Updating feature '{0}'.", feature); + try { + _dataMigrationManager.Update(feature); + } + catch (Exception ex) { + Logger.Error(ex, "Error while updating feature '{0}'", feature); + throw; + } + } + } + else { + Logger.Information("Updating features: {0}", String.Join(";", features)); + try { + _dataMigrationManager.Update(features); + } + catch (Exception ex) { + Logger.Error(ex, "Error while updating features: {0}", String.Join(";", features)); + throw; + } + } + } + + private static List ParseFeatures(string csv) { + return csv.Split(',') + .Select(value => value.Trim()) + .Where(sanitizedValue => !String.IsNullOrEmpty(sanitizedValue)) + .ToList(); + } + } } \ 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/RecipeExecutionSteps/ModuleStep.cs similarity index 75% rename from src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/ModuleRecipeHandler.cs rename to src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/ModuleStep.cs index f0ad6db5b..88946fdb3 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/ModuleRecipeHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/ModuleStep.cs @@ -1,111 +1,97 @@ -using System; -using System.Linq; -using System.Web.Hosting; -using Orchard.Environment.Extensions; -using Orchard.Environment.Extensions.Models; -using Orchard.Localization; -using Orchard.Logging; -using Orchard.Packaging.Models; -using Orchard.Packaging.Services; -using Orchard.Recipes.Models; -using Orchard.Recipes.Services; - -namespace Orchard.Recipes.RecipeHandlers { - public class ModuleRecipeHandler : IRecipeHandler { - private readonly IPackagingSourceManager _packagingSourceManager; - private readonly IPackageManager _packageManager; - private readonly IExtensionManager _extensionManager; - - public ModuleRecipeHandler( - IPackagingSourceManager packagingSourceManager, - IPackageManager packageManager, - IExtensionManager extensionManager) { - _packagingSourceManager = packagingSourceManager; - _packageManager = packageManager; - _extensionManager = extensionManager; - - Logger = NullLogger.Instance; - T = NullLocalizer.Instance; - } - - public Localizer T { get; set; } - public ILogger Logger { get; set; } - - // - // install modules from feed. - public void ExecuteRecipeStep(RecipeContext recipeContext) { - if (!String.Equals(recipeContext.RecipeStep.Name, "Module", StringComparison.OrdinalIgnoreCase)) { - return; - } - - Logger.Information("Executing recipe step '{0}'; ExecutionId={1}", recipeContext.RecipeStep.Name, recipeContext.ExecutionId); - - string packageId = null, version = null, repository = null; - foreach (var attribute in recipeContext.RecipeStep.Step.Attributes()) { - if (String.Equals(attribute.Name.LocalName, "packageId", StringComparison.OrdinalIgnoreCase)) { - packageId = attribute.Value; - } - else if (String.Equals(attribute.Name.LocalName, "version", StringComparison.OrdinalIgnoreCase)) { - version = attribute.Value; - } - else if (String.Equals(attribute.Name.LocalName, "repository", StringComparison.OrdinalIgnoreCase)) { - repository = attribute.Value; - } - else { - throw new InvalidOperationException(string.Format("Unrecognized attribute {0} encountered in step Module.", attribute.Name.LocalName)); - } - } - - if (packageId == null) { - throw new InvalidOperationException("PackageId is required in a Module declaration in a recipe file."); - } - - // download and install module from the orchard feed or a custom feed if repository is specified. - bool enforceVersion = version != null; - bool installed = false; - PackagingEntry packagingEntry = null; - - var packagingSource = _packagingSourceManager.GetSources().FirstOrDefault(); - if (repository != null) { - packagingSource = new PackagingSource {FeedTitle = repository, FeedUrl = repository}; - } - - if (enforceVersion) { - packagingEntry = _packagingSourceManager.GetExtensionList(false, packagingSource, - packages => packages.Where(package => - package.PackageType.Equals(DefaultExtensionTypes.Module) && - package.Id.Equals(packageId, StringComparison.OrdinalIgnoreCase) && - package.Version.Equals(version, StringComparison.OrdinalIgnoreCase))).FirstOrDefault(); - } - else { - packagingEntry = _packagingSourceManager.GetExtensionList(false, packagingSource, - packages => packages.Where(package => - package.PackageType.Equals(DefaultExtensionTypes.Module) && - package.Id.Equals(packageId, StringComparison.OrdinalIgnoreCase) && - package.IsLatestVersion)).FirstOrDefault(); - } - - if (packagingEntry != null) { - if (!ModuleAlreadyInstalled(packagingEntry.PackageId)) { - Logger.Information("Installing module {0}.", packagingEntry.Title); - _packageManager.Install(packagingEntry.PackageId, packagingEntry.Version, packagingSource.FeedUrl, HostingEnvironment.MapPath("~/")); - } - installed = true; - } - - if (!installed) { - throw new InvalidOperationException(string.Format("Module {0} was not found in the specified location.", packageId)); - } - - recipeContext.Executed = true; - Logger.Information("Finished executing recipe step '{0}'.", recipeContext.RecipeStep.Name); - } - - private bool ModuleAlreadyInstalled(string packageId) { - return _extensionManager.AvailableExtensions().Where(m => DefaultExtensionTypes.IsModule(m.ExtensionType)) - .Any(module => module.Id.Equals( - packageId.Substring(PackagingSourceManager.GetExtensionPrefix(DefaultExtensionTypes.Module).Length), - StringComparison.OrdinalIgnoreCase)); - } - } +using System; +using System.Linq; +using System.Web.Hosting; +using Orchard.Environment.Extensions; +using Orchard.Environment.Extensions.Models; +using Orchard.Logging; +using Orchard.Packaging.Models; +using Orchard.Packaging.Services; +using Orchard.Recipes.Services; + +namespace Orchard.Recipes.RecipeExecutionSteps { + public class ModuleStep : RecipeExecutionStep { + private readonly IPackagingSourceManager _packagingSourceManager; + private readonly IPackageManager _packageManager; + private readonly IExtensionManager _extensionManager; + + public ModuleStep( + IPackagingSourceManager packagingSourceManager, + IPackageManager packageManager, + IExtensionManager extensionManager) { + + _packagingSourceManager = packagingSourceManager; + _packageManager = packageManager; + _extensionManager = extensionManager; + } + + public override string Name { get { return "Module"; } } + + // + // Install modules from feed. + public override void Execute(RecipeExecutionContext context) { + string packageId = null, version = null, repository = null; + foreach (var attribute in context.RecipeStep.Step.Attributes()) { + if (String.Equals(attribute.Name.LocalName, "packageId", StringComparison.OrdinalIgnoreCase)) { + packageId = attribute.Value; + } + else if (String.Equals(attribute.Name.LocalName, "version", StringComparison.OrdinalIgnoreCase)) { + version = attribute.Value; + } + else if (String.Equals(attribute.Name.LocalName, "repository", StringComparison.OrdinalIgnoreCase)) { + repository = attribute.Value; + } + else { + throw new InvalidOperationException(String.Format("Unrecognized attribute {0} encountered in step Module.", attribute.Name.LocalName)); + } + } + + if (packageId == null) { + throw new InvalidOperationException("PackageId is required in a Module declaration in a recipe file."); + } + + // download and install module from the orchard feed or a custom feed if repository is specified. + var enforceVersion = version != null; + var installed = false; + PackagingEntry packagingEntry = null; + + var packagingSource = _packagingSourceManager.GetSources().FirstOrDefault(); + if (repository != null) { + packagingSource = new PackagingSource {FeedTitle = repository, FeedUrl = repository}; + } + + if (enforceVersion) { + packagingEntry = _packagingSourceManager.GetExtensionList(false, packagingSource, + packages => packages.Where(package => + package.PackageType.Equals(DefaultExtensionTypes.Module) && + package.Id.Equals(packageId, StringComparison.OrdinalIgnoreCase) && + package.Version.Equals(version, StringComparison.OrdinalIgnoreCase))).FirstOrDefault(); + } + else { + packagingEntry = _packagingSourceManager.GetExtensionList(false, packagingSource, + packages => packages.Where(package => + package.PackageType.Equals(DefaultExtensionTypes.Module) && + package.Id.Equals(packageId, StringComparison.OrdinalIgnoreCase) && + package.IsLatestVersion)).FirstOrDefault(); + } + + if (packagingEntry != null) { + if (!ModuleAlreadyInstalled(packagingEntry.PackageId)) { + Logger.Information("Installing module {0}.", packagingEntry.Title); + _packageManager.Install(packagingEntry.PackageId, packagingEntry.Version, packagingSource.FeedUrl, HostingEnvironment.MapPath("~/")); + } + installed = true; + } + + if (!installed) { + throw new InvalidOperationException(String.Format("Module {0} was not found in the specified location.", packageId)); + } + } + + private bool ModuleAlreadyInstalled(string packageId) { + return _extensionManager.AvailableExtensions().Where(m => DefaultExtensionTypes.IsModule(m.ExtensionType)) + .Any(module => module.Id.Equals( + packageId.Substring(PackagingSourceManager.GetExtensionPrefix(DefaultExtensionTypes.Module).Length), + StringComparison.OrdinalIgnoreCase)); + } + } } \ 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/RecipeExecutionSteps/SettingsStep.cs similarity index 67% rename from src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/SettingsRecipeHandler.cs rename to src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/SettingsStep.cs index 2c6a4f7aa..5a9e095b5 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/SettingsRecipeHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/SettingsStep.cs @@ -1,101 +1,88 @@ -using System; -using System.Collections.Generic; -using System.Xml.Linq; -using Orchard.ContentManagement; -using Orchard.ContentManagement.Handlers; -using Orchard.Localization; -using Orchard.Logging; -using Orchard.Recipes.Models; -using Orchard.Recipes.Services; -using Orchard.Settings; - -namespace Orchard.Recipes.RecipeHandlers { - public class SettingsRecipeHandler : IRecipeHandler { - private readonly ISiteService _siteService; - private readonly IContentManager _contentManager; - private readonly Lazy> _handlers; - - public SettingsRecipeHandler(ISiteService siteService, IContentManager contentManager, Lazy> handlers) { - _siteService = siteService; - _contentManager = contentManager; - _handlers = handlers; - Logger = NullLogger.Instance; - T = NullLocalizer.Instance; - } - - public Localizer T { get; set; } - public ILogger Logger { get; set; } - private IEnumerable Handlers { get { return _handlers.Value; } } - - /* - - - - - */ - // Set site and part settings. - public void ExecuteRecipeStep(RecipeContext recipeContext) { - if (!String.Equals(recipeContext.RecipeStep.Name, "Settings", StringComparison.OrdinalIgnoreCase)) { - return; - } - - Logger.Information("Executing recipe step '{0}'; ExecutionId={1}", recipeContext.RecipeStep.Name, recipeContext.ExecutionId); - - var siteContentItem = _siteService.GetSiteSettings().ContentItem; - - var importContentSession = new ImportContentSession(_contentManager); - - var context = new ImportContentContext(siteContentItem, recipeContext.RecipeStep.Step, importContentSession); - foreach (var contentHandler in Handlers) { - contentHandler.Importing(context); - } - - foreach (var contentPart in siteContentItem.Parts) { - var partElement = context.Data.Element(contentPart.PartDefinition.Name); - if (partElement == null) { - continue; - } - - Logger.Information("Importing settings part '{0}'.", contentPart.PartDefinition.Name); - try { - ImportSettingPart(contentPart, partElement); - } - catch (Exception ex) { - Logger.Error(ex, "Error while importing settings part '{0}'.", contentPart.PartDefinition.Name); - throw; - } - } - - foreach (var contentHandler in Handlers) { - contentHandler.Imported(context); - } - - recipeContext.Executed = true; - Logger.Information("Finished executing recipe step '{0}'.", recipeContext.RecipeStep.Name); - } - - private void ImportSettingPart(ContentPart sitePart, XElement element) { - - foreach (var attribute in element.Attributes()) { - var attributeName = attribute.Name.LocalName; - var attributeValue = attribute.Value; - - var property = sitePart.GetType().GetProperty(attributeName); - if (property == null) { - continue; - } - - var propertyType = property.PropertyType; - if (propertyType == typeof(string)) { - property.SetValue(sitePart, attributeValue, null); - } - else if (propertyType == typeof(bool)) { - property.SetValue(sitePart, Boolean.Parse(attributeValue), null); - } - else if (propertyType == typeof(int)) { - property.SetValue(sitePart, Int32.Parse(attributeValue), null); - } - } - } - } -} +using System; +using System.Collections.Generic; +using System.Xml.Linq; +using Orchard.ContentManagement; +using Orchard.ContentManagement.Handlers; +using Orchard.Localization; +using Orchard.Logging; +using Orchard.Recipes.Models; +using Orchard.Recipes.Services; +using Orchard.Settings; + +namespace Orchard.Recipes.RecipeExecutionSteps { + public class SettingsStep : RecipeExecutionStep { + private readonly ISiteService _siteService; + private readonly IContentManager _contentManager; + private readonly Lazy> _handlers; + + public SettingsStep(ISiteService siteService, IContentManager contentManager, Lazy> handlers) { + _siteService = siteService; + _contentManager = contentManager; + _handlers = handlers; + } + + public override string Name { get { return "Settings"; } } + private IEnumerable Handlers { get { return _handlers.Value; } } + + /* + + + + + */ + // Set site and part settings. + public override void Execute(RecipeExecutionContext context) { + var siteContentItem = _siteService.GetSiteSettings().ContentItem; + var importContentSession = new ImportContentSession(_contentManager); + var importContentContext = new ImportContentContext(siteContentItem, context.RecipeStep.Step, importContentSession); + + foreach (var contentHandler in Handlers) { + contentHandler.Importing(importContentContext); + } + + foreach (var contentPart in siteContentItem.Parts) { + var partElement = importContentContext.Data.Element(contentPart.PartDefinition.Name); + if (partElement == null) { + continue; + } + + Logger.Information("Importing settings part '{0}'.", contentPart.PartDefinition.Name); + try { + ImportSettingPart(contentPart, partElement); + } + catch (Exception ex) { + Logger.Error(ex, "Error while importing settings part '{0}'.", contentPart.PartDefinition.Name); + throw; + } + } + + foreach (var contentHandler in Handlers) { + contentHandler.Imported(importContentContext); + } + } + + private void ImportSettingPart(ContentPart sitePart, XElement element) { + + foreach (var attribute in element.Attributes()) { + var attributeName = attribute.Name.LocalName; + var attributeValue = attribute.Value; + + var property = sitePart.GetType().GetProperty(attributeName); + if (property == null) { + continue; + } + + var propertyType = property.PropertyType; + if (propertyType == typeof(string)) { + property.SetValue(sitePart, attributeValue, null); + } + else if (propertyType == typeof(bool)) { + property.SetValue(sitePart, Boolean.Parse(attributeValue), null); + } + else if (propertyType == typeof(int)) { + property.SetValue(sitePart, Int32.Parse(attributeValue), null); + } + } + } + } +} diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/ThemeRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/ThemeStep.cs similarity index 80% rename from src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/ThemeRecipeHandler.cs rename to src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/ThemeStep.cs index 59a51dcc8..a30a0c154 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/ThemeRecipeHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeExecutionSteps/ThemeStep.cs @@ -1,138 +1,123 @@ -using System; -using System.Linq; -using System.Web.Hosting; -using Orchard.Environment.Extensions; -using Orchard.Environment.Extensions.Models; -using Orchard.Localization; -using Orchard.Logging; -using Orchard.Packaging.Models; -using Orchard.Packaging.Services; -using Orchard.Recipes.Models; -using Orchard.Recipes.Services; -using Orchard.Themes.Services; - -namespace Orchard.Recipes.RecipeHandlers { - public class ThemeRecipeHandler : IRecipeHandler { - private readonly IPackagingSourceManager _packagingSourceManager; - private readonly IPackageManager _packageManager; - private readonly IExtensionManager _extensionManager; - private readonly IThemeService _themeService; - private readonly ISiteThemeService _siteThemeService; - - public ThemeRecipeHandler( - IPackagingSourceManager packagingSourceManager, - IPackageManager packageManager, - IExtensionManager extensionManager, - IThemeService themeService, - ISiteThemeService siteThemeService) { - - _packagingSourceManager = packagingSourceManager; - _packageManager = packageManager; - _extensionManager = extensionManager; - _themeService = themeService; - _siteThemeService = siteThemeService; - - Logger = NullLogger.Instance; - T = NullLocalizer.Instance; - } - - public Localizer T { get; set; } - public ILogger Logger { get; set; } - - // - // install themes from feed. - public void ExecuteRecipeStep(RecipeContext recipeContext) { - if (!String.Equals(recipeContext.RecipeStep.Name, "Theme", StringComparison.OrdinalIgnoreCase)) { - return; - } - - Logger.Information("Executing recipe step '{0}'; ExecutionId={1}", recipeContext.RecipeStep.Name, recipeContext.ExecutionId); - - bool enable = false, current = false; - string packageId = null, version = null, repository = null; - - foreach (var attribute in recipeContext.RecipeStep.Step.Attributes()) { - if (String.Equals(attribute.Name.LocalName, "enable", StringComparison.OrdinalIgnoreCase)) { - enable = Boolean.Parse(attribute.Value); - } - else if (String.Equals(attribute.Name.LocalName, "current", StringComparison.OrdinalIgnoreCase)) { - current = Boolean.Parse(attribute.Value); - } - else if (String.Equals(attribute.Name.LocalName, "packageId", StringComparison.OrdinalIgnoreCase)) { - packageId = attribute.Value; - } - else if (String.Equals(attribute.Name.LocalName, "version", StringComparison.OrdinalIgnoreCase)) { - version = attribute.Value; - } - else if (String.Equals(attribute.Name.LocalName, "repository", StringComparison.OrdinalIgnoreCase)) { - repository = attribute.Value; - } - else { - Logger.Warning("Unrecognized attribute '{0}' encountered; skipping.", attribute.Name.LocalName); - } - } - - if (packageId == null) { - throw new InvalidOperationException("The PackageId attribute is required on a Theme declaration in a recipe file."); - } - - // download and install theme from the orchard feed or a custom feed if repository is specified. - bool enforceVersion = version != null; - bool installed = false; - PackagingEntry packagingEntry = null; - - var packagingSource = _packagingSourceManager.GetSources().FirstOrDefault(); - if (repository != null) { - packagingSource = new PackagingSource { FeedTitle = repository, FeedUrl = repository }; - } - - if (enforceVersion) { - packagingEntry = _packagingSourceManager.GetExtensionList(false, packagingSource, - packages => packages.Where(package => - package.PackageType.Equals(DefaultExtensionTypes.Theme) && - package.Id.Equals(packageId, StringComparison.OrdinalIgnoreCase) && - package.Version.Equals(version, StringComparison.OrdinalIgnoreCase))).FirstOrDefault(); - } - else { - packagingEntry = _packagingSourceManager.GetExtensionList(false, packagingSource, - packages => packages.Where(package => - package.PackageType.Equals(DefaultExtensionTypes.Theme) && - package.Id.Equals(packageId, StringComparison.OrdinalIgnoreCase) && - package.IsLatestVersion)).FirstOrDefault(); - } - - if (packagingEntry != null) { - if (!ThemeAlreadyInstalled(packagingEntry.PackageId)) { - Logger.Information("Installing theme package '{0}'.", packagingEntry.PackageId); - _packageManager.Install(packagingEntry.PackageId, packagingEntry.Version, packagingSource.FeedUrl, HostingEnvironment.MapPath("~/")); - } - if (current) { - Logger.Information("Enabling theme '{0}'.", packagingEntry.Title); - _themeService.EnableThemeFeatures(packagingEntry.Title); - Logger.Information("Setting theme '{0}' as the site theme.", packagingEntry.Title); - _siteThemeService.SetSiteTheme(packagingEntry.Title); - } - else if (enable) { - Logger.Information("Enabling theme '{0}'.", packagingEntry.Title); - _themeService.EnableThemeFeatures(packagingEntry.Title); - } - - installed = true; - } - - if (!installed) { - throw new InvalidOperationException(string.Format("Theme '{0}' was not found in the specified location.", packageId)); - } - - recipeContext.Executed = true; - Logger.Information("Finished executing recipe step '{0}'.", recipeContext.RecipeStep.Name); - } - - private bool ThemeAlreadyInstalled(string packageId) { - return _extensionManager.AvailableExtensions().Where(t => DefaultExtensionTypes.IsTheme(t.ExtensionType)) - .Any(theme => theme.Id.Equals( - packageId.Substring(PackagingSourceManager.GetExtensionPrefix(DefaultExtensionTypes.Theme).Length), - StringComparison.OrdinalIgnoreCase)); - } - } +using System; +using System.Linq; +using System.Web.Hosting; +using Orchard.Environment.Extensions; +using Orchard.Environment.Extensions.Models; +using Orchard.Logging; +using Orchard.Packaging.Models; +using Orchard.Packaging.Services; +using Orchard.Recipes.Services; +using Orchard.Themes.Services; + +namespace Orchard.Recipes.RecipeExecutionSteps { + public class ThemeStep : RecipeExecutionStep { + private readonly IPackagingSourceManager _packagingSourceManager; + private readonly IPackageManager _packageManager; + private readonly IExtensionManager _extensionManager; + private readonly IThemeService _themeService; + private readonly ISiteThemeService _siteThemeService; + + public ThemeStep( + IPackagingSourceManager packagingSourceManager, + IPackageManager packageManager, + IExtensionManager extensionManager, + IThemeService themeService, + ISiteThemeService siteThemeService) { + + _packagingSourceManager = packagingSourceManager; + _packageManager = packageManager; + _extensionManager = extensionManager; + _themeService = themeService; + _siteThemeService = siteThemeService; + } + + public override string Name { get { return "Theme"; } } + + // + // Install themes from feed. + public override void Execute(RecipeExecutionContext context) { + bool enable = false, current = false; + string packageId = null, version = null, repository = null; + + foreach (var attribute in context.RecipeStep.Step.Attributes()) { + if (String.Equals(attribute.Name.LocalName, "enable", StringComparison.OrdinalIgnoreCase)) { + enable = Boolean.Parse(attribute.Value); + } + else if (String.Equals(attribute.Name.LocalName, "current", StringComparison.OrdinalIgnoreCase)) { + current = Boolean.Parse(attribute.Value); + } + else if (String.Equals(attribute.Name.LocalName, "packageId", StringComparison.OrdinalIgnoreCase)) { + packageId = attribute.Value; + } + else if (String.Equals(attribute.Name.LocalName, "version", StringComparison.OrdinalIgnoreCase)) { + version = attribute.Value; + } + else if (String.Equals(attribute.Name.LocalName, "repository", StringComparison.OrdinalIgnoreCase)) { + repository = attribute.Value; + } + else { + Logger.Warning("Unrecognized attribute '{0}' encountered; skipping.", attribute.Name.LocalName); + } + } + + if (packageId == null) { + throw new InvalidOperationException("The PackageId attribute is required on a Theme declaration in a recipe file."); + } + + // Download and install theme from the orchard feed or a custom feed if repository is specified. + var enforceVersion = version != null; + var installed = false; + PackagingEntry packagingEntry = null; + + var packagingSource = _packagingSourceManager.GetSources().FirstOrDefault(); + if (repository != null) { + packagingSource = new PackagingSource { FeedTitle = repository, FeedUrl = repository }; + } + + if (enforceVersion) { + packagingEntry = _packagingSourceManager.GetExtensionList(false, packagingSource, + packages => packages.Where(package => + package.PackageType.Equals(DefaultExtensionTypes.Theme) && + package.Id.Equals(packageId, StringComparison.OrdinalIgnoreCase) && + package.Version.Equals(version, StringComparison.OrdinalIgnoreCase))).FirstOrDefault(); + } + else { + packagingEntry = _packagingSourceManager.GetExtensionList(false, packagingSource, + packages => packages.Where(package => + package.PackageType.Equals(DefaultExtensionTypes.Theme) && + package.Id.Equals(packageId, StringComparison.OrdinalIgnoreCase) && + package.IsLatestVersion)).FirstOrDefault(); + } + + if (packagingEntry != null) { + if (!ThemeAlreadyInstalled(packagingEntry.PackageId)) { + Logger.Information("Installing theme package '{0}'.", packagingEntry.PackageId); + _packageManager.Install(packagingEntry.PackageId, packagingEntry.Version, packagingSource.FeedUrl, HostingEnvironment.MapPath("~/")); + } + if (current) { + Logger.Information("Enabling theme '{0}'.", packagingEntry.Title); + _themeService.EnableThemeFeatures(packagingEntry.Title); + Logger.Information("Setting theme '{0}' as the site theme.", packagingEntry.Title); + _siteThemeService.SetSiteTheme(packagingEntry.Title); + } + else if (enable) { + Logger.Information("Enabling theme '{0}'.", packagingEntry.Title); + _themeService.EnableThemeFeatures(packagingEntry.Title); + } + + installed = true; + } + + if (!installed) { + throw new InvalidOperationException(String.Format("Theme '{0}' was not found in the specified location.", packageId)); + } + } + + private bool ThemeAlreadyInstalled(string packageId) { + return _extensionManager.AvailableExtensions().Where(t => DefaultExtensionTypes.IsTheme(t.ExtensionType)) + .Any(theme => theme.Id.Equals( + packageId.Substring(PackagingSourceManager.GetExtensionPrefix(DefaultExtensionTypes.Theme).Length), + StringComparison.OrdinalIgnoreCase)); + } + } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/RecipeExecutionStepHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/RecipeExecutionStepHandler.cs new file mode 100644 index 000000000..f309211b1 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/RecipeExecutionStepHandler.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using System.Linq; +using Orchard.Logging; +using Orchard.Recipes.Models; +using Orchard.Recipes.Services; + +namespace Orchard.Recipes.RecipeHandlers { + /// + /// Delegates execution of the step to the appropriate recipe execution step implementation. + /// + public class RecipeExecutionStepHandler : Component, IRecipeHandler { + private readonly IEnumerable _recipeExecutionSteps; + public RecipeExecutionStepHandler(IEnumerable recipeExecutionSteps) { + _recipeExecutionSteps = recipeExecutionSteps; + } + + public void ExecuteRecipeStep(RecipeContext recipeContext) { + var executionStep = _recipeExecutionSteps.FirstOrDefault(x => x.Name == recipeContext.RecipeStep.Name); + var recipeExecutionContext = new RecipeExecutionContext {ExecutionId = recipeContext.ExecutionId, RecipeStep = recipeContext.RecipeStep}; + + if (executionStep != null) { + Logger.Information("Executing recipe step '{0}'; ExecutionId={1}", recipeContext.RecipeStep.Name, recipeContext.ExecutionId); + executionStep.Execute(recipeExecutionContext); + Logger.Information("Finished executing recipe step '{0}'.", recipeContext.RecipeStep.Name); + recipeContext.Executed = true; + } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/Services/IRecipeExecutionStep.cs b/src/Orchard.Web/Modules/Orchard.Recipes/Services/IRecipeExecutionStep.cs new file mode 100644 index 000000000..072d23965 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Recipes/Services/IRecipeExecutionStep.cs @@ -0,0 +1,6 @@ +namespace Orchard.Recipes.Services { + public interface IRecipeExecutionStep : IDependency { + string Name { get; } + void Execute(RecipeExecutionContext context); + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeExecutionContext.cs b/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeExecutionContext.cs new file mode 100644 index 000000000..f89e3b54b --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeExecutionContext.cs @@ -0,0 +1,8 @@ +using Orchard.Recipes.Models; + +namespace Orchard.Recipes.Services { + public class RecipeExecutionContext { + public string ExecutionId { get; set; } + public RecipeStep RecipeStep { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeExecutionStep.cs b/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeExecutionStep.cs new file mode 100644 index 000000000..297a70e68 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeExecutionStep.cs @@ -0,0 +1,6 @@ +namespace Orchard.Recipes.Services { + public abstract class RecipeExecutionStep : Component, IRecipeExecutionStep { + public abstract string Name { get; } + public abstract void Execute(RecipeExecutionContext context); + } +} \ 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 f38f34fd7..fde7944a6 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeManager.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeManager.cs @@ -17,6 +17,7 @@ namespace Orchard.Recipes.Services { IRecipeScheduler recipeScheduler, IRecipeExecuteEventHandler recipeExecuteEventHandler, IRepository recipeStepResultRecordRepository) { + _recipeStepQueue = recipeStepQueue; _recipeScheduler = recipeScheduler; _recipeExecuteEventHandler = recipeExecuteEventHandler; diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeStepExecutor.cs b/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeStepExecutor.cs index 5d31f550a..7d1ad2ae0 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeStepExecutor.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeStepExecutor.cs @@ -2,13 +2,12 @@ using System.Collections.Generic; using System.Linq; using Orchard.Data; -using Orchard.Localization; using Orchard.Logging; using Orchard.Recipes.Events; using Orchard.Recipes.Models; namespace Orchard.Recipes.Services { - public class RecipeStepExecutor : IRecipeStepExecutor { + public class RecipeStepExecutor : Component, IRecipeStepExecutor { private readonly IRecipeStepQueue _recipeStepQueue; private readonly IEnumerable _recipeHandlers; private readonly IRecipeExecuteEventHandler _recipeExecuteEventHandler; @@ -19,18 +18,13 @@ namespace Orchard.Recipes.Services { IEnumerable recipeHandlers, IRecipeExecuteEventHandler recipeExecuteEventHandler, IRepository recipeStepResultRecordRepository) { + _recipeStepQueue = recipeStepQueue; _recipeHandlers = recipeHandlers; _recipeExecuteEventHandler = recipeExecuteEventHandler; _recipeStepResultRecordRepository = recipeStepResultRecordRepository; - - Logger = NullLogger.Instance; - T = NullLocalizer.Instance; } - public Localizer T { get; set; } - public ILogger Logger { get; set; } - public bool ExecuteNextStep(string executionId) { var nextRecipeStep = _recipeStepQueue.Dequeue(executionId); if (nextRecipeStep == null) { @@ -45,9 +39,11 @@ namespace Orchard.Recipes.Services { try { _recipeExecuteEventHandler.RecipeStepExecuting(executionId, recipeContext); + foreach (var recipeHandler in _recipeHandlers) { recipeHandler.ExecuteRecipeStep(recipeContext); } + UpdateStepResultRecord(executionId, nextRecipeStep.Name, isSuccessful: true); _recipeExecuteEventHandler.RecipeStepExecuted(executionId, recipeContext); } diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/Views/EditorTemplates/ExportSteps/SiteSettings.cshtml b/src/Orchard.Web/Modules/Orchard.Recipes/Views/EditorTemplates/ExportSteps/Settings.cshtml similarity index 100% rename from src/Orchard.Web/Modules/Orchard.Recipes/Views/EditorTemplates/ExportSteps/SiteSettings.cshtml rename to src/Orchard.Web/Modules/Orchard.Recipes/Views/EditorTemplates/ExportSteps/Settings.cshtml