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