2016-05-27 14:26:28 +02:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Xml.XPath;
|
2016-05-30 19:54:36 +02:00
|
|
|
|
using Umbraco.Core.Cache;
|
2016-05-27 14:26:28 +02:00
|
|
|
|
using Umbraco.Core.Models.PublishedContent;
|
|
|
|
|
|
using Umbraco.Core.Xml;
|
|
|
|
|
|
using Umbraco.Core.Xml.XPath;
|
|
|
|
|
|
using Umbraco.Web.PublishedCache.NuCache.Navigable;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Umbraco.Web.PublishedCache.NuCache
|
|
|
|
|
|
{
|
2016-11-05 12:22:57 +01:00
|
|
|
|
internal class MediaCache : PublishedCacheBase, IPublishedMediaCache, INavigableData, IDisposable
|
2016-05-27 14:26:28 +02:00
|
|
|
|
{
|
2017-07-12 14:09:31 +02:00
|
|
|
|
private readonly ContentStore.Snapshot _snapshot;
|
2016-05-30 19:54:36 +02:00
|
|
|
|
private readonly ICacheProvider _facadeCache;
|
|
|
|
|
|
private readonly ICacheProvider _snapshotCache;
|
2016-05-27 14:26:28 +02:00
|
|
|
|
|
|
|
|
|
|
#region Constructors
|
|
|
|
|
|
|
2017-07-12 14:09:31 +02:00
|
|
|
|
public MediaCache(bool previewDefault, ContentStore.Snapshot snapshot, ICacheProvider facadeCache, ICacheProvider snapshotCache)
|
2016-05-27 14:26:28 +02:00
|
|
|
|
: base(previewDefault)
|
|
|
|
|
|
{
|
|
|
|
|
|
_snapshot = snapshot;
|
2016-05-30 19:54:36 +02:00
|
|
|
|
_facadeCache = facadeCache;
|
|
|
|
|
|
_snapshotCache = snapshotCache;
|
2016-05-27 14:26:28 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region Get, Has
|
|
|
|
|
|
|
|
|
|
|
|
public override IPublishedContent GetById(bool preview, int contentId)
|
|
|
|
|
|
{
|
|
|
|
|
|
var n = _snapshot.Get(contentId);
|
2016-05-30 19:54:36 +02:00
|
|
|
|
return n?.Published;
|
2016-05-27 14:26:28 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-11-03 10:31:44 +01:00
|
|
|
|
public override IPublishedContent GetById(bool preview, Guid contentId)
|
|
|
|
|
|
{
|
2016-11-05 12:22:57 +01:00
|
|
|
|
var n = _snapshot.Get(contentId);
|
|
|
|
|
|
return n?.Published;
|
2016-11-03 10:31:44 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-05-27 14:26:28 +02:00
|
|
|
|
public override bool HasById(bool preview, int contentId)
|
|
|
|
|
|
{
|
|
|
|
|
|
var n = _snapshot.Get(contentId);
|
|
|
|
|
|
return n != null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override IEnumerable<IPublishedContent> GetAtRoot(bool preview)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (FacadeService.CacheContentCacheRoots == false)
|
|
|
|
|
|
return GetAtRootNoCache(preview);
|
|
|
|
|
|
|
2016-05-30 19:54:36 +02:00
|
|
|
|
var cache = preview == false || FacadeService.FullCacheWhenPreviewing
|
|
|
|
|
|
? _snapshotCache
|
|
|
|
|
|
: _facadeCache;
|
2016-05-27 14:26:28 +02:00
|
|
|
|
|
|
|
|
|
|
if (cache == null)
|
|
|
|
|
|
return GetAtRootNoCache(preview);
|
|
|
|
|
|
|
|
|
|
|
|
// note: ToArray is important here, we want to cache the result, not the function!
|
|
|
|
|
|
return (IEnumerable<IPublishedContent>)cache.GetCacheItem(
|
|
|
|
|
|
CacheKeys.MediaCacheRoots(preview),
|
|
|
|
|
|
() => GetAtRootNoCache(preview).ToArray());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private IEnumerable<IPublishedContent> GetAtRootNoCache(bool preview)
|
|
|
|
|
|
{
|
|
|
|
|
|
var c = _snapshot.GetAtRoot();
|
|
|
|
|
|
|
|
|
|
|
|
// there's no .Draft for medias, only non-null .Published
|
|
|
|
|
|
// but we may want published as previewing, still
|
|
|
|
|
|
return c.Select(n => preview
|
|
|
|
|
|
? ContentCache.GetPublishedContentAsPreviewing(n.Published)
|
|
|
|
|
|
: n.Published);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override bool HasContent(bool preview)
|
|
|
|
|
|
{
|
|
|
|
|
|
return _snapshot.IsEmpty == false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region XPath
|
|
|
|
|
|
|
|
|
|
|
|
public override IPublishedContent GetSingleByXPath(bool preview, string xpath, XPathVariable[] vars)
|
|
|
|
|
|
{
|
|
|
|
|
|
var navigator = CreateNavigator(preview);
|
|
|
|
|
|
var iterator = navigator.Select(xpath, vars);
|
|
|
|
|
|
return GetSingleByXPath(iterator);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override IPublishedContent GetSingleByXPath(bool preview, XPathExpression xpath, XPathVariable[] vars)
|
|
|
|
|
|
{
|
|
|
|
|
|
var navigator = CreateNavigator(preview);
|
|
|
|
|
|
var iterator = navigator.Select(xpath, vars);
|
|
|
|
|
|
return GetSingleByXPath(iterator);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static IPublishedContent GetSingleByXPath(XPathNodeIterator iterator)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (iterator.MoveNext() == false) return null;
|
|
|
|
|
|
|
|
|
|
|
|
var xnav = iterator.Current as NavigableNavigator;
|
|
|
|
|
|
if (xnav == null) return null;
|
|
|
|
|
|
|
|
|
|
|
|
var xcontent = xnav.UnderlyingObject as NavigableContent;
|
|
|
|
|
|
return xcontent == null ? null : xcontent.InnerContent;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override IEnumerable<IPublishedContent> GetByXPath(bool preview, string xpath, XPathVariable[] vars)
|
|
|
|
|
|
{
|
|
|
|
|
|
var navigator = CreateNavigator(preview);
|
|
|
|
|
|
var iterator = navigator.Select(xpath, vars);
|
|
|
|
|
|
return GetByXPath(iterator);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override IEnumerable<IPublishedContent> GetByXPath(bool preview, XPathExpression xpath, XPathVariable[] vars)
|
|
|
|
|
|
{
|
|
|
|
|
|
var navigator = CreateNavigator(preview);
|
|
|
|
|
|
var iterator = navigator.Select(xpath, vars);
|
|
|
|
|
|
return GetByXPath(iterator);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static IEnumerable<IPublishedContent> GetByXPath(XPathNodeIterator iterator)
|
|
|
|
|
|
{
|
|
|
|
|
|
while (iterator.MoveNext())
|
|
|
|
|
|
{
|
|
|
|
|
|
var xnav = iterator.Current as NavigableNavigator;
|
|
|
|
|
|
if (xnav == null) continue;
|
|
|
|
|
|
|
|
|
|
|
|
var xcontent = xnav.UnderlyingObject as NavigableContent;
|
|
|
|
|
|
if (xcontent == null) continue;
|
|
|
|
|
|
|
|
|
|
|
|
yield return xcontent.InnerContent;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override XPathNavigator CreateNavigator(bool preview)
|
|
|
|
|
|
{
|
|
|
|
|
|
var source = new Source(this, preview);
|
|
|
|
|
|
var navigator = new NavigableNavigator(source);
|
|
|
|
|
|
return navigator;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override XPathNavigator CreateNodeNavigator(int id, bool preview)
|
|
|
|
|
|
{
|
|
|
|
|
|
var source = new Source(this, preview);
|
|
|
|
|
|
var navigator = new NavigableNavigator(source);
|
|
|
|
|
|
return navigator.CloneWithNewRoot(id, 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region Content types
|
|
|
|
|
|
|
|
|
|
|
|
public override PublishedContentType GetContentType(int id)
|
|
|
|
|
|
{
|
|
|
|
|
|
return _snapshot.GetContentType(id);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override PublishedContentType GetContentType(string alias)
|
|
|
|
|
|
{
|
|
|
|
|
|
return _snapshot.GetContentType(alias);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override IEnumerable<IPublishedContent> GetByContentType(PublishedContentType contentType)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new NotImplementedException();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region IDisposable
|
|
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
|
{
|
|
|
|
|
|
_snapshot.Dispose();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|