Breaking up IRecipeManager in two components: IRecipeHarvester (harvest and parse) and IRecipeManager (execute)

Renaming DiscoverRecipes to HarvestRecipes for consistency with other harvesters we have in Orchard.
Renaming MetaData to Metadata for the recipe step and its handler.
Moving recipe information elements in the recipe to under the Recipe element, renaming root element to Orchard and modifying the parser accordingly.
Using element.Name.LocalName in the parser.
Fixing whitespaces in a couple places, setting the Orchard.Recipes assembly copyright information and making the assembly securitytransparent.
Refactoring code and unit tests as a result of to above.

--HG--
branch : recipe
This commit is contained in:
Suha Can
2011-02-12 13:42:33 -08:00
parent 096e5e1d42
commit 578c107da3
12 changed files with 137 additions and 95 deletions

View File

@@ -7,6 +7,6 @@ OrchardVersion: 1.0.20
Description: Provides Orchard Recipes.
Features:
Orchard.Recipes:
Name: Recipes
Name: Recipes
Description: Implementation of Orchard recipes.
Category: Core

View File

@@ -55,11 +55,12 @@
<Compile Include="RecipeHandlers\CleanUpInactiveRecipeHandler.cs" />
<Compile Include="RecipeHandlers\CommandRecipeHandler.cs" />
<Compile Include="RecipeHandlers\FeatureRecipeHandler.cs" />
<Compile Include="RecipeHandlers\MetaDataRecipeHandler.cs" />
<Compile Include="RecipeHandlers\MetadataRecipeHandler.cs" />
<Compile Include="RecipeHandlers\MigrationRecipeHandler.cs" />
<Compile Include="RecipeHandlers\ModuleRecipeHandler.cs" />
<Compile Include="RecipeHandlers\SettingsRecipeHandler.cs" />
<Compile Include="RecipeHandlers\ThemeRecipeHandler.cs" />
<Compile Include="Services\RecipeHarvester.cs" />
<Compile Include="Services\RecipeManager.cs" />
<Compile Include="Services\RecipeParser.cs" />
</ItemGroup>

View File

@@ -1,6 +1,6 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
@@ -8,9 +8,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Orchard.Recipes")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("MSIT")]
[assembly: AssemblyProduct("Orchard.Recipes")]
[assembly: AssemblyCopyright("Copyright © MSIT 2011")]
[assembly: AssemblyProduct("Orchard")]
[assembly: AssemblyCopyright("Copyright © Outercurve Foundation 2009")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -31,5 +30,6 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.20")]
[assembly: AssemblyFileVersion("1.0.20")]
[assembly: SecurityTransparent]

View File

@@ -4,8 +4,8 @@ using Orchard.Recipes.Models;
using Orchard.Recipes.Services;
namespace Orchard.Recipes.RecipeHandlers {
public class MetaDataRecipeHandler : IRecipeHandler {
public MetaDataRecipeHandler() {
public class MetadataRecipeHandler : IRecipeHandler {
public MetadataRecipeHandler() {
Logger = NullLogger.Instance;
T = NullLocalizer.Instance;
}
@@ -13,7 +13,7 @@ namespace Orchard.Recipes.RecipeHandlers {
public Localizer T { get; set; }
ILogger Logger { get; set; }
// handles the <MetaData> step
// handles the <Metadata> step
public void ExecuteRecipeStep(RecipeContext recipeContext) {
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Orchard.Environment.Extensions;
using Orchard.FileSystems.WebSite;
using Orchard.Localization;
using Orchard.Logging;
using Orchard.Recipes.Models;
namespace Orchard.Recipes.Services {
public class RecipeHarvester : IRecipeHarvester {
private readonly IExtensionManager _extensionManager;
private readonly IWebSiteFolder _webSiteFolder;
private readonly IRecipeParser _recipeParser;
public RecipeHarvester(
IExtensionManager extensionManager,
IWebSiteFolder webSiteFolder,
IRecipeParser recipeParser) {
_extensionManager = extensionManager;
_webSiteFolder = webSiteFolder;
_recipeParser = recipeParser;
Logger = NullLogger.Instance;
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
ILogger Logger { get; set; }
public IEnumerable<Recipe> HarvestRecipes(string extensionName) {
var recipes = new List<Recipe>();
var extension = _extensionManager.GetExtension(extensionName);
if (extension != null) {
var recipeLocation = Path.Combine(extension.Location, extensionName, "Recipes");
var recipeFiles = _webSiteFolder.ListFiles(recipeLocation, true);
recipes.AddRange(
from recipeFile in recipeFiles
where recipeFile.EndsWith(".recipe.xml", StringComparison.OrdinalIgnoreCase)
select _recipeParser.ParseRecipe(_webSiteFolder.ReadFile(recipeFile)));
}
else {
Logger.Error("Could not discover recipes because module '{0}' was not found.", extensionName);
}
return recipes;
}
}
}

View File

@@ -1,27 +1,13 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Orchard.Environment.Extensions;
using Orchard.FileSystems.WebSite;
using Orchard.Localization;
using Orchard.Logging;
using Orchard.Recipes.Models;
namespace Orchard.Recipes.Services {
public class RecipeManager : IRecipeManager {
private readonly IExtensionManager _extensionManager;
private readonly IWebSiteFolder _webSiteFolder;
private readonly IRecipeParser _recipeParser;
private readonly IEnumerable<IRecipeHandler> _recipeHandlers;
public RecipeManager(
IExtensionManager extensionManager,
IWebSiteFolder webSiteFolder,
IRecipeParser recipeParser,
IEnumerable<IRecipeHandler> recipeHandlers) {
_extensionManager = extensionManager;
_webSiteFolder = webSiteFolder;
_recipeParser = recipeParser;
public RecipeManager(IEnumerable<IRecipeHandler> recipeHandlers) {
_recipeHandlers = recipeHandlers;
Logger = NullLogger.Instance;
@@ -36,6 +22,7 @@ namespace Orchard.Recipes.Services {
// TODO: Run each step inside a transaction boundary.
// TODO: Output should go into a report.
// TODO: Eventually return a guid.tostring("n") execution id
foreach (var recipeStep in recipe.RecipeSteps) {
recipeContext.RecipeStep = recipeStep;
recipeContext.Executed = false;
@@ -47,23 +34,5 @@ namespace Orchard.Recipes.Services {
}
}
}
public IEnumerable<Recipe> DiscoverRecipes(string extensionName) {
var recipes = new List<Recipe>();
var extension = _extensionManager.GetExtension(extensionName);
if (extension != null) {
var recipeLocation = Path.Combine(extension.Location, extensionName, "Recipes");
var recipeFiles = _webSiteFolder.ListFiles(recipeLocation, true);
recipes.AddRange(
from recipeFile in recipeFiles
where recipeFile.EndsWith(".recipe.xml")
select _recipeParser.ParseRecipe(_webSiteFolder.ReadFile(recipeFile)));
}
else {
Logger.Error("Could not discover recipes because module '{0}' was not found.", extensionName);
}
return recipes;
}
}
}

View File

@@ -26,29 +26,38 @@ namespace Orchard.Recipes.Services {
textReader.Close();
foreach (var element in recipeTree.Elements()) {
switch(element.Name.ToString()) {
case "Name":
recipe.Name = element.Value;
break;
case "Description":
recipe.Description = element.Value;
break;
case "Author":
recipe.Author = element.Value;
break;
case "WebSite":
recipe.WebSite = element.Value;
break;
case "Version":
recipe.Version = element.Value;
break;
case "Tags":
recipe.Tags = element.Value;
break;
default:
var recipeStep = new RecipeStep {Name = element.Name.ToString(), Step = element};
recipeSteps.Add(recipeStep);
break;
// Recipe mETaDaTA
if (element.Name.LocalName == "Recipe") {
foreach (var metadataElement in element.Elements()) {
switch (metadataElement.Name.LocalName) {
case "Name":
recipe.Name = metadataElement.Value;
break;
case "Description":
recipe.Description = metadataElement.Value;
break;
case "Author":
recipe.Author = metadataElement.Value;
break;
case "WebSite":
recipe.WebSite = metadataElement.Value;
break;
case "Version":
recipe.Version = metadataElement.Value;
break;
case "Tags":
recipe.Tags = metadataElement.Value;
break;
default:
Logger.Error("Unrecognized recipe metadata element {0} encountered. Skipping.", metadataElement.Name.LocalName);
break;
}
}
}
// Recipe step
else {
var recipeStep = new RecipeStep { Name = element.Name.LocalName, Step = element };
recipeSteps.Add(recipeStep);
}
}
recipe.RecipeSteps = recipeSteps;