merge
This commit is contained in:
72
src/Umbraco.Web/Routing/DefaultRoutesCache.cs
Normal file
72
src/Umbraco.Web/Routing/DefaultRoutesCache.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Web.Routing
|
||||
{
|
||||
/// <summary>
|
||||
/// The default implementation of IRoutesCache
|
||||
/// </summary>
|
||||
internal class DefaultRoutesCache : IRoutesCache
|
||||
{
|
||||
private readonly object _lock = new object();
|
||||
private Dictionary<int, string> _routes;
|
||||
private Dictionary<string, int> _nodeIds;
|
||||
|
||||
public DefaultRoutesCache()
|
||||
{
|
||||
Clear();
|
||||
|
||||
// here we should register handlers to clear the cache when content changes
|
||||
// at the moment this is done by library, which clears everything when content changed
|
||||
//
|
||||
// but really, we should do some partial refreshes!
|
||||
// otherwise, we could even cache 404 errors...
|
||||
}
|
||||
|
||||
public void Store(int nodeId, string route)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_routes[nodeId] = route;
|
||||
_nodeIds[route] = nodeId;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetRoute(int nodeId)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _routes.ContainsKey(nodeId) ? _routes[nodeId] : null;
|
||||
}
|
||||
}
|
||||
|
||||
public int GetNodeId(string route)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _nodeIds.ContainsKey(route) ? _nodeIds[route] : 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearNode(int nodeId)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (_routes.ContainsKey(nodeId))
|
||||
{
|
||||
_nodeIds.Remove(_routes[nodeId]);
|
||||
_routes.Remove(nodeId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_routes = new Dictionary<int, string>();
|
||||
_nodeIds = new Dictionary<string, int>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ using System.Globalization;
|
||||
using System.Diagnostics;
|
||||
|
||||
// legacy
|
||||
using umbraco.BusinessLogic;
|
||||
using umbraco.cms.businesslogic.web;
|
||||
using umbraco.cms.businesslogic.template;
|
||||
using umbraco.cms.businesslogic.member;
|
||||
@@ -19,21 +20,28 @@ namespace Umbraco.Web.Routing
|
||||
{
|
||||
static readonly TraceSource Trace = new TraceSource("DocumentRequest");
|
||||
|
||||
public DocumentRequest(Uri uri, RoutingEnvironment lookups, UmbracoContext umbracoContext, NiceUrls niceUrls)
|
||||
public DocumentRequest(Uri uri, RoutingContext routingContext)
|
||||
{
|
||||
this.Uri = uri;
|
||||
_environment = lookups;
|
||||
_umbracoContext = umbracoContext;
|
||||
_niceUrls = niceUrls;
|
||||
RoutingContext = routingContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the id of the requested node, if any, else zero.
|
||||
/// </summary>
|
||||
int _nodeId = 0;
|
||||
|
||||
/// <summary>
|
||||
/// the requested node, if any, else null.
|
||||
/// </summary>
|
||||
XmlNode _node = null;
|
||||
|
||||
#region Properties
|
||||
|
||||
// the id of the requested node, if any, else zero.
|
||||
int _nodeId = 0;
|
||||
|
||||
// the requested node, if any, else null.
|
||||
XmlNode _node = null;
|
||||
/// <summary>
|
||||
/// Returns the current RoutingContext
|
||||
/// </summary>
|
||||
public RoutingContext RoutingContext { get; private set; }
|
||||
|
||||
public Uri Uri { get; private set; }
|
||||
|
||||
@@ -74,7 +82,7 @@ namespace Umbraco.Web.Routing
|
||||
_node = value;
|
||||
this.Template = null;
|
||||
if (_node != null)
|
||||
_nodeId = int.Parse(_environment.ContentStore.GetNodeProperty(_node, "@id"));
|
||||
_nodeId = int.Parse(RoutingContext.ContentStore.GetNodeProperty(_node, "@id"));
|
||||
else
|
||||
_nodeId = 0;
|
||||
}
|
||||
@@ -134,15 +142,9 @@ namespace Umbraco.Web.Routing
|
||||
|
||||
#region Resolve
|
||||
|
||||
readonly RoutingEnvironment _environment;
|
||||
private readonly UmbracoContext _umbracoContext;
|
||||
private readonly NiceUrls _niceUrls;
|
||||
|
||||
/// <summary>
|
||||
/// Determines the site root (if any) matching the http request.
|
||||
/// </summary>
|
||||
/// <param name="host">The host name part of the http request, eg. <c>www.example.com</c>.</param>
|
||||
/// <param name="url">The url part of the http request, starting with a slash, eg. <c>/foo/bar</c>.</param>
|
||||
/// </summary>
|
||||
/// <returns>A value indicating whether a domain was found.</returns>
|
||||
public bool ResolveDomain()
|
||||
{
|
||||
@@ -200,7 +202,8 @@ namespace Umbraco.Web.Routing
|
||||
// the first successful lookup, if any, will set this.Node, and may also set this.Template
|
||||
// some lookups may implement caching
|
||||
Trace.TraceInformation("{0}Begin lookup", tracePrefix);
|
||||
_environment.Lookups.Any(lookup => lookup.LookupDocument(this));
|
||||
var lookups = RoutingContext.RouteLookups.GetLookups();
|
||||
lookups.Any(lookup => lookup.LookupDocument(this));
|
||||
Trace.TraceInformation("{0}End lookup, {1}", tracePrefix, (this.HasNode ? "a document was found" : "no document was found"));
|
||||
|
||||
// fixme - not handling umbracoRedirect
|
||||
@@ -240,7 +243,7 @@ namespace Umbraco.Web.Routing
|
||||
Trace.TraceInformation("{0}No document, try notFound lookup", tracePrefix);
|
||||
|
||||
// if it fails then give up, there isn't much more that we can do
|
||||
if (_environment.LookupNotFound == null || !_environment.LookupNotFound.LookupDocument(this))
|
||||
if (RoutingContext.LookupNotFound == null || !RoutingContext.LookupNotFound.LookupDocument(this))
|
||||
{
|
||||
Trace.TraceInformation("{0}Failed to find a document, give up", tracePrefix);
|
||||
break;
|
||||
@@ -292,7 +295,7 @@ namespace Umbraco.Web.Routing
|
||||
throw new InvalidOperationException("There is no node.");
|
||||
|
||||
bool redirect = false;
|
||||
string internalRedirect = _environment.ContentStore.GetNodeProperty(this.Node, "umbracoInternalRedirectId");
|
||||
string internalRedirect = RoutingContext.ContentStore.GetNodeProperty(this.Node, "umbracoInternalRedirectId");
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(internalRedirect))
|
||||
{
|
||||
@@ -316,7 +319,7 @@ namespace Umbraco.Web.Routing
|
||||
else
|
||||
{
|
||||
// redirect to another page
|
||||
var node = _environment.ContentStore.GetNodeById(internalRedirectId);
|
||||
var node = RoutingContext.ContentStore.GetNodeById(internalRedirectId);
|
||||
this.Node = node;
|
||||
if (node != null)
|
||||
{
|
||||
@@ -344,7 +347,7 @@ namespace Umbraco.Web.Routing
|
||||
if (this.Node == null)
|
||||
throw new InvalidOperationException("There is no node.");
|
||||
|
||||
var path = _environment.ContentStore.GetNodeProperty(this.Node, "@path");
|
||||
var path = RoutingContext.ContentStore.GetNodeProperty(this.Node, "@path");
|
||||
|
||||
if (Access.IsProtected(this.NodeId, path))
|
||||
{
|
||||
@@ -357,14 +360,14 @@ namespace Umbraco.Web.Routing
|
||||
Trace.TraceInformation("{0}Not logged in, redirect to login page", tracePrefix);
|
||||
var loginPageId = Access.GetLoginPage(path);
|
||||
if (loginPageId != this.NodeId)
|
||||
this.Node = _environment.ContentStore.GetNodeById(loginPageId);
|
||||
this.Node = RoutingContext.ContentStore.GetNodeById(loginPageId);
|
||||
}
|
||||
else if (!Access.HasAccces(this.NodeId, user.ProviderUserKey))
|
||||
{
|
||||
Trace.TraceInformation("{0}Current member has not access, redirect to error page", tracePrefix);
|
||||
var errorPageId = Access.GetErrorPage(path);
|
||||
if (errorPageId != this.NodeId)
|
||||
this.Node = _environment.ContentStore.GetNodeById(errorPageId);
|
||||
this.Node = RoutingContext.ContentStore.GetNodeById(errorPageId);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -387,9 +390,9 @@ namespace Umbraco.Web.Routing
|
||||
if (this.Node == null)
|
||||
throw new InvalidOperationException("There is no node.");
|
||||
|
||||
var templateAlias = _umbracoContext.HttpContext.Request.QueryString["altTemplate"];
|
||||
var templateAlias = RoutingContext.UmbracoContext.HttpContext.Request.QueryString["altTemplate"];
|
||||
if (string.IsNullOrWhiteSpace(templateAlias))
|
||||
templateAlias = _umbracoContext.HttpContext.Request.Form["altTemplate"];
|
||||
templateAlias = RoutingContext.UmbracoContext.HttpContext.Request.Form["altTemplate"];
|
||||
|
||||
// fixme - we might want to support cookies?!? NO but provide a hook to change the template
|
||||
|
||||
@@ -397,7 +400,7 @@ namespace Umbraco.Web.Routing
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(templateAlias))
|
||||
{
|
||||
templateAlias = _environment.ContentStore.GetNodeProperty(this.Node, "@template");
|
||||
templateAlias = RoutingContext.ContentStore.GetNodeProperty(this.Node, "@template");
|
||||
Trace.TraceInformation("{0}Look for template id={1}", tracePrefix, templateAlias);
|
||||
int templateId;
|
||||
if (!int.TryParse(templateAlias, out templateId))
|
||||
@@ -439,11 +442,11 @@ namespace Umbraco.Web.Routing
|
||||
if (this.HasNode)
|
||||
{
|
||||
int redirectId;
|
||||
if (!int.TryParse(_environment.ContentStore.GetNodeProperty(this.Node, "umbracoRedirect"), out redirectId))
|
||||
if (!int.TryParse(RoutingContext.ContentStore.GetNodeProperty(this.Node, "umbracoRedirect"), out redirectId))
|
||||
redirectId = -1;
|
||||
string redirectUrl = "#";
|
||||
if (redirectId > 0)
|
||||
redirectUrl = _niceUrls.GetNiceUrl(redirectId);
|
||||
redirectUrl = RoutingContext.NiceUrlResolver.GetNiceUrl(redirectId);
|
||||
if (redirectUrl != "#")
|
||||
this.RedirectUrl = redirectUrl;
|
||||
}
|
||||
|
||||
11
src/Umbraco.Web/Routing/IRoutesCache.cs
Normal file
11
src/Umbraco.Web/Routing/IRoutesCache.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Umbraco.Web.Routing
|
||||
{
|
||||
internal interface IRoutesCache
|
||||
{
|
||||
void Store(int nodeId, string route);
|
||||
string GetRoute(int nodeId);
|
||||
int GetNodeId(string route);
|
||||
void ClearNode(int nodeId);
|
||||
void Clear();
|
||||
}
|
||||
}
|
||||
@@ -13,14 +13,9 @@ namespace Umbraco.Web.Routing
|
||||
[LookupWeight(50)]
|
||||
internal class LookupByAlias : ILookup
|
||||
{
|
||||
public LookupByAlias(ContentStore contentStore)
|
||||
{
|
||||
_contentStore = contentStore;
|
||||
}
|
||||
|
||||
|
||||
static readonly TraceSource Trace = new TraceSource("LookupByAlias");
|
||||
|
||||
readonly ContentStore _contentStore;
|
||||
|
||||
public bool LookupDocument(DocumentRequest docreq)
|
||||
{
|
||||
@@ -28,7 +23,7 @@ namespace Umbraco.Web.Routing
|
||||
|
||||
if (docreq.Uri.AbsolutePath != "/") // no alias if "/"
|
||||
{
|
||||
node = _contentStore.GetNodeByUrlAlias(docreq.HasDomain ? docreq.Domain.RootNodeId : 0, docreq.Uri.AbsolutePath);
|
||||
node = docreq.RoutingContext.ContentStore.GetNodeByUrlAlias(docreq.HasDomain ? docreq.Domain.RootNodeId : 0, docreq.Uri.AbsolutePath);
|
||||
if (node != null)
|
||||
{
|
||||
Trace.TraceInformation("Path \"{0}\" is an alias for id={1}", docreq.Uri.AbsolutePath, docreq.NodeId);
|
||||
|
||||
@@ -10,24 +10,9 @@ namespace Umbraco.Web.Routing
|
||||
[LookupWeight(20)]
|
||||
internal class LookupById : ILookup
|
||||
{
|
||||
public LookupById(ContentStore contentStore)
|
||||
{
|
||||
_contentStore = contentStore;
|
||||
}
|
||||
|
||||
|
||||
static readonly TraceSource Trace = new TraceSource("LookupById");
|
||||
|
||||
readonly ContentStore _contentStore;
|
||||
|
||||
////[Import]
|
||||
//IContentStore ContentStoreImport
|
||||
//{
|
||||
// set { _contentStore = value; }
|
||||
//}
|
||||
|
||||
//public LookupById()
|
||||
//{ }
|
||||
|
||||
public bool LookupDocument(DocumentRequest docreq)
|
||||
{
|
||||
XmlNode node = null;
|
||||
@@ -43,7 +28,7 @@ namespace Umbraco.Web.Routing
|
||||
if (nodeId > 0)
|
||||
{
|
||||
Trace.TraceInformation("Id={0}", nodeId);
|
||||
node = _contentStore.GetNodeById(nodeId);
|
||||
node = docreq.RoutingContext.ContentStore.GetNodeById(nodeId);
|
||||
if (node != null)
|
||||
{
|
||||
docreq.Node = node;
|
||||
|
||||
@@ -9,17 +9,9 @@ namespace Umbraco.Web.Routing
|
||||
[LookupWeight(10)]
|
||||
internal class LookupByPath : ILookup
|
||||
{
|
||||
public LookupByPath(ContentStore contentStore, RoutesCache routesCache)
|
||||
{
|
||||
ContentStore = contentStore;
|
||||
RoutesCache = routesCache;
|
||||
}
|
||||
|
||||
|
||||
static readonly TraceSource Trace = new TraceSource("LookupByPath");
|
||||
|
||||
protected ContentStore ContentStore;
|
||||
protected RoutesCache RoutesCache;
|
||||
|
||||
public virtual bool LookupDocument(DocumentRequest docreq)
|
||||
{
|
||||
string route;
|
||||
@@ -36,11 +28,16 @@ namespace Umbraco.Web.Routing
|
||||
{
|
||||
Trace.TraceInformation("Test route \"{0}\"", route);
|
||||
|
||||
var nodeId = RoutesCache.GetNodeId(route);
|
||||
//return '0' if in preview mode!
|
||||
var nodeId = !docreq.RoutingContext.UmbracoContext.InPreviewMode
|
||||
? docreq.RoutingContext.UmbracoContext.RoutesCache.GetNodeId(route)
|
||||
: 0;
|
||||
|
||||
|
||||
XmlNode node = null;
|
||||
if (nodeId > 0)
|
||||
{
|
||||
node = ContentStore.GetNodeById(nodeId);
|
||||
node = docreq.RoutingContext.ContentStore.GetNodeById(nodeId);
|
||||
if (node != null)
|
||||
{
|
||||
docreq.Node = node;
|
||||
@@ -48,19 +45,24 @@ namespace Umbraco.Web.Routing
|
||||
}
|
||||
else
|
||||
{
|
||||
RoutesCache.ClearNode(nodeId);
|
||||
docreq.RoutingContext.UmbracoContext.RoutesCache.ClearNode(nodeId);
|
||||
}
|
||||
}
|
||||
|
||||
if (node == null)
|
||||
{
|
||||
Trace.TraceInformation("Cache miss, query");
|
||||
node = ContentStore.GetNodeByRoute(route);
|
||||
node = docreq.RoutingContext.ContentStore.GetNodeByRoute(route);
|
||||
if (node != null)
|
||||
{
|
||||
docreq.Node = node;
|
||||
Trace.TraceInformation("Query matches, id={0}", docreq.NodeId);
|
||||
RoutesCache.Store(docreq.NodeId, route);
|
||||
|
||||
if (!docreq.RoutingContext.UmbracoContext.InPreviewMode)
|
||||
{
|
||||
docreq.RoutingContext.UmbracoContext.RoutesCache.Store(docreq.NodeId, route); // will not write if previewing
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -11,12 +11,7 @@ namespace Umbraco.Web.Routing
|
||||
[LookupWeight(30)]
|
||||
internal class LookupByPathWithTemplate : LookupByPath, ILookup
|
||||
{
|
||||
static readonly TraceSource Trace = new TraceSource("LookupByPathWithTemplate");
|
||||
|
||||
public LookupByPathWithTemplate(ContentStore contentStore, RoutesCache routesCache)
|
||||
: base(contentStore, routesCache)
|
||||
{
|
||||
}
|
||||
static readonly TraceSource Trace = new TraceSource("LookupByPathWithTemplate");
|
||||
|
||||
public override bool LookupDocument(DocumentRequest docreq)
|
||||
{
|
||||
|
||||
@@ -14,15 +14,7 @@ namespace Umbraco.Web.Routing
|
||||
[LookupWeight(40)]
|
||||
internal class LookupByProfile : LookupByPath, ILookup
|
||||
{
|
||||
private readonly UmbracoContext _umbracoContext;
|
||||
static readonly TraceSource Trace = new TraceSource("LookupByProfile");
|
||||
|
||||
|
||||
public LookupByProfile(ContentStore contentStore, RoutesCache routesCache, UmbracoContext umbracoContext)
|
||||
: base(contentStore, routesCache)
|
||||
{
|
||||
_umbracoContext = umbracoContext;
|
||||
}
|
||||
static readonly TraceSource Trace = new TraceSource("LookupByProfile");
|
||||
|
||||
public override bool LookupDocument(DocumentRequest docreq)
|
||||
{
|
||||
@@ -44,7 +36,10 @@ namespace Umbraco.Web.Routing
|
||||
node = LookupDocumentNode(docreq, route);
|
||||
|
||||
if (node != null)
|
||||
_umbracoContext.HttpContext.Items["umbMemberLogin"] = memberLogin;
|
||||
{
|
||||
//TODO: Should be handled by Context Items class manager (http://issues.umbraco.org/issue/U4-61)
|
||||
docreq.RoutingContext.UmbracoContext.HttpContext.Items["umbMemberLogin"] = memberLogin;
|
||||
}
|
||||
else
|
||||
Trace.TraceInformation("No document matching profile path?");
|
||||
}
|
||||
|
||||
@@ -11,18 +11,12 @@ namespace Umbraco.Web.Routing
|
||||
{
|
||||
internal class LookupFor404 : ILookupNotFound
|
||||
{
|
||||
public LookupFor404(ContentStore contentStore)
|
||||
{
|
||||
_contentStore = contentStore;
|
||||
}
|
||||
|
||||
|
||||
static TraceSource _trace = new TraceSource("LookupByAlias");
|
||||
|
||||
private readonly ContentStore _contentStore;
|
||||
|
||||
public bool LookupDocument(DocumentRequest docRequest)
|
||||
{
|
||||
docRequest.Node = HandlePageNotFound(docRequest.Uri.AbsolutePath);
|
||||
docRequest.Node = HandlePageNotFound(docRequest);
|
||||
return docRequest.HasNode;
|
||||
}
|
||||
|
||||
@@ -30,17 +24,17 @@ namespace Umbraco.Web.Routing
|
||||
|
||||
// copied from presentation/requestHandler
|
||||
// temporary!!
|
||||
XmlNode HandlePageNotFound(string url)
|
||||
XmlNode HandlePageNotFound(DocumentRequest docRequest)
|
||||
{
|
||||
HttpContext.Current.Trace.Write("NotFoundHandler", string.Format("Running for url='{0}'.", url));
|
||||
HttpContext.Current.Trace.Write("NotFoundHandler", string.Format("Running for url='{0}'.", docRequest.Uri.AbsolutePath));
|
||||
XmlNode currentPage = null;
|
||||
|
||||
foreach (var handler in GetNotFoundHandlers())
|
||||
{
|
||||
if (handler.Execute(url) && handler.redirectID > 0)
|
||||
if (handler.Execute(docRequest.Uri.AbsolutePath) && handler.redirectID > 0)
|
||||
{
|
||||
//currentPage = umbracoContent.GetElementById(handler.redirectID.ToString());
|
||||
currentPage = _contentStore.GetNodeById(handler.redirectID);
|
||||
currentPage = docRequest.RoutingContext.ContentStore.GetNodeById(handler.redirectID);
|
||||
|
||||
// FIXME - could it be null?
|
||||
|
||||
|
||||
106
src/Umbraco.Web/Routing/RouteLookups.cs
Normal file
106
src/Umbraco.Web/Routing/RouteLookups.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Umbraco.Core;
|
||||
|
||||
namespace Umbraco.Web.Routing
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a collection of ILookup used for routing that are registered in the application
|
||||
/// </summary>
|
||||
internal class RouteLookups
|
||||
{
|
||||
private static readonly List<ILookup> Lookups = new List<ILookup>();
|
||||
private static readonly ReaderWriterLockSlim Lock = new ReaderWriterLockSlim();
|
||||
|
||||
/// <summary>
|
||||
/// Singleton accessor
|
||||
/// </summary>
|
||||
public static RouteLookups Current { get; internal set; }
|
||||
|
||||
internal RouteLookups(IEnumerable<ILookup> lookups)
|
||||
{
|
||||
Lookups.AddRange(SortByWeight(lookups));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all of the lookups
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<ILookup> GetLookups()
|
||||
{
|
||||
return Lookups;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes an ILookup based on the specified Type
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public void RemoveLookup<T>()
|
||||
where T : ILookup
|
||||
{
|
||||
using (new WriteLock(Lock))
|
||||
{
|
||||
Lookups.Remove(Lookups.SingleOrDefault(x => x is T));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new lookup to the end of the list
|
||||
/// </summary>
|
||||
/// <param name="lookup"></param>
|
||||
public void AddLookup(ILookup lookup)
|
||||
{
|
||||
if (CheckExists(lookup))
|
||||
throw new InvalidOperationException("The lookup type " + lookup + " already exists in the lookup collection");
|
||||
|
||||
using (new WriteLock(Lock))
|
||||
{
|
||||
Lookups.Add(lookup);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a lookup at the specified index
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="lookup"></param>
|
||||
public void InsertLookup(int index, ILookup lookup)
|
||||
{
|
||||
if (CheckExists(lookup))
|
||||
throw new InvalidOperationException("The lookup type " + lookup + " already exists in the lookup collection");
|
||||
|
||||
using (new WriteLock(Lock))
|
||||
{
|
||||
Lookups.Insert(index, lookup);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// checks if a lookup already exists by type
|
||||
/// </summary>
|
||||
/// <param name="lookup"></param>
|
||||
/// <returns></returns>
|
||||
private static bool CheckExists(ILookup lookup)
|
||||
{
|
||||
return Lookups.Any(x => x.GetType() == lookup.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sorts the ILookups in the list based on an attribute weight if one is specified
|
||||
/// </summary>
|
||||
/// <param name="lookups"></param>
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<ILookup> SortByWeight(IEnumerable<ILookup> lookups)
|
||||
{
|
||||
return lookups.OrderBy(x =>
|
||||
{
|
||||
var attribute = x.GetType().GetCustomAttributes(true).OfType<LookupWeightAttribute>().SingleOrDefault();
|
||||
return attribute == null ? LookupWeightAttribute.DefaultWeight : attribute.Weight;
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Web.Routing
|
||||
{
|
||||
@@ -8,82 +8,54 @@ namespace Umbraco.Web.Routing
|
||||
//
|
||||
// a route is [rootId]/path/to/node
|
||||
// where rootId is the id of the "site root" node
|
||||
// if missing then the "site root" is the content root
|
||||
//
|
||||
internal class RoutesCache
|
||||
{
|
||||
private readonly object _lock = new object();
|
||||
private Dictionary<int, string> _routes;
|
||||
private Dictionary<string, int> _nodeIds;
|
||||
internal class RoutesCache
|
||||
{
|
||||
private static readonly RoutesCache Instance = new RoutesCache();
|
||||
private static IRoutesCache _provider;
|
||||
|
||||
private readonly UmbracoContext _umbracoContext;
|
||||
/// <summary>
|
||||
/// public contructor assigns the DefaultRoutesCache as the default provider
|
||||
/// </summary>
|
||||
public RoutesCache()
|
||||
:this(null)
|
||||
{
|
||||
}
|
||||
|
||||
public RoutesCache(UmbracoContext umbracoContext)
|
||||
{
|
||||
_umbracoContext = umbracoContext;
|
||||
/// <summary>
|
||||
/// Constructor sets a custom provider if specified
|
||||
/// </summary>
|
||||
/// <param name="provider"></param>
|
||||
internal RoutesCache(IRoutesCache provider)
|
||||
{
|
||||
_provider = provider ?? new DefaultRoutesCache();
|
||||
}
|
||||
|
||||
Clear();
|
||||
/// <summary>
|
||||
/// Set the routes cache provider
|
||||
/// </summary>
|
||||
/// <param name="provider"></param>
|
||||
public static void SetProvider(IRoutesCache provider)
|
||||
{
|
||||
if (provider == null) throw new ArgumentNullException("provider");
|
||||
_provider = provider;
|
||||
}
|
||||
|
||||
// here we should register handlers to clear the cache when content changes
|
||||
// at the moment this is done by library, which clears everything when content changed
|
||||
//
|
||||
// but really, we should do some partial refreshes!
|
||||
// otherwise, we could even cache 404 errors...
|
||||
}
|
||||
/// <summary>
|
||||
/// Singleton accessor
|
||||
/// </summary>
|
||||
public static RoutesCache Current
|
||||
{
|
||||
get { return Instance; }
|
||||
}
|
||||
|
||||
public void Store(int nodeId, string route)
|
||||
{
|
||||
if (_umbracoContext.InPreviewMode)
|
||||
return;
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
_routes[nodeId] = route;
|
||||
_nodeIds[route] = nodeId;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetRoute(int nodeId)
|
||||
{
|
||||
if (_umbracoContext.InPreviewMode)
|
||||
return null;
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
return _routes.ContainsKey(nodeId) ? _routes[nodeId] : null;
|
||||
}
|
||||
}
|
||||
|
||||
public int GetNodeId(string route)
|
||||
{
|
||||
if (_umbracoContext.InPreviewMode)
|
||||
return 0;
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
return _nodeIds.ContainsKey(route) ? _nodeIds[route] : 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearNode(int nodeId)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (_routes.ContainsKey(nodeId))
|
||||
{
|
||||
_nodeIds.Remove(_routes[nodeId]);
|
||||
_routes.Remove(nodeId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_routes = new Dictionary<int, string>();
|
||||
_nodeIds = new Dictionary<string, int>();
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Get the current provider
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IRoutesCache GetProvider()
|
||||
{
|
||||
return _provider;
|
||||
}
|
||||
}
|
||||
}
|
||||
33
src/Umbraco.Web/Routing/RoutingContext.cs
Normal file
33
src/Umbraco.Web/Routing/RoutingContext.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Web.Routing
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// represents a request for one specified Umbraco document to be rendered by one specified template,
|
||||
/// using one particular culture.
|
||||
/// </summary>
|
||||
internal class RoutingContext
|
||||
{
|
||||
public RoutingContext(
|
||||
UmbracoContext umbracoContext,
|
||||
RouteLookups lookups,
|
||||
ILookupNotFound lookupNotFound,
|
||||
ContentStore contentStore,
|
||||
NiceUrlResolver niceUrlResolver)
|
||||
{
|
||||
UmbracoContext = umbracoContext;
|
||||
RouteLookups = lookups;
|
||||
LookupNotFound = lookupNotFound;
|
||||
ContentStore = contentStore;
|
||||
NiceUrlResolver = niceUrlResolver;
|
||||
}
|
||||
|
||||
public UmbracoContext UmbracoContext { get; private set; }
|
||||
public RouteLookups RouteLookups { get; private set; }
|
||||
public ILookupNotFound LookupNotFound { get; private set; }
|
||||
public ContentStore ContentStore { get; private set; }
|
||||
public NiceUrlResolver NiceUrlResolver { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Web.Routing
|
||||
{
|
||||
internal class RoutingEnvironment
|
||||
{
|
||||
public RoutingEnvironment(
|
||||
IEnumerable<ILookup> lookups,
|
||||
ILookupNotFound lookupNotFound,
|
||||
ContentStore contentStore)
|
||||
{
|
||||
Lookups = SortByPartWeight(lookups);
|
||||
LookupNotFound = lookupNotFound;
|
||||
ContentStore = contentStore;
|
||||
}
|
||||
|
||||
private static IEnumerable<ILookup> SortByPartWeight(IEnumerable<ILookup> lookups)
|
||||
{
|
||||
return lookups.OrderBy(x =>
|
||||
{
|
||||
var attribute = x.GetType().GetCustomAttributes(true).OfType<LookupWeightAttribute>().SingleOrDefault();
|
||||
return attribute == null ? LookupWeightAttribute.DefaultWeight : attribute.Weight;
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
public IEnumerable<ILookup> Lookups
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public ILookupNotFound LookupNotFound { get; private set; }
|
||||
|
||||
public ContentStore ContentStore { get; private set; }
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user