mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Refactoring Import/Export optimizations
--HG-- branch : 1.x
This commit is contained in:
@@ -39,58 +39,6 @@ namespace Orchard.Tests.ContentManagement {
|
||||
var identity2 = new ContentIdentity(@"/foo=bar/abaz=quux\/fr\\ed=foo/yarg=yiu=foo");
|
||||
Assert.That(comparer.Equals(identity2, new ContentIdentity(identity2.ToString())));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IdentitiesCanBeAddedWithNoPriority() {
|
||||
var contentIdentity = new ContentIdentity();
|
||||
|
||||
contentIdentity.Add("identifier", "CAEEB150-F5E9-481D-9FF9-3053D23329C1");
|
||||
contentIdentity.Add("alias", "some-unique-item-alias/sub-alias");
|
||||
|
||||
Assert.That("/alias=some-unique-item-alias\\/sub-alias/identifier=CAEEB150-F5E9-481D-9FF9-3053D23329C1", Is.EqualTo(contentIdentity.ToString()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IdentitiesCanBeAddedWithSamePriority() {
|
||||
var contentIdentity = new ContentIdentity();
|
||||
contentIdentity.Add("identifier", "CAEEB150-F5E9-481D-9FF9-3053D23329C1", 5);
|
||||
contentIdentity.Add("alias", "some-unique-item-alias/sub-alias", 5);
|
||||
|
||||
var contentIdentityNegative = new ContentIdentity();
|
||||
contentIdentityNegative.Add("identifier", "CAEEB150-F5E9-481D-9FF9-3053D23329C1", -5);
|
||||
contentIdentityNegative.Add("alias", "some-unique-item-alias/sub-alias", -5);
|
||||
|
||||
Assert.That("/alias=some-unique-item-alias\\/sub-alias/identifier=CAEEB150-F5E9-481D-9FF9-3053D23329C1", Is.EqualTo(contentIdentity.ToString()));
|
||||
Assert.That("/alias=some-unique-item-alias\\/sub-alias/identifier=CAEEB150-F5E9-481D-9FF9-3053D23329C1", Is.EqualTo(contentIdentityNegative.ToString()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LowestPriorityIdentityIsIgnored() {
|
||||
var contentIdentity = new ContentIdentity();
|
||||
contentIdentity.Add("alias", "some-unique-item-alias/sub-alias", 0);
|
||||
contentIdentity.Add("identifier", "CAEEB150-F5E9-481D-9FF9-3053D23329C1", 5);
|
||||
|
||||
var contentIdentityNegative = new ContentIdentity();
|
||||
contentIdentityNegative.Add("alias", "some-unique-item-alias/sub-alias", -5);
|
||||
contentIdentityNegative.Add("identifier", "CAEEB150-F5E9-481D-9FF9-3053D23329C1", 0);
|
||||
|
||||
Assert.That("/identifier=CAEEB150-F5E9-481D-9FF9-3053D23329C1", Is.EqualTo(contentIdentity.ToString()));
|
||||
Assert.That("/identifier=CAEEB150-F5E9-481D-9FF9-3053D23329C1", Is.EqualTo(contentIdentityNegative.ToString()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void HighestPriorityIdentityIsRetained() {
|
||||
var contentIdentity = new ContentIdentity();
|
||||
contentIdentity.Add("identifier", "CAEEB150-F5E9-481D-9FF9-3053D23329C1", 5);
|
||||
contentIdentity.Add("alias", "some-unique-item-alias/sub-alias", 0);
|
||||
|
||||
var contentIdentityNegative = new ContentIdentity();
|
||||
contentIdentityNegative.Add("identifier", "CAEEB150-F5E9-481D-9FF9-3053D23329C1", 0);
|
||||
contentIdentityNegative.Add("alias", "some-unique-item-alias/sub-alias", -5);
|
||||
|
||||
Assert.That("/identifier=CAEEB150-F5E9-481D-9FF9-3053D23329C1", Is.EqualTo(contentIdentity.ToString()));
|
||||
Assert.That("/identifier=CAEEB150-F5E9-481D-9FF9-3053D23329C1", Is.EqualTo(contentIdentityNegative.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Moq;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Records;
|
||||
@@ -42,7 +39,6 @@ namespace Orchard.Tests.ContentManagement {
|
||||
|
||||
_contentManager.Setup(m => m.New(It.IsAny<string>())).Returns(draftItem5);
|
||||
|
||||
_contentManager.Setup(m => m.HasResolverForIdentity(It.Is<ContentIdentity>(id => id.Get("ItemId") != null))).Returns(true);
|
||||
_contentManager.Setup(m => m.ResolveIdentity(It.Is<ContentIdentity>(id => id.Get("ItemId") == "1"))).Returns(publishedItem);
|
||||
}
|
||||
#endregion
|
||||
|
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Core.Common.Models;
|
||||
@@ -9,14 +8,10 @@ using Orchard.ContentManagement.Handlers;
|
||||
namespace Orchard.Core.Common.Handlers {
|
||||
[UsedImplicitly]
|
||||
public class IdentityPartHandler : ContentHandler {
|
||||
private readonly IContentManager _contentManager;
|
||||
|
||||
public IdentityPartHandler(IRepository<IdentityPartRecord> identityRepository,
|
||||
IContentManager contentManager) {
|
||||
Filters.Add(StorageFilter.For(identityRepository));
|
||||
OnInitializing<IdentityPart>(AssignIdentity);
|
||||
|
||||
_contentManager = contentManager;
|
||||
}
|
||||
|
||||
protected void AssignIdentity(InitializingContentContext context, IdentityPart part) {
|
||||
@@ -30,24 +25,5 @@ namespace Orchard.Core.Common.Handlers {
|
||||
context.Metadata.Identity.Add("Identifier", part.Identifier);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void RegisterIdentityResolver(RegisterIdentityResolverContext context) {
|
||||
context.Register(id => id.Get("Identifier") != null, ResolveIdentity);
|
||||
}
|
||||
|
||||
private ContentItem ResolveIdentity(ContentIdentity identity) {
|
||||
var identifier = identity.Get("Identifier");
|
||||
|
||||
if (identifier == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var comparer = new ContentIdentity.ContentIdentityEqualityComparer();
|
||||
return _contentManager
|
||||
.Query<IdentityPart, IdentityPartRecord>()
|
||||
.Where(p => p.Identifier == identifier)
|
||||
.List<ContentItem>()
|
||||
.FirstOrDefault(c => comparer.Equals(identity, _contentManager.GetItemMetadata(c).Identity));
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Core.Common.Models;
|
||||
|
||||
namespace Orchard.Core.Common.Services {
|
||||
public class IdentifierResolverSelector : IIdentityResolverSelector {
|
||||
private readonly IContentManager _contentManager;
|
||||
|
||||
public IdentifierResolverSelector(IContentManager contentManager) {
|
||||
_contentManager = contentManager;
|
||||
}
|
||||
|
||||
public IdentityResolverSelectorResult GetResolver(ContentIdentity contentIdentity) {
|
||||
if (contentIdentity.Has("Identifier")) {
|
||||
return new IdentityResolverSelectorResult {
|
||||
Priority = 5,
|
||||
Resolve = ResolveIdentity
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private IEnumerable<ContentItem> ResolveIdentity(ContentIdentity identity) {
|
||||
var identifier = identity.Get("Identifier");
|
||||
|
||||
if (identifier == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var comparer = new ContentIdentity.ContentIdentityEqualityComparer();
|
||||
return _contentManager
|
||||
.Query<IdentityPart, IdentityPartRecord>()
|
||||
.Where(p => p.Identifier == identifier)
|
||||
.List<ContentItem>()
|
||||
.Where(c => comparer.Equals(identity, _contentManager.GetItemMetadata(c).Identity));
|
||||
}
|
||||
}
|
||||
}
|
@@ -79,6 +79,7 @@
|
||||
<Compile Include="Common\Models\IdentityPart.cs" />
|
||||
<Compile Include="Common\ResourceManifest.cs" />
|
||||
<Compile Include="Common\Routes.cs" />
|
||||
<Compile Include="Common\Services\IdentifierResolverSelector.cs" />
|
||||
<Compile Include="Common\Services\XmlRpcHandler.cs" />
|
||||
<Compile Include="Common\DateEditor\DateEditorViewModel.cs" />
|
||||
<Compile Include="Common\Settings\TextFieldSettingsEvents.cs" />
|
||||
|
@@ -95,6 +95,7 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="Commands\AutorouteCommands.cs" />
|
||||
<Compile Include="ResourceManifest.cs" />
|
||||
<Compile Include="Services\AliasResolverSelector.cs" />
|
||||
<Compile Include="Services\IRouteEvents.cs" />
|
||||
<Compile Include="Settings\AutorouteSettingsEvents.cs" />
|
||||
<Compile Include="Settings\RoutePattern.cs" />
|
||||
|
@@ -0,0 +1,37 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Autoroute.Models;
|
||||
using Orchard.ContentManagement;
|
||||
|
||||
namespace Orchard.Autoroute.Services {
|
||||
public class AliasResolverSelector : IIdentityResolverSelector {
|
||||
private readonly IContentManager _contentManager;
|
||||
|
||||
public AliasResolverSelector(IContentManager contentManager) {
|
||||
_contentManager = contentManager;
|
||||
}
|
||||
|
||||
public IdentityResolverSelectorResult GetResolver(ContentIdentity contentIdentity) {
|
||||
if (contentIdentity.Has("alias")) {
|
||||
return new IdentityResolverSelectorResult {
|
||||
Priority = 0,
|
||||
Resolve = ResolveIdentity
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private IEnumerable<ContentItem> ResolveIdentity(ContentIdentity identity) {
|
||||
var identifier = identity.Get("alias");
|
||||
|
||||
if (identifier == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return _contentManager
|
||||
.Query<AutoroutePart, AutoroutePartRecord>()
|
||||
.Where(p => p.DisplayAlias == identifier)
|
||||
.List<ContentItem>();
|
||||
}
|
||||
}
|
||||
}
|
@@ -6,8 +6,6 @@ using System.Text;
|
||||
namespace Orchard.ContentManagement {
|
||||
public class ContentIdentity {
|
||||
private readonly Dictionary<string, string> _dictionary;
|
||||
private int _currentIdentityPriority = int.MinValue; //initialise to lowest possible priority
|
||||
private string _encodedIdentity = null;
|
||||
|
||||
public ContentIdentity() {
|
||||
_dictionary = new Dictionary<string, string>();
|
||||
@@ -20,50 +18,36 @@ namespace Orchard.ContentManagement {
|
||||
foreach (var identityEntry in identityEntries) {
|
||||
var keyValuePair = GetIdentityKeyValue(identityEntry);
|
||||
if (keyValuePair != null) {
|
||||
Add(keyValuePair.Value.Key, UnencodeIdentityValue(keyValuePair.Value.Value));
|
||||
_dictionary.Add(keyValuePair.Value.Key, UnencodeIdentityValue(keyValuePair.Value.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(string name, string value) {
|
||||
Add(name, value, 0/*default priority*/);
|
||||
}
|
||||
|
||||
public void Add(string name, string value, int priority) {
|
||||
if (priority < _currentIdentityPriority)
|
||||
return; //lower priority, so ignore
|
||||
if (priority > _currentIdentityPriority)
|
||||
_dictionary.Clear(); //higher, so override and delete existing
|
||||
|
||||
//save the current highest priority
|
||||
_currentIdentityPriority = priority;
|
||||
|
||||
//if equal or higher priority add to identity collection
|
||||
if (_dictionary.ContainsKey(name)) {
|
||||
_dictionary[name] = value;
|
||||
}
|
||||
else {
|
||||
_dictionary.Add(name, value);
|
||||
else {
|
||||
_dictionary.Add(name, value);
|
||||
}
|
||||
_encodedIdentity = null;
|
||||
}
|
||||
|
||||
public string Get(string name) {
|
||||
return _dictionary.ContainsKey(name) ? _dictionary[name] : null;
|
||||
return Has(name) ? _dictionary[name] : null;
|
||||
}
|
||||
|
||||
public bool Has(string name) {
|
||||
return _dictionary.ContainsKey(name);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
if (_encodedIdentity != null)
|
||||
return _encodedIdentity;
|
||||
|
||||
var stringBuilder = new StringBuilder();
|
||||
foreach (var key in _dictionary.Keys.OrderBy(key => key)) {
|
||||
var escapedIdentity = EncodeIdentityValue(_dictionary[key]);
|
||||
stringBuilder.Append("/" + key + "=" + escapedIdentity);
|
||||
}
|
||||
_encodedIdentity = stringBuilder.ToString();
|
||||
return _encodedIdentity;
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
private static string EncodeIdentityValue(string identityValue) {
|
||||
@@ -161,11 +145,14 @@ namespace Orchard.ContentManagement {
|
||||
|
||||
public class ContentIdentityEqualityComparer : IEqualityComparer<ContentIdentity> {
|
||||
public bool Equals(ContentIdentity contentIdentity1, ContentIdentity contentIdentity2) {
|
||||
return contentIdentity1.ToString().Equals(contentIdentity2.ToString());
|
||||
if (contentIdentity1._dictionary.Keys.Count != contentIdentity2._dictionary.Keys.Count)
|
||||
return false;
|
||||
|
||||
return contentIdentity1._dictionary.OrderBy(kvp => kvp.Key).SequenceEqual(contentIdentity2._dictionary.OrderBy(kvp => kvp.Key));
|
||||
}
|
||||
|
||||
public int GetHashCode(ContentIdentity contentIdentity) {
|
||||
return contentIdentity.ToString().GetHashCode();
|
||||
return contentIdentity._dictionary.OrderBy(kvp => kvp.Key).ToString().GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -33,6 +33,8 @@ namespace Orchard.ContentManagement {
|
||||
private readonly Lazy<IContentDisplay> _contentDisplay;
|
||||
private readonly Lazy<ISessionLocator> _sessionLocator;
|
||||
private readonly Lazy<IEnumerable<IContentHandler>> _handlers;
|
||||
private readonly Lazy<IEnumerable<IIdentityResolverSelector>> _identityResolverSelectors;
|
||||
|
||||
private const string Published = "Published";
|
||||
private const string Draft = "Draft";
|
||||
|
||||
@@ -46,7 +48,8 @@ namespace Orchard.ContentManagement {
|
||||
Func<IContentManagerSession> contentManagerSession,
|
||||
Lazy<IContentDisplay> contentDisplay,
|
||||
Lazy<ISessionLocator> sessionLocator,
|
||||
Lazy<IEnumerable<IContentHandler>> handlers) {
|
||||
Lazy<IEnumerable<IContentHandler>> handlers,
|
||||
Lazy<IEnumerable<IIdentityResolverSelector>> identityResolverSelectors) {
|
||||
_context = context;
|
||||
_contentTypeRepository = contentTypeRepository;
|
||||
_contentItemRepository = contentItemRepository;
|
||||
@@ -54,6 +57,7 @@ namespace Orchard.ContentManagement {
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
_cacheManager = cacheManager;
|
||||
_contentManagerSession = contentManagerSession;
|
||||
_identityResolverSelectors = identityResolverSelectors;
|
||||
_handlers = handlers;
|
||||
_contentDisplay = contentDisplay;
|
||||
_sessionLocator = sessionLocator;
|
||||
@@ -514,18 +518,42 @@ namespace Orchard.ContentManagement {
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasResolverForIdentity(ContentIdentity contentIdentity) {
|
||||
var context = new RegisterIdentityResolverContext();
|
||||
Handlers.Invoke(handler => handler.RegisterIdentityResolver(context), Logger);
|
||||
return context.HasResolverForIdentity(contentIdentity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lookup for a content item based on a <see cref="ContentIdentity"/>. If multiple
|
||||
/// resolvers can give a result, the one with the highest priority is used. As soon as
|
||||
/// only one content item is returned from resolvers, it is returned as the result.
|
||||
/// </summary>
|
||||
/// <param name="contentIdentity">The <see cref="ContentIdentity"/> instance to lookup</param>
|
||||
/// <returns>The <see cref="ContentItem"/> instance represented by the identity object.</returns>
|
||||
public ContentItem ResolveIdentity(ContentIdentity contentIdentity) {
|
||||
var context = new RegisterIdentityResolverContext();
|
||||
Handlers.Invoke(handler => handler.RegisterIdentityResolver(context), Logger);
|
||||
return context.ResolveIdentity(contentIdentity);
|
||||
}
|
||||
var resolvers = _identityResolverSelectors.Value
|
||||
.Select(x => x.GetResolver(contentIdentity))
|
||||
.Where(x => x != null)
|
||||
.OrderByDescending(x => x.Priority);
|
||||
|
||||
if (!resolvers.Any())
|
||||
return null;
|
||||
|
||||
IEnumerable<ContentItem> contentItems = null;
|
||||
foreach (var resolver in resolvers) {
|
||||
var resolved = resolver.Resolve(contentIdentity).ToArray();
|
||||
|
||||
// first pass
|
||||
if (contentItems == null) {
|
||||
contentItems = resolved;
|
||||
}
|
||||
else { // subsquent passes means we need to intersect
|
||||
contentItems = contentItems.Intersect(resolved).ToArray();
|
||||
}
|
||||
|
||||
if (contentItems.Count() == 1) {
|
||||
return contentItems.First();
|
||||
}
|
||||
}
|
||||
|
||||
return contentItems.FirstOrDefault();
|
||||
}
|
||||
|
||||
public ContentItemMetadata GetItemMetadata(IContent content) {
|
||||
var context = new GetContentItemMetadataContext {
|
||||
ContentItem = content.ContentItem,
|
||||
@@ -605,7 +633,7 @@ namespace Orchard.ContentManagement {
|
||||
var identity = elementId.Value;
|
||||
var status = element.Attribute("Status");
|
||||
|
||||
var item = importContentSession.Get(identity, VersionOptions.DraftRequired, XmlConvert.DecodeName(element.Name.LocalName));
|
||||
var item = importContentSession.Get(identity, VersionOptions.Latest, XmlConvert.DecodeName(element.Name.LocalName));
|
||||
if (item == null) {
|
||||
item = New(XmlConvert.DecodeName(element.Name.LocalName));
|
||||
if (status != null && status.Value == "Draft") {
|
||||
|
@@ -327,10 +327,6 @@ namespace Orchard.ContentManagement.Handlers {
|
||||
Exported(context);
|
||||
}
|
||||
|
||||
void IContentHandler.RegisterIdentityResolver(RegisterIdentityResolverContext context) {
|
||||
RegisterIdentityResolver(context);
|
||||
}
|
||||
|
||||
void IContentHandler.GetContentItemMetadata(GetContentItemMetadataContext context) {
|
||||
foreach (var filter in Filters.OfType<IContentTemplateFilter>())
|
||||
filter.GetContentItemMetadata(context);
|
||||
@@ -386,7 +382,6 @@ namespace Orchard.ContentManagement.Handlers {
|
||||
protected virtual void Exporting(ExportContentContext context) { }
|
||||
protected virtual void Exported(ExportContentContext context) { }
|
||||
|
||||
protected virtual void RegisterIdentityResolver(RegisterIdentityResolverContext context) { }
|
||||
protected virtual void GetItemMetadata(GetContentItemMetadataContext context) { }
|
||||
protected virtual void BuildDisplayShape(BuildDisplayContext context) { }
|
||||
protected virtual void BuildEditorShape(BuildEditorContext context) { }
|
||||
|
@@ -24,7 +24,6 @@
|
||||
public virtual void Exporting(ExportContentContext context) {}
|
||||
public virtual void Exported(ExportContentContext context) {}
|
||||
|
||||
public virtual void RegisterIdentityResolver(RegisterIdentityResolverContext context) { }
|
||||
public virtual void GetContentItemMetadata(GetContentItemMetadataContext context) {}
|
||||
public virtual void BuildDisplay(BuildDisplayContext context) {}
|
||||
public virtual void BuildEditor(BuildEditorContext context) {}
|
||||
|
@@ -24,7 +24,6 @@
|
||||
void Exporting(ExportContentContext context);
|
||||
void Exported(ExportContentContext context);
|
||||
|
||||
void RegisterIdentityResolver(RegisterIdentityResolverContext context);
|
||||
void GetContentItemMetadata(GetContentItemMetadataContext context);
|
||||
void BuildDisplay(BuildDisplayContext context);
|
||||
void BuildEditor(BuildEditorContext context);
|
||||
|
@@ -1,28 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Orchard.ContentManagement.Handlers {
|
||||
public class RegisterIdentityResolverContext {
|
||||
private readonly IList<Tuple<Func<ContentIdentity, bool>, Func<ContentIdentity, ContentItem>>> _resolvers;
|
||||
|
||||
public RegisterIdentityResolverContext() {
|
||||
_resolvers = new List<Tuple<Func<ContentIdentity, bool>, Func<ContentIdentity, ContentItem>>>();
|
||||
}
|
||||
|
||||
public void Register(Func<ContentIdentity, bool> isResolverForIdentity, Func<ContentIdentity, ContentItem> resolveIdentity) {
|
||||
_resolvers.Add(new Tuple<Func<ContentIdentity, bool>, Func<ContentIdentity, ContentItem>>(
|
||||
isResolverForIdentity, resolveIdentity));
|
||||
}
|
||||
|
||||
public bool HasResolverForIdentity(ContentIdentity identity) {
|
||||
return _resolvers.Any(r => r.Item1(identity));
|
||||
}
|
||||
|
||||
public ContentItem ResolveIdentity(ContentIdentity identity) {
|
||||
return _resolvers.Where(r => r.Item1(identity))
|
||||
.Select(r => r.Item2(identity))
|
||||
.FirstOrDefault(r => r != null);
|
||||
}
|
||||
}
|
||||
}
|
@@ -89,7 +89,6 @@ namespace Orchard.ContentManagement {
|
||||
GroupInfo GetEditorGroupInfo(IContent contentItem, string groupInfoId);
|
||||
GroupInfo GetDisplayGroupInfo(IContent contentItem, string groupInfoId);
|
||||
|
||||
bool HasResolverForIdentity(ContentIdentity contentIdentity);
|
||||
ContentItem ResolveIdentity(ContentIdentity contentIdentity);
|
||||
|
||||
/// <summary>
|
||||
|
13
src/Orchard/ContentManagement/IIdentityResolverSelector.cs
Normal file
13
src/Orchard/ContentManagement/IIdentityResolverSelector.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Orchard.ContentManagement {
|
||||
public class IdentityResolverSelectorResult {
|
||||
public int Priority { get; set; }
|
||||
public Func<ContentIdentity, IEnumerable<ContentItem>> Resolve { get; set; }
|
||||
}
|
||||
|
||||
public interface IIdentityResolverSelector : IDependency {
|
||||
IdentityResolverSelectorResult GetResolver(ContentIdentity contentIdentity);
|
||||
}
|
||||
}
|
@@ -20,11 +20,6 @@ namespace Orchard.ContentManagement {
|
||||
private int _batchSize = int.MaxValue;
|
||||
private int _currentIndex;
|
||||
|
||||
//for identity prefetch
|
||||
private const int BulkPage = 128;
|
||||
private bool _firstRequest = true;
|
||||
private bool _allIdentitiesPrefetched = false;
|
||||
|
||||
public ImportContentSession(IContentManager contentManager) {
|
||||
_identityComparer = new ContentIdentity.ContentIdentityEqualityComparer();
|
||||
_contentManager = contentManager;
|
||||
@@ -86,15 +81,6 @@ namespace Orchard.ContentManagement {
|
||||
public ContentItem Get(string id, VersionOptions versionOptions, string contentTypeHint = null) {
|
||||
var contentIdentity = new ContentIdentity(id);
|
||||
|
||||
if (_firstRequest) {
|
||||
_firstRequest = false;
|
||||
//If we know we have identities without a resolver
|
||||
//just load all up-front
|
||||
if (HasIdentitiesSetWithoutResolver()) {
|
||||
PrefetchAllIdentities(true);
|
||||
}
|
||||
}
|
||||
|
||||
// lookup in local cache
|
||||
if (_identities.ContainsKey(contentIdentity)) {
|
||||
if (_draftVersionRecordIds.ContainsKey(_identities[contentIdentity])) {
|
||||
@@ -111,32 +97,23 @@ namespace Orchard.ContentManagement {
|
||||
}
|
||||
}
|
||||
|
||||
if (!_allIdentitiesPrefetched) {
|
||||
ContentItem existingItem = null;
|
||||
ContentItem existingItem = _contentManager.ResolveIdentity(contentIdentity);
|
||||
|
||||
//try retrieve the item using handlers to resolve, otherwise fall back to full scan
|
||||
if (_contentManager.HasResolverForIdentity(contentIdentity)) {
|
||||
existingItem = _contentManager.ResolveIdentity(contentIdentity);
|
||||
//ensure we have the correct version
|
||||
if (existingItem != null) {
|
||||
existingItem = _contentManager.Get(existingItem.Id, versionOptions);
|
||||
}
|
||||
|
||||
//ensure we have the correct version
|
||||
if (existingItem != null)
|
||||
existingItem = _contentManager.Get(existingItem.Id, versionOptions);
|
||||
}
|
||||
else {
|
||||
//may be a contentidentity without a resolver and all identities have not
|
||||
//been prefetched yet e.g. is a dependency without resolver.
|
||||
PrefetchAllIdentities(false);
|
||||
if (_identities.ContainsKey(contentIdentity))
|
||||
existingItem = _contentManager.Get(_identities[contentIdentity], versionOptions);
|
||||
}
|
||||
if (existingItem == null && _identities.ContainsKey(contentIdentity)) {
|
||||
existingItem = _contentManager.Get(_identities[contentIdentity], versionOptions);
|
||||
}
|
||||
|
||||
if (existingItem != null) {
|
||||
_identities[contentIdentity] = existingItem.Id;
|
||||
if (versionOptions.IsDraftRequired) {
|
||||
_draftVersionRecordIds[existingItem.Id] = existingItem.VersionRecord.Id;
|
||||
}
|
||||
return existingItem;
|
||||
if (existingItem != null) {
|
||||
_identities[contentIdentity] = existingItem.Id;
|
||||
if (versionOptions.IsDraftRequired) {
|
||||
_draftVersionRecordIds[existingItem.Id] = existingItem.VersionRecord.Id;
|
||||
}
|
||||
return existingItem;
|
||||
}
|
||||
|
||||
//create item if not found and draft was requested, or it is found later in the import queue
|
||||
@@ -166,37 +143,5 @@ namespace Orchard.ContentManagement {
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool HasIdentitiesSetWithoutResolver() {
|
||||
return _allIdentitiesForImport.Any(id => !_contentManager.HasResolverForIdentity(id));
|
||||
}
|
||||
|
||||
private void PrefetchAllIdentities(bool clearContentManager) {
|
||||
if (_allIdentitiesPrefetched)
|
||||
return;
|
||||
|
||||
IEnumerable<ContentItem> block;
|
||||
int lastIndex = 0;
|
||||
|
||||
while ((block = _contentManager.HqlQuery()
|
||||
.ForVersion(VersionOptions.Latest)
|
||||
.OrderBy(x => x.ContentItemVersion(), x => x.Asc("Id"))
|
||||
.Slice(lastIndex, BulkPage)).Any()) {
|
||||
foreach (var item in block) {
|
||||
lastIndex++;
|
||||
|
||||
var identity = _contentManager.GetItemMetadata(item).Identity;
|
||||
|
||||
// store mapping for later
|
||||
_identities[identity] = item.Id;
|
||||
}
|
||||
|
||||
//Clearing the ContentManger after import has started can cause errors
|
||||
if (clearContentManager) {
|
||||
_contentManager.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
_allIdentitiesPrefetched = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -54,7 +54,7 @@ namespace Orchard.Localization.Services {
|
||||
.Where(x => x != null)
|
||||
.OrderByDescending(x => x.Priority);
|
||||
|
||||
if ( requestCulture.Count() < 1 )
|
||||
if ( !requestCulture.Any() )
|
||||
return String.Empty;
|
||||
|
||||
foreach (var culture in requestCulture) {
|
||||
|
@@ -153,7 +153,6 @@
|
||||
<Compile Include="ContentManagement\Aspects\ILocalizableAspect.cs" />
|
||||
<Compile Include="ContentManagement\ContentIdentity.cs" />
|
||||
<Compile Include="ContentManagement\DefaultHqlQuery.cs" />
|
||||
<Compile Include="ContentManagement\Handlers\RegisterIdentityResolverContext.cs" />
|
||||
<Compile Include="ContentManagement\Handlers\UpdateContentContext.cs" />
|
||||
<Compile Include="ContentManagement\IHqlExpression.cs" />
|
||||
<Compile Include="ContentManagement\IHqlQuery.cs" />
|
||||
@@ -166,6 +165,7 @@
|
||||
<Compile Include="ContentManagement\Handlers\BuildShapeContext.cs" />
|
||||
<Compile Include="ContentManagement\Handlers\ExportContentContext.cs" />
|
||||
<Compile Include="ContentManagement\Handlers\ImportContentContext.cs" />
|
||||
<Compile Include="ContentManagement\IIdentityResolverSelector.cs" />
|
||||
<Compile Include="ContentManagement\ImportContentSession.cs" />
|
||||
<Compile Include="ContentManagement\MetaData\Services\ISettingsFormatter.cs" />
|
||||
<Compile Include="ContentManagement\QueryHints.cs" />
|
||||
|
Reference in New Issue
Block a user