Merge branch dev-v8 into temp-u4-8497
This commit is contained in:
@@ -267,15 +267,13 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
|
||||
private IPublishedContent ConvertToDocument(XmlNode xmlNode, bool isPreviewing, ICacheProvider cacheProvider)
|
||||
{
|
||||
return xmlNode == null
|
||||
? null
|
||||
: (new XmlPublishedContent(xmlNode, isPreviewing, cacheProvider, _contentTypeCache)).CreateModel();
|
||||
return xmlNode == null ? null : XmlPublishedContent.Get(xmlNode, isPreviewing); // fixme cacheProvider, _contentTypeCache
|
||||
}
|
||||
|
||||
private IEnumerable<IPublishedContent> ConvertToDocuments(XmlNodeList xmlNodes, bool isPreviewing, ICacheProvider cacheProvider)
|
||||
{
|
||||
return xmlNodes.Cast<XmlNode>()
|
||||
.Select(xmlNode => (new XmlPublishedContent(xmlNode, isPreviewing, cacheProvider, _contentTypeCache)).CreateModel());
|
||||
.Select(xmlNode => XmlPublishedContent.Get(xmlNode, isPreviewing)); // fixme cacheProvider, _contentTypeCache
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
internal class PublishedMediaCache : PublishedCacheBase, IPublishedMediaCache
|
||||
{
|
||||
private readonly IMediaService _mediaService;
|
||||
private readonly IUserService _userService;
|
||||
|
||||
// by default these are null unless specified by the ctor dedicated to tests
|
||||
// when they are null the cache derives them from the ExamineManager, see
|
||||
@@ -45,12 +46,15 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
// must be specified by the ctor
|
||||
private readonly ICacheProvider _cacheProvider;
|
||||
|
||||
public PublishedMediaCache(XmlStore xmlStore, IMediaService mediaService, ICacheProvider cacheProvider, PublishedContentTypeCache contentTypeCache)
|
||||
public PublishedMediaCache(XmlStore xmlStore, IMediaService mediaService, IUserService userService, ICacheProvider cacheProvider, PublishedContentTypeCache contentTypeCache)
|
||||
: base(false)
|
||||
{
|
||||
if (mediaService == null) throw new ArgumentNullException(nameof(mediaService));
|
||||
_mediaService = mediaService;
|
||||
_cacheProvider = cacheProvider;
|
||||
if (userService == null) throw new ArgumentNullException(nameof(userService));
|
||||
_mediaService = mediaService;
|
||||
_userService = userService;
|
||||
|
||||
_cacheProvider = cacheProvider;
|
||||
_xmlStore = xmlStore;
|
||||
_contentTypeCache = contentTypeCache;
|
||||
}
|
||||
@@ -63,15 +67,17 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
/// <param name="indexProvider"></param>
|
||||
/// <param name="cacheProvider"></param>
|
||||
/// <param name="contentTypeCache"></param>
|
||||
internal PublishedMediaCache(IMediaService mediaService, ILuceneSearcher searchProvider, BaseIndexProvider indexProvider, ICacheProvider cacheProvider, PublishedContentTypeCache contentTypeCache)
|
||||
internal PublishedMediaCache(IMediaService mediaService, IUserService userService, ILuceneSearcher searchProvider, BaseIndexProvider indexProvider, ICacheProvider cacheProvider, PublishedContentTypeCache contentTypeCache)
|
||||
: base(false)
|
||||
{
|
||||
if (mediaService == null) throw new ArgumentNullException(nameof(mediaService));
|
||||
if (searchProvider == null) throw new ArgumentNullException(nameof(searchProvider));
|
||||
if (userService == null) throw new ArgumentNullException(nameof(userService));
|
||||
if (searchProvider == null) throw new ArgumentNullException(nameof(searchProvider));
|
||||
if (indexProvider == null) throw new ArgumentNullException(nameof(indexProvider));
|
||||
|
||||
_mediaService = mediaService;
|
||||
_searchProvider = searchProvider;
|
||||
_userService = userService;
|
||||
_searchProvider = searchProvider;
|
||||
_indexProvider = indexProvider;
|
||||
_cacheProvider = cacheProvider;
|
||||
_contentTypeCache = contentTypeCache;
|
||||
@@ -293,10 +299,12 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
"Could not retrieve media {0} from Examine index, reverting to looking up media via legacy library.GetMedia method",
|
||||
() => id);
|
||||
|
||||
var media = library.GetMedia(id, false);
|
||||
//var media = library.GetMedia(id, false);
|
||||
//return ConvertFromXPathNodeIterator(media, id);
|
||||
|
||||
return ConvertFromXPathNodeIterator(media, id);
|
||||
}
|
||||
var media = ApplicationContext.Current.Services.MediaService.GetById(id);
|
||||
return media == null ? null : ConvertFromIMedia(media);
|
||||
}
|
||||
|
||||
internal CacheValues ConvertFromXPathNodeIterator(XPathNodeIterator media, int id)
|
||||
{
|
||||
@@ -381,14 +389,49 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We will need to first check if the document was loaded by Examine, if so we'll need to check if this property exists
|
||||
/// in the results, if it does not, then we'll have to revert to looking up in the db.
|
||||
/// </summary>
|
||||
/// <param name="dd"> </param>
|
||||
/// <param name="alias"></param>
|
||||
/// <returns></returns>
|
||||
private IPublishedProperty GetProperty(DictionaryPublishedContent dd, string alias)
|
||||
internal CacheValues ConvertFromIMedia(IMedia media)
|
||||
{
|
||||
var values = new Dictionary<string, string>();
|
||||
|
||||
var creator = _userService.GetProfileById(media.CreatorId);
|
||||
var creatorName = creator == null ? "" : creator.Name;
|
||||
|
||||
values["id"] = media.Id.ToString();
|
||||
values["key"] = media.Key.ToString();
|
||||
values["parentID"] = media.ParentId.ToString();
|
||||
values["level"] = media.Level.ToString();
|
||||
values["creatorID"] = media.CreatorId.ToString();
|
||||
values["creatorName"] = creatorName;
|
||||
values["writerID"] = media.CreatorId.ToString();
|
||||
values["writerName"] = creatorName;
|
||||
values["template"] = "0";
|
||||
values["urlName"] = "";
|
||||
values["sortOrder"] = media.SortOrder.ToString();
|
||||
values["createDate"] = media.CreateDate.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
values["updateDate"] = media.UpdateDate.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
values["nodeName"] = media.Name;
|
||||
values["path"] = media.Path;
|
||||
values["nodeType"] = media.ContentType.Id.ToString();
|
||||
values["nodeTypeAlias"] = media.ContentType.Alias;
|
||||
|
||||
// add the user props
|
||||
foreach (var prop in media.Properties)
|
||||
values[prop.Alias] = prop.Value == null ? null : prop.Value.ToString();
|
||||
|
||||
return new CacheValues
|
||||
{
|
||||
Values = values
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We will need to first check if the document was loaded by Examine, if so we'll need to check if this property exists
|
||||
/// in the results, if it does not, then we'll have to revert to looking up in the db.
|
||||
/// </summary>
|
||||
/// <param name="dd"> </param>
|
||||
/// <param name="alias"></param>
|
||||
/// <returns></returns>
|
||||
private IPublishedProperty GetProperty(DictionaryPublishedContent dd, string alias)
|
||||
{
|
||||
//lets check if the alias does not exist on the document.
|
||||
//NOTE: Examine will not index empty values and we do not output empty XML Elements to the cache - either of these situations
|
||||
@@ -605,7 +648,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
_keysAdded.Add(alias);
|
||||
string value;
|
||||
const bool isPreviewing = false; // false :: never preview a media
|
||||
var property = valueDictionary.TryGetValue(alias, out value) == false
|
||||
var property = valueDictionary.TryGetValue(alias, out value) == false || value == null
|
||||
? new XmlPublishedProperty(propertyType, isPreviewing)
|
||||
: new XmlPublishedProperty(propertyType, isPreviewing, value);
|
||||
_properties.Add(property);
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using System.Xml.XPath;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Models;
|
||||
@@ -29,52 +27,30 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
/// <param name="isPreviewing">A value indicating whether the published content is being previewed.</param>
|
||||
/// <param name="cacheProvider">A cache provider.</param>
|
||||
/// <param name="contentTypeCache">A content type cache.</param>
|
||||
public XmlPublishedContent(XmlNode xmlNode, bool isPreviewing, ICacheProvider cacheProvider, PublishedContentTypeCache contentTypeCache)
|
||||
private XmlPublishedContent(XmlNode xmlNode, bool isPreviewing, ICacheProvider cacheProvider, PublishedContentTypeCache contentTypeCache)
|
||||
{
|
||||
_xmlNode = xmlNode;
|
||||
_isPreviewing = isPreviewing;
|
||||
_cacheProvider = cacheProvider;
|
||||
_contentTypeCache = contentTypeCache;
|
||||
InitializeStructure();
|
||||
Initialize();
|
||||
InitializeChildren();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <c>XmlPublishedContent</c> class with an Xml node,
|
||||
/// and a value indicating whether to lazy-initialize the instance.
|
||||
/// </summary>
|
||||
/// <param name="xmlNode">The Xml node.</param>
|
||||
/// <param name="isPreviewing">A value indicating whether the published content is being previewed.</param>
|
||||
/// <param name="cacheProvider">A cache provider.</param>
|
||||
/// <param name="contentTypeCache">A content type cache.</param>
|
||||
/// <param name="lazyInitialize">A value indicating whether to lazy-initialize the instance.</param>
|
||||
/// <remarks>Lazy-initializationg is NOT thread-safe.</remarks>
|
||||
internal XmlPublishedContent(XmlNode xmlNode, bool isPreviewing, ICacheProvider cacheProvider, PublishedContentTypeCache contentTypeCache, bool lazyInitialize)
|
||||
{
|
||||
_xmlNode = xmlNode;
|
||||
_isPreviewing = isPreviewing;
|
||||
_cacheProvider = cacheProvider;
|
||||
_contentTypeCache = contentTypeCache;
|
||||
InitializeStructure();
|
||||
if (lazyInitialize == false)
|
||||
{
|
||||
Initialize();
|
||||
InitializeChildren();
|
||||
}
|
||||
}
|
||||
|
||||
private readonly XmlNode _xmlNode;
|
||||
private readonly bool _isPreviewing;
|
||||
private readonly ICacheProvider _cacheProvider;
|
||||
private readonly PublishedContentTypeCache _contentTypeCache;
|
||||
|
||||
private bool _initialized;
|
||||
|
||||
private bool _nodeInitialized;
|
||||
private bool _parentInitialized;
|
||||
private bool _childrenInitialized;
|
||||
|
||||
private readonly ICollection<IPublishedContent> _children = new Collection<IPublishedContent>();
|
||||
private IEnumerable<IPublishedContent> _children = Enumerable.Empty<IPublishedContent>();
|
||||
private IPublishedContent _parent;
|
||||
|
||||
private int _id;
|
||||
private PublishedContentType _contentType;
|
||||
private Dictionary<string, IPublishedProperty> _properties;
|
||||
|
||||
private int _id;
|
||||
private Guid _key;
|
||||
private int _template;
|
||||
private string _name;
|
||||
@@ -89,28 +65,25 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
private DateTime _createDate;
|
||||
private DateTime _updateDate;
|
||||
private Guid _version;
|
||||
private IPublishedProperty[] _properties;
|
||||
private int _sortOrder;
|
||||
private int _level;
|
||||
private bool _isDraft;
|
||||
private readonly bool _isPreviewing;
|
||||
private PublishedContentType _contentType;
|
||||
|
||||
public override IEnumerable<IPublishedContent> Children
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_childrenInitialized == false)
|
||||
InitializeChildren();
|
||||
return _children.OrderBy(x => x.SortOrder);
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
if (_childrenInitialized == false) InitializeChildren();
|
||||
return _children;
|
||||
}
|
||||
}
|
||||
|
||||
public override IPublishedProperty GetProperty(string alias)
|
||||
{
|
||||
return Properties.FirstOrDefault(x => x.PropertyTypeAlias.InvariantEquals(alias));
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
IPublishedProperty property;
|
||||
return _properties.TryGetValue(alias, out property) ? property : null;
|
||||
}
|
||||
|
||||
// override to implement cache
|
||||
@@ -120,24 +93,21 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
if (recurse == false) return GetProperty(alias);
|
||||
|
||||
var key = string.Format("XmlPublishedCache.PublishedContentCache:RecursiveProperty-{0}-{1}", Id, alias.ToLowerInvariant());
|
||||
var key = $"XmlPublishedCache.PublishedContentCache:RecursiveProperty-{Id}-{alias.ToLowerInvariant()}";
|
||||
var cacheProvider = _cacheProvider;
|
||||
return cacheProvider.GetCacheItem<IPublishedProperty>(key, () => base.GetProperty(alias, true));
|
||||
|
||||
// note: cleared by PublishedContentCache.Resync - any change here must be applied there
|
||||
}
|
||||
|
||||
public override PublishedItemType ItemType
|
||||
{
|
||||
get { return PublishedItemType.Content; }
|
||||
}
|
||||
public override PublishedItemType ItemType => PublishedItemType.Content;
|
||||
|
||||
public override IPublishedContent Parent
|
||||
public override IPublishedContent Parent
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
if (_parentInitialized == false) InitializeParent();
|
||||
return _parent;
|
||||
}
|
||||
}
|
||||
@@ -146,8 +116,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _id;
|
||||
}
|
||||
}
|
||||
@@ -156,8 +125,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _key;
|
||||
}
|
||||
}
|
||||
@@ -166,8 +134,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _template;
|
||||
}
|
||||
}
|
||||
@@ -176,8 +143,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _sortOrder;
|
||||
}
|
||||
}
|
||||
@@ -186,8 +152,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _name;
|
||||
}
|
||||
}
|
||||
@@ -196,8 +161,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _docTypeAlias;
|
||||
}
|
||||
}
|
||||
@@ -206,8 +170,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _docTypeId;
|
||||
}
|
||||
}
|
||||
@@ -216,8 +179,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _writerName;
|
||||
}
|
||||
}
|
||||
@@ -226,8 +188,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _creatorName;
|
||||
}
|
||||
}
|
||||
@@ -236,8 +197,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _writerId;
|
||||
}
|
||||
}
|
||||
@@ -246,8 +206,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _creatorId;
|
||||
}
|
||||
}
|
||||
@@ -256,8 +215,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _path;
|
||||
}
|
||||
}
|
||||
@@ -266,8 +224,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _createDate;
|
||||
}
|
||||
}
|
||||
@@ -276,8 +233,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _updateDate;
|
||||
}
|
||||
}
|
||||
@@ -286,8 +242,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _version;
|
||||
}
|
||||
}
|
||||
@@ -296,8 +251,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _urlName;
|
||||
}
|
||||
}
|
||||
@@ -306,8 +260,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _level;
|
||||
}
|
||||
}
|
||||
@@ -316,8 +269,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _isDraft;
|
||||
}
|
||||
}
|
||||
@@ -326,9 +278,8 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
return _properties;
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _properties.Values;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,24 +287,24 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_initialized == false)
|
||||
Initialize();
|
||||
if (_nodeInitialized == false) InitializeNode();
|
||||
return _contentType;
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeStructure()
|
||||
{
|
||||
// load parent if it exists and is a node
|
||||
|
||||
var parent = _xmlNode == null ? null : _xmlNode.ParentNode;
|
||||
private void InitializeParent()
|
||||
{
|
||||
var parent = _xmlNode?.ParentNode;
|
||||
if (parent == null) return;
|
||||
|
||||
if (parent.Attributes != null && parent.Attributes.GetNamedItem("isDoc") != null)
|
||||
_parent = (new XmlPublishedContent(parent, _isPreviewing, _cacheProvider, _contentTypeCache, true)).CreateModel();
|
||||
if (parent.Attributes?.GetNamedItem("isDoc") != null)
|
||||
_parent = Get(parent, _isPreviewing, _cacheProvider, _contentTypeCache);
|
||||
|
||||
// warn: this is not thread-safe...
|
||||
_parentInitialized = true;
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
private void InitializeNode()
|
||||
{
|
||||
if (_xmlNode == null) return;
|
||||
|
||||
@@ -382,7 +333,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
_creatorName = _writerName;
|
||||
}
|
||||
|
||||
//Added the actual userID, as a user cannot be looked up via full name only...
|
||||
//Added the actual userID, as a user cannot be looked up via full name only...
|
||||
if (_xmlNode.Attributes.GetNamedItem("creatorID") != null)
|
||||
_creatorId = int.Parse(_xmlNode.Attributes.GetNamedItem("creatorID").Value);
|
||||
if (_xmlNode.Attributes.GetNamedItem("writerID") != null)
|
||||
@@ -407,7 +358,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
}
|
||||
|
||||
// load data
|
||||
var dataXPath = "* [not(@isDoc)]";
|
||||
const string dataXPath = "* [not(@isDoc)]";
|
||||
var nodes = _xmlNode.SelectNodes(dataXPath);
|
||||
|
||||
_contentType = _contentTypeCache.Get(PublishedItemType.Content, _docTypeAlias);
|
||||
@@ -420,16 +371,19 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
propertyNodes[alias.ToLowerInvariant()] = n;
|
||||
}
|
||||
|
||||
_properties = _contentType.PropertyTypes.Select(p =>
|
||||
{
|
||||
XmlNode n;
|
||||
return propertyNodes.TryGetValue(p.PropertyTypeAlias.ToLowerInvariant(), out n)
|
||||
? new XmlPublishedProperty(p, _isPreviewing, n)
|
||||
: new XmlPublishedProperty(p, _isPreviewing);
|
||||
}).Cast<IPublishedProperty>().ToArray();
|
||||
_properties = _contentType.PropertyTypes.Select(p =>
|
||||
{
|
||||
XmlNode n;
|
||||
return propertyNodes.TryGetValue(p.PropertyTypeAlias.ToLowerInvariant(), out n)
|
||||
? new XmlPublishedProperty(p, _isPreviewing, n)
|
||||
: new XmlPublishedProperty(p, _isPreviewing);
|
||||
}).Cast<IPublishedProperty>().ToDictionary(
|
||||
x => x.PropertyTypeAlias,
|
||||
x => x,
|
||||
StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
// warn: this is not thread-safe...
|
||||
_initialized = true;
|
||||
_nodeInitialized = true;
|
||||
}
|
||||
|
||||
private void InitializeChildren()
|
||||
@@ -437,17 +391,49 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
if (_xmlNode == null) return;
|
||||
|
||||
// load children
|
||||
var childXPath = "* [@isDoc]";
|
||||
const string childXPath = "* [@isDoc]";
|
||||
var nav = _xmlNode.CreateNavigator();
|
||||
var expr = nav.Compile(childXPath);
|
||||
expr.AddSort("@sortOrder", XmlSortOrder.Ascending, XmlCaseOrder.None, "", XmlDataType.Number);
|
||||
//expr.AddSort("@sortOrder", XmlSortOrder.Ascending, XmlCaseOrder.None, "", XmlDataType.Number);
|
||||
var iterator = nav.Select(expr);
|
||||
while (iterator.MoveNext())
|
||||
_children.Add(
|
||||
(new XmlPublishedContent(((IHasXmlNode)iterator.Current).GetNode(), _isPreviewing, _cacheProvider, _contentTypeCache, true)).CreateModel());
|
||||
|
||||
|
||||
_children = iterator.Cast<XPathNavigator>()
|
||||
.Select(n => Get(((IHasXmlNode) n).GetNode(), _isPreviewing, _cacheProvider, _contentTypeCache))
|
||||
.OrderBy(x => x.SortOrder)
|
||||
.ToList();
|
||||
|
||||
// warn: this is not thread-safe
|
||||
_childrenInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an IPublishedContent corresponding to an Xml cache node.
|
||||
/// </summary>
|
||||
/// <param name="node">The Xml node.</param>
|
||||
/// <param name="isPreviewing">A value indicating whether we are previewing or not.</param>
|
||||
/// <param name="cacheProvider">A cache provider.</param>
|
||||
/// <param name="contentTypeCache">A content type cache.</param>
|
||||
/// <returns>The IPublishedContent corresponding to the Xml cache node.</returns>
|
||||
/// <remarks>Maintains a per-request cache of IPublishedContent items in order to make
|
||||
/// sure that we create only one instance of each for the duration of a request. The
|
||||
/// returned IPublishedContent is a model, if models are enabled.</remarks>
|
||||
public static IPublishedContent Get(XmlNode node, bool isPreviewing, ICacheProvider cacheProvider, PublishedContentTypeCache contentTypeCache)
|
||||
{
|
||||
// only 1 per request
|
||||
|
||||
var attrs = node.Attributes;
|
||||
var id = attrs?.GetNamedItem("id").Value;
|
||||
if (id.IsNullOrWhiteSpace()) throw new InvalidOperationException("Node has no ID attribute.");
|
||||
var cache = ApplicationContext.Current.ApplicationCache.RequestCache;
|
||||
var key = CacheKeyPrefix + id; // dont bother with preview, wont change during request in v7
|
||||
return (IPublishedContent) cache.GetCacheItem(key, () => (new XmlPublishedContent(node, isPreviewing, cacheProvider, contentTypeCache)).CreateModel());
|
||||
}
|
||||
|
||||
public static void ClearRequest()
|
||||
{
|
||||
ApplicationContext.Current.ApplicationCache.RequestCache.ClearCacheByKeySearch(CacheKeyPrefix);
|
||||
}
|
||||
|
||||
private const string CacheKeyPrefix = "CONTENTCACHE_XMLPUBLISHEDCONTENT_";
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,8 @@ using System;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Xml;
|
||||
using Umbraco.Web.Models;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
@@ -18,10 +16,15 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
internal class XmlPublishedProperty : PublishedPropertyBase
|
||||
{
|
||||
private readonly string _xmlValue; // the raw, xml node value
|
||||
private readonly Lazy<object> _sourceValue;
|
||||
private readonly Lazy<object> _objectValue;
|
||||
private readonly Lazy<object> _xpathValue;
|
||||
private readonly bool _isPreviewing;
|
||||
|
||||
// in v7 we're not using XPath value so don't allocate that Lazy.
|
||||
// as for the rest... we're single threaded here, keep it simple
|
||||
//private readonly Lazy<object> _sourceValue;
|
||||
//private readonly Lazy<object> _objectValue;
|
||||
//private readonly Lazy<object> _xpathValue;
|
||||
private object _objectValue;
|
||||
private bool _objectValueComputed;
|
||||
private readonly bool _isPreviewing;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw value of the property.
|
||||
@@ -35,10 +38,26 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
get { return _xmlValue.Trim().Length > 0; }
|
||||
}
|
||||
|
||||
public override object Value { get { return _objectValue.Value; } }
|
||||
public override object XPathValue { get { return _xpathValue.Value; } }
|
||||
public override object Value
|
||||
{
|
||||
get
|
||||
{
|
||||
// NOT caching the source (intermediate) value since we'll never need it
|
||||
// everything in Xml cache in v7 is per-request anyways
|
||||
// also, properties should not be shared between requests and therefore
|
||||
// are single threaded, so the following code should be safe & fast
|
||||
|
||||
public XmlPublishedProperty(PublishedPropertyType propertyType, bool isPreviewing, XmlNode propertyXmlData)
|
||||
if (_objectValueComputed) return _objectValue;
|
||||
var sourceValue = PropertyType.ConvertDataToSource(_xmlValue, _isPreviewing);
|
||||
_objectValue = PropertyType.ConvertSourceToObject(sourceValue, _isPreviewing);
|
||||
_objectValueComputed = true;
|
||||
return _objectValue;
|
||||
}
|
||||
}
|
||||
|
||||
public override object XPathValue { get { throw new NotImplementedException(); } }
|
||||
|
||||
public XmlPublishedProperty(PublishedPropertyType propertyType, bool isPreviewing, XmlNode propertyXmlData)
|
||||
: this(propertyType, isPreviewing)
|
||||
{
|
||||
if (propertyXmlData == null)
|
||||
@@ -60,9 +79,9 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
_xmlValue = string.Empty;
|
||||
_isPreviewing = isPreviewing;
|
||||
|
||||
_sourceValue = new Lazy<object>(() => PropertyType.ConvertDataToSource(_xmlValue, _isPreviewing));
|
||||
_objectValue = new Lazy<object>(() => PropertyType.ConvertSourceToObject(_sourceValue.Value, _isPreviewing));
|
||||
_xpathValue = new Lazy<object>(() => PropertyType.ConvertSourceToXPath(_sourceValue.Value, _isPreviewing));
|
||||
//_sourceValue = new Lazy<object>(() => PropertyType.ConvertDataToSource(_xmlValue, _isPreviewing));
|
||||
//_objectValue = new Lazy<object>(() => PropertyType.ConvertSourceToObject(_sourceValue.Value, _isPreviewing));
|
||||
//_xpathValue = new Lazy<object>(() => PropertyType.ConvertSourceToXPath(_sourceValue.Value, _isPreviewing));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user