mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
#19778: Implementing Import/Export for Workflows.
Work Item: 19778 --HG-- branch : 1.x
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Events;
|
||||
|
||||
namespace Orchard.Workflows.ImportExport {
|
||||
public interface ICustomExportStep : IEventHandler {
|
||||
void Register(IList<string> steps);
|
||||
}
|
||||
|
||||
public class WorkflowsCustomExportStep : ICustomExportStep {
|
||||
public void Register(IList<string> steps) {
|
||||
steps.Add("Workflows");
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Orchard.Data;
|
||||
using Orchard.Events;
|
||||
using Orchard.Workflows.Models;
|
||||
|
||||
namespace Orchard.Workflows.ImportExport {
|
||||
public interface IExportEventHandler : IEventHandler {
|
||||
void Exporting(dynamic context);
|
||||
void Exported(dynamic context);
|
||||
}
|
||||
|
||||
public class WorkflowsExportEventHandler : IExportEventHandler {
|
||||
private readonly IRepository<WorkflowDefinitionRecord> _workflowDefinitionRepository;
|
||||
|
||||
public WorkflowsExportEventHandler(IRepository<WorkflowDefinitionRecord> workflowDefinitionRepository) {
|
||||
_workflowDefinitionRepository = workflowDefinitionRepository;
|
||||
}
|
||||
|
||||
public void Exporting(dynamic context) {
|
||||
}
|
||||
|
||||
public void Exported(dynamic context) {
|
||||
|
||||
if (!((IEnumerable<string>)context.ExportOptions.CustomSteps).Contains("Workflows")) {
|
||||
return;
|
||||
}
|
||||
|
||||
var workflowDefinitions = _workflowDefinitionRepository.Table.ToList();
|
||||
|
||||
if (!workflowDefinitions.Any()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var root = new XElement("Workflows");
|
||||
context.Document.Element("Orchard").Add(root);
|
||||
|
||||
foreach (var workflowDefinition in workflowDefinitions) {
|
||||
root.Add(new XElement("Workflow",
|
||||
new XAttribute("Name", workflowDefinition.Name),
|
||||
new XAttribute("Enabled", workflowDefinition.Enabled),
|
||||
new XElement("Activities", workflowDefinition.ActivityRecords.Select(activity =>
|
||||
new XElement("Activity",
|
||||
new XAttribute("Id", activity.Id),
|
||||
new XAttribute("Name", activity.Name),
|
||||
new XAttribute("Start", activity.Start),
|
||||
new XAttribute("X", activity.X),
|
||||
new XAttribute("Y", activity.Y),
|
||||
new XElement("State", activity.State)))),
|
||||
new XElement("Transitions", workflowDefinition.TransitionRecords.Select(transition =>
|
||||
new XElement("Transition",
|
||||
new XAttribute("SourceActivityId", transition.SourceActivityRecord.Id),
|
||||
new XAttribute("SourceEndpoint", transition.SourceEndpoint ?? ""),
|
||||
new XAttribute("DestinationActivityId", transition.DestinationActivityRecord.Id),
|
||||
new XAttribute("DestinationEndpoint", transition.DestinationEndpoint ?? ""))))));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Data;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Logging;
|
||||
using Orchard.Recipes.Models;
|
||||
using Orchard.Recipes.Services;
|
||||
using Orchard.Workflows.Models;
|
||||
|
||||
namespace Orchard.Workflows.ImportExport {
|
||||
public class WorkflowsRecipeHandler : IRecipeHandler {
|
||||
private readonly IRepository<WorkflowDefinitionRecord> _workflowDefinitionRepository;
|
||||
|
||||
public WorkflowsRecipeHandler(IRepository<WorkflowDefinitionRecord> workflowDefinitionRepository) {
|
||||
_workflowDefinitionRepository = workflowDefinitionRepository;
|
||||
Logger = NullLogger.Instance;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public void ExecuteRecipeStep(RecipeContext recipeContext) {
|
||||
if (!String.Equals(recipeContext.RecipeStep.Name, "Workflows", StringComparison.OrdinalIgnoreCase)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var workflowDefinitionElement in recipeContext.RecipeStep.Step.Elements()) {
|
||||
var workflowDefinition = new WorkflowDefinitionRecord {
|
||||
Name = ProbeWorkflowDefinitionName(workflowDefinitionElement.Attribute("Name").Value),
|
||||
Enabled = Boolean.Parse(workflowDefinitionElement.Attribute("Enabled").Value)
|
||||
};
|
||||
|
||||
_workflowDefinitionRepository.Create(workflowDefinition);
|
||||
|
||||
var activitiesElement = workflowDefinitionElement.Element("Activities");
|
||||
var transitionsElement = workflowDefinitionElement.Element("Transitions");
|
||||
var activitiesDictionary = new Dictionary<int, ActivityRecord>();
|
||||
|
||||
foreach (var activityElement in activitiesElement.Elements()) {
|
||||
var localId = Int32.Parse(activityElement.Attribute("Id").Value);
|
||||
var activity = new ActivityRecord {
|
||||
Name = activityElement.Attribute("Name").Value,
|
||||
Start = Boolean.Parse(activityElement.Attribute("Start").Value),
|
||||
X = Int32.Parse(activityElement.Attribute("X").Value),
|
||||
Y = Int32.Parse(activityElement.Attribute("Y").Value),
|
||||
State = activityElement.Element("State").Value
|
||||
};
|
||||
|
||||
activitiesDictionary.Add(localId, activity);
|
||||
workflowDefinition.ActivityRecords.Add(activity);
|
||||
}
|
||||
|
||||
foreach (var transitionElement in transitionsElement.Elements()) {
|
||||
var sourceActivityId = Int32.Parse(transitionElement.Attribute("SourceActivityId").Value);
|
||||
var sourceEndpoint = transitionElement.Attribute("SourceEndpoint").Value;
|
||||
var destinationActivityId = Int32.Parse(transitionElement.Attribute("DestinationActivityId").Value);
|
||||
var destinationEndpoint = transitionElement.Attribute("DestinationEndpoint").Value;
|
||||
|
||||
workflowDefinition.TransitionRecords.Add(new TransitionRecord {
|
||||
SourceActivityRecord = activitiesDictionary[sourceActivityId],
|
||||
SourceEndpoint = sourceEndpoint,
|
||||
DestinationActivityRecord = activitiesDictionary[destinationActivityId],
|
||||
DestinationEndpoint = destinationEndpoint
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
recipeContext.Executed = true;
|
||||
}
|
||||
|
||||
private string ProbeWorkflowDefinitionName(string name) {
|
||||
var count = 0;
|
||||
var newName = name;
|
||||
WorkflowDefinitionRecord workflowDefinition;
|
||||
|
||||
do {
|
||||
var localName = newName;
|
||||
workflowDefinition = _workflowDefinitionRepository.Get(x => x.Name == localName);
|
||||
|
||||
if (workflowDefinition != null) {
|
||||
newName = string.Format("{0}-{1}", name, ++count);
|
||||
}
|
||||
|
||||
} while (workflowDefinition != null);
|
||||
|
||||
return newName;
|
||||
}
|
||||
}
|
||||
}
|
@@ -164,6 +164,9 @@
|
||||
<Compile Include="Forms\WebRequestForm.cs" />
|
||||
<Compile Include="Handlers\ContentHandler.cs" />
|
||||
<Compile Include="Handlers\WorkflowHandler.cs" />
|
||||
<Compile Include="ImportExport\WorkflowsCustomExportStep.cs" />
|
||||
<Compile Include="ImportExport\WorkflowsExportEventHandler.cs" />
|
||||
<Compile Include="ImportExport\WorkflowsRecipeHandler.cs" />
|
||||
<Compile Include="Models\AwaitingActivityRecord.cs" />
|
||||
<Compile Include="Models\CancellationToken.cs" />
|
||||
<Compile Include="Models\ActivityContext.cs" />
|
||||
|
Reference in New Issue
Block a user