Added ImportCompleted event.

This event is invoked after all content items have been imported.
This commit is contained in:
Sipke Schoorstra 2015-10-09 23:52:35 +02:00
parent ee43743621
commit df2ab76613
19 changed files with 138 additions and 44 deletions

View File

@ -1,4 +1,6 @@
using System.Linq;
using System;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentManagement.Handlers;
@ -100,20 +102,24 @@ namespace Orchard.Layouts.Drivers {
}
protected override void Importing(ElementWrapperPart part, ImportContentContext context) {
var root = context.Data.Element(part.PartDefinition.Name);
if (root == null)
return;
var exportedData = root.Value;
var describeContext = CreateDescribeContext(part);
var element = _serializer.Deserialize(exportedData, describeContext);
_elementManager.Importing(new[]{element}, new ImportLayoutContext { Session = new ImportContentContextWrapper(context)});
part.ElementData = element.Data.Serialize();
HandleImportEvent(part, context, (describeContext, element) => {
_elementManager.Importing(new[] { element }, new ImportLayoutContext { Session = new ImportContentContextWrapper(context) });
});
}
protected override void Imported(ElementWrapperPart part, ImportContentContext context) {
HandleImportEvent(part, context, (describeContext, element) => {
_elementManager.Imported(new[] { element }, new ImportLayoutContext { Session = new ImportContentContextWrapper(context) });
});
}
protected override void ImportCompleted(ElementWrapperPart part, ImportContentContext context) {
HandleImportEvent(part, context, (describeContext, element) => {
_elementManager.ImportCompleted(new[] { element }, new ImportLayoutContext { Session = new ImportContentContextWrapper(context) });
});
}
private void HandleImportEvent(ElementWrapperPart part, ImportContentContext context, Action<DescribeElementsContext, Element> callback) {
var root = context.Data.Element(part.PartDefinition.Name);
if (root == null)
@ -123,7 +129,7 @@ namespace Orchard.Layouts.Drivers {
var describeContext = CreateDescribeContext(part);
var element = _serializer.Deserialize(exportedData, describeContext);
_elementManager.Imported(new[] { element }, new ImportLayoutContext { Session = new ImportContentContextWrapper(context) });
callback(describeContext, element);
part.ElementData = element.Data.Serialize();
}

View File

@ -144,29 +144,31 @@ namespace Orchard.Layouts.Drivers {
}
protected override void Importing(LayoutPart part, ImportContentContext context) {
// Don't do anything if the tag is not specified.
if (context.Data.Element(part.PartDefinition.Name) == null) {
return;
}
context.ImportChildEl(part.PartDefinition.Name, "LayoutData", s => {
part.LayoutData = s;
_layoutManager.Importing(new ImportLayoutContext {
Layout = part,
Session = new ImportContentContextWrapper(context)
HandleImportEvent(part, context, importLayoutContext => {
context.ImportChildEl(part.PartDefinition.Name, "LayoutData", s => {
part.LayoutData = s;
_layoutManager.Importing(importLayoutContext);
});
});
context.ImportAttribute(part.PartDefinition.Name, "TemplateId", s => part.TemplateId = GetTemplateId(context, s));
context.ImportAttribute(part.PartDefinition.Name, "TemplateId", s => part.TemplateId = GetTemplateId(context, s));
});
}
protected override void Imported(LayoutPart part, ImportContentContext context) {
HandleImportEvent(part, context, importLayoutContext => _layoutManager.Imported(importLayoutContext));
}
protected override void ImportCompleted(LayoutPart part, ImportContentContext context) {
HandleImportEvent(part, context, importLayoutContext => _layoutManager.ImportCompleted(importLayoutContext));
}
private void HandleImportEvent(LayoutPart part, ImportContentContext context, Action<ImportLayoutContext> callback) {
// Don't do anything if the tag is not specified.
if (context.Data.Element(part.PartDefinition.Name) == null) {
return;
}
_layoutManager.Imported(new ImportLayoutContext {
callback(new ImportLayoutContext {
Layout = part,
Session = new ImportContentContextWrapper(context)
});

View File

@ -298,7 +298,7 @@ namespace Orchard.Layouts.Drivers {
}
}
protected override void OnImported(Projection element, ImportElementContext context) {
protected override void OnImportCompleted(Projection element, ImportElementContext context) {
var queryIdentity = context.ExportableData.Get("QueryId");
var query = queryIdentity != null ? context.Session.GetItemFromSession(queryIdentity) : default(ContentManagement.ContentItem);

View File

@ -53,6 +53,10 @@ namespace Orchard.Layouts.Framework.Drivers {
OnImported((TElement)context.Element, context);
}
public void ImportCompleted(ImportElementContext context) {
OnImportCompleted((TElement)context.Element, context);
}
protected virtual EditorResult OnBuildEditor(TElement element, ElementEditorContext context) {
return null;
}
@ -88,6 +92,9 @@ namespace Orchard.Layouts.Framework.Drivers {
protected virtual void OnImported(TElement element, ImportElementContext context) {
}
protected virtual void OnImportCompleted(TElement element, ImportElementContext context) {
}
protected EditorResult Editor(ElementEditorContext context, params dynamic[] editorShapes) {
foreach (var editorShape in editorShapes) {
if (String.IsNullOrWhiteSpace(editorShape.Metadata.Position)) {

View File

@ -15,5 +15,6 @@ namespace Orchard.Layouts.Framework.Drivers {
void Exported(ExportElementContext context);
void Importing(ImportElementContext context);
void Imported(ImportElementContext context);
void ImportCompleted(ImportElementContext context);
}
}

View File

@ -201,6 +201,18 @@ namespace Orchard.Layouts.Services {
});
}
public void ImportCompleted(IEnumerable<Element> elements, ImportLayoutContext context) {
InvokeDriver(elements, (driver, element) => {
var importElementContext = new ImportElementContext {
Layout = context.Layout,
Element = element,
ExportableData = element.ExportableData,
Session = context.Session
};
driver.ImportCompleted(importElementContext);
});
}
private IDictionary<string, Category> GetCategories() {
var providers = _categoryProviders.Value;
var categories = providers.SelectMany(x => x.GetCategories());

View File

@ -26,5 +26,6 @@ namespace Orchard.Layouts.Services {
void Exported(IEnumerable<Element> elements, ExportLayoutContext context);
void Importing(IEnumerable<Element> elements, ImportLayoutContext context);
void Imported(IEnumerable<Element> elements, ImportLayoutContext context);
void ImportCompleted(IEnumerable<Element> elements, ImportLayoutContext context);
}
}

View File

@ -57,5 +57,6 @@ namespace Orchard.Layouts.Services {
void Exported(ExportLayoutContext context);
void Importing(ImportLayoutContext context);
void Imported(ImportLayoutContext context);
void ImportCompleted(ImportLayoutContext context);
}
}

View File

@ -91,6 +91,14 @@ namespace Orchard.Layouts.Services {
context.Layout.LayoutData = _serializer.Serialize(elementTree);
}
public void ImportCompleted(ImportLayoutContext context) {
var elementTree = LoadElements(context.Layout).ToArray();
var elements = elementTree.Flatten().ToArray();
_elementManager.ImportCompleted(elements, context);
context.Layout.LayoutData = _serializer.Serialize(elementTree);
}
public dynamic RenderLayout(string data, string displayType = null, IContent content = null) {
var elements = _serializer.Deserialize(data, new DescribeElementsContext { Content = content });
var layoutRoot = _elementDisplay.DisplayElements(elements, content, displayType);

View File

@ -307,23 +307,22 @@ namespace Orchard.Projections.Drivers {
context.ImportAttribute(part.PartDefinition.Name, "DisplayPager", x => part.Record.DisplayPager = Boolean.Parse(x));
}
protected override void Imported(ProjectionPart part, ImportContentContext context) {
protected override void ImportCompleted(ProjectionPart part, ImportContentContext context) {
// Assign the query only when everything is imported.
var query = context.Attribute(part.PartDefinition.Name, "Query");
if (query != null) {
part.Record.QueryPartRecord = context.GetItemFromSession(query).As<QueryPart>().Record;
var layoutIndex = context.Attribute(part.PartDefinition.Name, "LayoutIndex");
int layoutIndexValue;
if (layoutIndex != null
if (layoutIndex != null
&& Int32.TryParse(layoutIndex, out layoutIndexValue)
&& layoutIndexValue >= 0
&& part.Record.QueryPartRecord.Layouts.Count > layoutIndexValue)
{
&& part.Record.QueryPartRecord.Layouts.Count > layoutIndexValue) {
part.Record.LayoutRecord = part.Record.QueryPartRecord.Layouts[Int32.Parse(layoutIndex)];
}
}
}
protected override void Exporting(ProjectionPart part, ExportContentContext context) {
context.Element(part.PartDefinition.Name).SetAttributeValue("Items", part.Record.Items);
context.Element(part.PartDefinition.Name).SetAttributeValue("ItemsPerPage", part.Record.ItemsPerPage);

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Xml.Linq;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Handlers;
using Orchard.Data;
using Orchard.Localization;
using Orchard.Logging;
@ -13,14 +14,17 @@ namespace Orchard.Recipes.Providers.Executors {
public class ContentStep : RecipeExecutionStep {
private readonly IOrchardServices _orchardServices;
private readonly ITransactionManager _transactionManager;
private readonly Lazy<IEnumerable<IContentHandler>> _handlers;
public ContentStep(
IOrchardServices orchardServices,
ITransactionManager transactionManager,
Lazy<IEnumerable<IContentHandler>> handlers,
RecipeExecutionLogger logger) : base(logger) {
_orchardServices = orchardServices;
_transactionManager = transactionManager;
_handlers = handlers;
BatchSize = 64;
}
@ -71,6 +75,22 @@ namespace Orchard.Recipes.Providers.Executors {
// <Data />
// Import Data.
public override void Execute(RecipeExecutionContext context) {
// Run the import.
BatchedInvoke(context, (itemId, nextIdentityValue, element, importContentSession, elementDictionary) => {
_orchardServices.ContentManager.Import(element, importContentSession);
});
// Invoke ImportCompleted.
BatchedInvoke(context, (itemId, nextIdentityValue, element, importContentSession, elementDictionary) => {
var contentItem = importContentSession.Get(itemId, VersionOptions.Latest);
var importContentContext = new ImportContentContext(contentItem, elementDictionary[nextIdentityValue], importContentSession);
foreach (var handler in _handlers.Value) {
handler.ImportCompleted(importContentContext);
}
});
}
private void BatchedInvoke(RecipeExecutionContext context, Action<string, string, XElement, ImportContentSession, IDictionary<string, XElement>> contentItemAction) {
var importContentSession = new ImportContentSession(_orchardServices.ContentManager);
// Populate local dictionary with elements and their ids.
@ -82,15 +102,15 @@ namespace Orchard.Recipes.Providers.Executors {
}
// Determine if the import is to be batched in multiple transactions.
var startIndex = 0;
var itemIndex = 0;
var batchSize = GetBatchSizeForDataStep(context.RecipeStep.Step);
Logger.Debug("Using batch size {0}.", batchSize);
// Run the import.
var startIndex = 0;
var itemIndex = 0;
Logger.Debug("Using batch size {0}.", batchSize);
try {
while (startIndex < elementDictionary.Count) {
Logger.Debug("Importing batch starting at index {0}.", startIndex);
Logger.Debug("Batch execution starting at index {0}.", startIndex);
importContentSession.InitializeBatch(startIndex, batchSize);
// The session determines which items are included in the current batch
@ -102,14 +122,12 @@ namespace Orchard.Recipes.Providers.Executors {
if (elementDictionary[nextIdentityValue].HasAttributes) {
itemId = elementDictionary[nextIdentityValue].FirstAttribute.Value;
}
Logger.Information("Importing data item '{0}' (item {1}/{2}).", itemId, itemIndex + 1, elementDictionary.Count);
Logger.Information("Handling content item '{0}' (item {1}/{2}).", itemId, itemIndex + 1, elementDictionary.Count);
try {
_orchardServices.ContentManager.Import(
elementDictionary[nextIdentityValue],
importContentSession);
contentItemAction(itemId, nextIdentityValue, elementDictionary[nextIdentityValue], importContentSession, elementDictionary);
}
catch (Exception ex) {
Logger.Error(ex, "Error while importing data item '{0}'.", itemId);
Logger.Error(ex, "Error while handling content item '{0}'.", itemId);
throw;
}
itemIndex++;
@ -123,7 +141,7 @@ namespace Orchard.Recipes.Providers.Executors {
_transactionManager.RequireNew();
}
Logger.Debug("Finished importing batch starting at index {0}.", startIndex);
Logger.Debug("Finished batch starting at index {0}.", startIndex);
}
}
catch (Exception) {

View File

@ -129,6 +129,12 @@ namespace Orchard.ContentManagement.Drivers {
Imported(part, context);
}
void IContentPartDriver.ImportCompleted(ImportContentContext context) {
var part = context.ContentItem.As<TContent>();
if (part != null)
ImportCompleted(part, context);
}
void IContentPartDriver.Exporting(ExportContentContext context) {
var part = context.ContentItem.As<TContent>();
if (part != null)
@ -149,6 +155,7 @@ namespace Orchard.ContentManagement.Drivers {
protected virtual void Importing(TContent part, ImportContentContext context) { }
protected virtual void Imported(TContent part, ImportContentContext context) { }
protected virtual void ImportCompleted(TContent part, ImportContentContext context) { }
protected virtual void Exporting(TContent part, ExportContentContext context) { }
protected virtual void Exported(TContent part, ExportContentContext context) { }

View File

@ -78,6 +78,12 @@ namespace Orchard.ContentManagement.Drivers.Coordinators {
}
}
public override void ImportCompleted(ImportContentContext context) {
foreach (var contentPartDriver in _drivers) {
contentPartDriver.ImportCompleted(context);
}
}
public override void Exporting(ExportContentContext context) {
foreach (var contentPartDriver in _drivers.OrderBy(x => x.GetPartInfo().First().PartName)) {
contentPartDriver.Exporting(context);

View File

@ -9,6 +9,7 @@ namespace Orchard.ContentManagement.Drivers {
DriverResult UpdateEditor(UpdateEditorContext context);
void Importing(ImportContentContext context);
void Imported(ImportContentContext context);
void ImportCompleted(ImportContentContext context);
void Exporting(ExportContentContext context);
void Exported(ExportContentContext context);
IEnumerable<ContentPartInfo> GetPartInfo();

View File

@ -104,6 +104,10 @@ namespace Orchard.ContentManagement.Handlers {
Filters.Add(new InlineStorageFilter<TPart> { OnImported = handler });
}
protected void OnImportedAll<TPart>(Action<ImportContentContext, TPart> handler) where TPart : class, IContent {
Filters.Add(new InlineStorageFilter<TPart> { OnImportCompleted = handler });
}
protected void OnExporting<TPart>(Action<ExportContentContext, TPart> handler) where TPart : class, IContent {
Filters.Add(new InlineStorageFilter<TPart> { OnExporting = handler });
}
@ -157,6 +161,7 @@ namespace Orchard.ContentManagement.Handlers {
public Action<IndexContentContext, TPart> OnIndexed { get; set; }
public Action<ImportContentContext, TPart> OnImporting { get; set; }
public Action<ImportContentContext, TPart> OnImported { get; set; }
public Action<ImportContentContext, TPart> OnImportCompleted { get; set; }
public Action<ExportContentContext, TPart> OnExporting { get; set; }
public Action<ExportContentContext, TPart> OnExported { get; set; }
public Action<RestoreContentContext, TPart> OnRestoring { get; set; }
@ -230,6 +235,10 @@ namespace Orchard.ContentManagement.Handlers {
if (OnImported != null)
OnImported(context, instance);
}
protected override void ImportCompleted(ImportContentContext context, TPart instance) {
if (OnImportCompleted != null)
OnImportCompleted(context, instance);
}
protected override void Exporting(ExportContentContext context, TPart instance) {
if (OnExporting != null)
OnExporting(context, instance);
@ -407,6 +416,12 @@ namespace Orchard.ContentManagement.Handlers {
Imported(context);
}
void IContentHandler.ImportCompleted(ImportContentContext importContentContext) {
foreach (var filter in Filters.OfType<IContentStorageFilter>())
filter.ImportCompleted(importContentContext);
ImportedAll(importContentContext);
}
void IContentHandler.Exporting(ExportContentContext context) {
foreach (var filter in Filters.OfType<IContentStorageFilter>())
filter.Exporting(context);
@ -496,6 +511,7 @@ namespace Orchard.ContentManagement.Handlers {
protected virtual void Importing(ImportContentContext context) { }
protected virtual void Imported(ImportContentContext context) { }
protected virtual void ImportedAll(ImportContentContext context) { }
protected virtual void Exporting(ExportContentContext context) { }
protected virtual void Exported(ExportContentContext context) { }
protected virtual void Restoring(RestoreContentContext context) { }

View File

@ -22,6 +22,7 @@
public virtual void Indexed(IndexContentContext context) {}
public virtual void Importing(ImportContentContext context) {}
public virtual void Imported(ImportContentContext context) {}
public virtual void ImportCompleted(ImportContentContext importContentContext) {}
public virtual void Exporting(ExportContentContext context) {}
public virtual void Exported(ExportContentContext context) {}
public virtual void Restoring(RestoreContentContext context) { }

View File

@ -22,6 +22,7 @@
void Indexed(IndexContentContext context);
void Importing(ImportContentContext context);
void Imported(ImportContentContext context);
void ImportCompleted(ImportContentContext importContentContext);
void Exporting(ExportContentContext context);
void Exported(ExportContentContext context);

View File

@ -21,6 +21,7 @@ namespace Orchard.ContentManagement.Handlers {
void Indexed(IndexContentContext context);
void Importing(ImportContentContext context);
void Imported(ImportContentContext context);
void ImportCompleted(ImportContentContext context);
void Exporting(ExportContentContext context);
void Exported(ExportContentContext context);
void Restoring(RestoreContentContext context);

View File

@ -23,6 +23,7 @@ namespace Orchard.ContentManagement.Handlers {
protected virtual void Indexed(IndexContentContext context, TPart instance) { }
protected virtual void Importing(ImportContentContext context, TPart instance) { }
protected virtual void Imported(ImportContentContext context, TPart instance) { }
protected virtual void ImportCompleted(ImportContentContext context, TPart instance) { }
protected virtual void Exporting(ExportContentContext context, TPart instance) { }
protected virtual void Exported(ExportContentContext context, TPart instance) { }
protected virtual void Restoring(RestoreContentContext context, TPart instance) { }
@ -135,6 +136,11 @@ namespace Orchard.ContentManagement.Handlers {
Imported(context, context.ContentItem.As<TPart>());
}
void IContentStorageFilter.ImportCompleted(ImportContentContext context) {
if (context.ContentItem.Is<TPart>())
ImportCompleted(context, context.ContentItem.As<TPart>());
}
void IContentStorageFilter.Exporting(ExportContentContext context) {
if (context.ContentItem.Is<TPart>())
Exporting(context, context.ContentItem.As<TPart>());