Created an ContentStoreResolver so we can specify a custom ContentStore which means we can return a custom
IDocument. This now means we've opened up the possibility of an abstracted routing lookup system to map to a Document stored anywhere. By default this is obviously Xml but could theoretically be anything, still internal until more review of the API is done.
This commit is contained in:
@@ -13,7 +13,7 @@ namespace Umbraco.Tests
|
||||
{
|
||||
private FakeHttpContextFactory _httpContextFactory;
|
||||
private UmbracoContext _umbracoContext;
|
||||
private ContentStore _contentStore;
|
||||
private XmlContentStore _contentStore;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
@@ -56,7 +56,7 @@ namespace Umbraco.Tests
|
||||
return xDoc;
|
||||
};
|
||||
|
||||
_contentStore = new ContentStore(_umbracoContext);
|
||||
_contentStore = new XmlContentStore();
|
||||
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace Umbraco.Tests
|
||||
[TestCase("/home/Sub1", 1173)] //test different cases
|
||||
public void Get_Node_By_Route(string route, int nodeId)
|
||||
{
|
||||
var result = _contentStore.GetDocumentByRoute(route, false);
|
||||
var result = _contentStore.GetDocumentByRoute(_umbracoContext, route, false);
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual(nodeId, result.Id);
|
||||
}
|
||||
@@ -84,7 +84,7 @@ namespace Umbraco.Tests
|
||||
[TestCase("/Sub1", 1173)]
|
||||
public void Get_Node_By_Route_Hiding_Top_Level_Nodes(string route, int nodeId)
|
||||
{
|
||||
var result = _contentStore.GetDocumentByRoute(route, true);
|
||||
var result = _contentStore.GetDocumentByRoute(_umbracoContext, route, true);
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual(nodeId, result.Id);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Umbraco.Tests.DocumentLookups
|
||||
protected RoutingContext GetRoutingContext(string url, Template template)
|
||||
{
|
||||
var umbracoContext = GetUmbracoContext(url, template);
|
||||
var contentStore = new ContentStore(umbracoContext);
|
||||
var contentStore = new XmlContentStore();
|
||||
var niceUrls = new NiceUrlProvider(contentStore, umbracoContext);
|
||||
var routingRequest = new RoutingContext(
|
||||
umbracoContext,
|
||||
|
||||
32
src/Umbraco.Web/ContentStoreResolver.cs
Normal file
32
src/Umbraco.Web/ContentStoreResolver.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
/// <summary>
|
||||
/// An object resolver to return the IContentStore
|
||||
/// </summary>
|
||||
internal class ContentStoreResolver : SingleObjectResolverBase<ContentStoreResolver, IContentStore>
|
||||
{
|
||||
internal ContentStoreResolver(IContentStore contentStore)
|
||||
{
|
||||
Value = contentStore;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can be used by developers at runtime to set their IContentStore at app startup
|
||||
/// </summary>
|
||||
/// <param name="contentStore"></param>
|
||||
public void SetContentStore(IContentStore contentStore)
|
||||
{
|
||||
Value = contentStore;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the IContentStore
|
||||
/// </summary>
|
||||
public IContentStore ContentStore
|
||||
{
|
||||
get { return Value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,9 @@ namespace Umbraco.Web
|
||||
{
|
||||
internal interface IContentStore
|
||||
{
|
||||
IDocument GetDocumentById(int nodeId);
|
||||
IDocument GetDocumentByRoute(string route, bool? hideTopLevelNode = null);
|
||||
IDocument GetDocumentByUrlAlias(int rootNodeId, string alias);
|
||||
string GetDocumentProperty(IDocument node, string propertyAlias);
|
||||
IDocument GetDocumentById(UmbracoContext umbracoContext, int nodeId);
|
||||
IDocument GetDocumentByRoute(UmbracoContext umbracoContext, string route, bool? hideTopLevelNode = null);
|
||||
IDocument GetDocumentByUrlAlias(UmbracoContext umbracoContext, int rootNodeId, string alias);
|
||||
string GetDocumentProperty(UmbracoContext umbracoContext, IDocument node, string propertyAlias);
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,9 @@ namespace Umbraco.Web.Routing
|
||||
if (handler.Execute(docRequest.Uri.AbsolutePath) && handler.redirectID > 0)
|
||||
{
|
||||
//currentPage = umbracoContent.GetElementById(handler.redirectID.ToString());
|
||||
currentPage = docRequest.RoutingContext.ContentStore.GetDocumentById(handler.redirectID);
|
||||
currentPage = docRequest.RoutingContext.ContentStore.GetDocumentById(
|
||||
docRequest.RoutingContext.UmbracoContext,
|
||||
handler.redirectID);
|
||||
|
||||
// FIXME - could it be null?
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@ namespace Umbraco.Web.Routing
|
||||
throw new InvalidOperationException("There is no node.");
|
||||
|
||||
bool redirect = false;
|
||||
string internalRedirect = _routingContext.ContentStore.GetDocumentProperty(_documentRequest.Node, "umbracoInternalRedirectId");
|
||||
string internalRedirect = _routingContext.ContentStore.GetDocumentProperty(_umbracoContext, _documentRequest.Node, "umbracoInternalRedirectId");
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(internalRedirect))
|
||||
{
|
||||
@@ -207,7 +207,10 @@ namespace Umbraco.Web.Routing
|
||||
else
|
||||
{
|
||||
// redirect to another page
|
||||
var node = _routingContext.ContentStore.GetDocumentById(internalRedirectId);
|
||||
var node = _routingContext.ContentStore.GetDocumentById(
|
||||
_umbracoContext,
|
||||
internalRedirectId);
|
||||
|
||||
_documentRequest.Node = node;
|
||||
if (node != null)
|
||||
{
|
||||
@@ -235,7 +238,7 @@ namespace Umbraco.Web.Routing
|
||||
if (_documentRequest.Node == null)
|
||||
throw new InvalidOperationException("There is no node.");
|
||||
|
||||
var path = _routingContext.ContentStore.GetDocumentProperty(_documentRequest.Node, "@path");
|
||||
var path = _routingContext.ContentStore.GetDocumentProperty(_umbracoContext, _documentRequest.Node, "@path");
|
||||
|
||||
if (Access.IsProtected(_documentRequest.NodeId, path))
|
||||
{
|
||||
@@ -248,14 +251,18 @@ namespace Umbraco.Web.Routing
|
||||
LogHelper.Debug<DocumentRequest>("{0}Not logged in, redirect to login page", () => tracePrefix);
|
||||
var loginPageId = Access.GetLoginPage(path);
|
||||
if (loginPageId != _documentRequest.NodeId)
|
||||
_documentRequest.Node = _routingContext.ContentStore.GetDocumentById(loginPageId);
|
||||
_documentRequest.Node = _routingContext.ContentStore.GetDocumentById(
|
||||
_umbracoContext,
|
||||
loginPageId);
|
||||
}
|
||||
else if (!Access.HasAccces(_documentRequest.NodeId, user.ProviderUserKey))
|
||||
{
|
||||
LogHelper.Debug<DocumentRequest>("{0}Current member has not access, redirect to error page", () => tracePrefix);
|
||||
var errorPageId = Access.GetErrorPage(path);
|
||||
if (errorPageId != _documentRequest.NodeId)
|
||||
_documentRequest.Node = _routingContext.ContentStore.GetDocumentById(errorPageId);
|
||||
_documentRequest.Node = _routingContext.ContentStore.GetDocumentById(
|
||||
_umbracoContext,
|
||||
errorPageId);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -288,7 +295,7 @@ namespace Umbraco.Web.Routing
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(templateAlias))
|
||||
{
|
||||
templateAlias = _routingContext.ContentStore.GetDocumentProperty(_documentRequest.Node, "@template");
|
||||
templateAlias = _routingContext.ContentStore.GetDocumentProperty(_umbracoContext, _documentRequest.Node, "@template");
|
||||
LogHelper.Debug<DocumentRequest>("{0}Look for template id={1}", () => tracePrefix, () => templateAlias);
|
||||
int templateId;
|
||||
if (!int.TryParse(templateAlias, out templateId))
|
||||
@@ -330,7 +337,7 @@ namespace Umbraco.Web.Routing
|
||||
if (_documentRequest.HasNode)
|
||||
{
|
||||
int redirectId;
|
||||
if (!int.TryParse(_routingContext.ContentStore.GetDocumentProperty(_documentRequest.Node, "umbracoRedirect"), out redirectId))
|
||||
if (!int.TryParse(_routingContext.ContentStore.GetDocumentProperty(_umbracoContext, _documentRequest.Node, "umbracoRedirect"), out redirectId))
|
||||
redirectId = -1;
|
||||
string redirectUrl = "#";
|
||||
if (redirectId > 0)
|
||||
|
||||
@@ -28,7 +28,11 @@ namespace Umbraco.Web.Routing
|
||||
|
||||
if (docRequest.Uri.AbsolutePath != "/") // no alias if "/"
|
||||
{
|
||||
node = docRequest.RoutingContext.ContentStore.GetDocumentByUrlAlias(docRequest.HasDomain ? docRequest.Domain.RootNodeId : 0, docRequest.Uri.AbsolutePath);
|
||||
node = docRequest.RoutingContext.ContentStore.GetDocumentByUrlAlias(
|
||||
docRequest.RoutingContext.UmbracoContext,
|
||||
docRequest.HasDomain ? docRequest.Domain.RootNodeId : 0,
|
||||
docRequest.Uri.AbsolutePath);
|
||||
|
||||
if (node != null)
|
||||
{
|
||||
LogHelper.Debug<LookupByAlias>("Path \"{0}\" is an alias for id={1}", () => docRequest.Uri.AbsolutePath, () => docRequest.NodeId);
|
||||
|
||||
@@ -36,7 +36,10 @@ namespace Umbraco.Web.Routing
|
||||
if (nodeId > 0)
|
||||
{
|
||||
LogHelper.Debug<LookupById>("Id={0}", () => nodeId);
|
||||
node = docRequest.RoutingContext.ContentStore.GetDocumentById(nodeId);
|
||||
node = docRequest.RoutingContext.ContentStore.GetDocumentById(
|
||||
docRequest.RoutingContext.UmbracoContext,
|
||||
nodeId);
|
||||
|
||||
if (node != null)
|
||||
{
|
||||
docRequest.Node = node;
|
||||
|
||||
@@ -51,7 +51,10 @@ namespace Umbraco.Web.Routing
|
||||
IDocument node = null;
|
||||
if (nodeId > 0)
|
||||
{
|
||||
node = docreq.RoutingContext.ContentStore.GetDocumentById(nodeId);
|
||||
node = docreq.RoutingContext.ContentStore.GetDocumentById(
|
||||
docreq.RoutingContext.UmbracoContext,
|
||||
nodeId);
|
||||
|
||||
if (node != null)
|
||||
{
|
||||
docreq.Node = node;
|
||||
@@ -66,7 +69,10 @@ namespace Umbraco.Web.Routing
|
||||
if (node == null)
|
||||
{
|
||||
LogHelper.Debug<LookupByNiceUrl>("Cache miss, query");
|
||||
node = docreq.RoutingContext.ContentStore.GetDocumentByRoute(route);
|
||||
node = docreq.RoutingContext.ContentStore.GetDocumentByRoute(
|
||||
docreq.RoutingContext.UmbracoContext,
|
||||
route);
|
||||
|
||||
if (node != null)
|
||||
{
|
||||
docreq.Node = node;
|
||||
|
||||
@@ -22,14 +22,14 @@ namespace Umbraco.Web.Routing
|
||||
/// </summary>
|
||||
/// <param name="contentStore">The content store.</param>
|
||||
/// <param name="umbracoContext">The Umbraco context.</param>
|
||||
public NiceUrlProvider(ContentStore contentStore, UmbracoContext umbracoContext)
|
||||
public NiceUrlProvider(IContentStore contentStore, UmbracoContext umbracoContext)
|
||||
{
|
||||
_umbracoContext = umbracoContext;
|
||||
_contentStore = contentStore;
|
||||
}
|
||||
|
||||
private readonly UmbracoContext _umbracoContext;
|
||||
private readonly ContentStore _contentStore;
|
||||
private readonly IContentStore _contentStore;
|
||||
|
||||
// note: this could be a parameter...
|
||||
const string UrlNameProperty = "@urlName";
|
||||
@@ -86,7 +86,7 @@ namespace Umbraco.Web.Routing
|
||||
}
|
||||
else
|
||||
{
|
||||
var node = _contentStore.GetDocumentById(nodeId);
|
||||
var node = _contentStore.GetDocumentById(_umbracoContext, nodeId);
|
||||
if (node == null)
|
||||
return "#"; // legacy wrote to the log here...
|
||||
|
||||
@@ -95,9 +95,9 @@ namespace Umbraco.Web.Routing
|
||||
domainUri = DomainUriAtNode(id, current);
|
||||
while (domainUri == null && id > 0)
|
||||
{
|
||||
pathParts.Add(_contentStore.GetDocumentProperty(node, UrlNameProperty));
|
||||
pathParts.Add(_contentStore.GetDocumentProperty(_umbracoContext, node, UrlNameProperty));
|
||||
node = node.Parent; // set to parent node
|
||||
id = int.Parse(_contentStore.GetDocumentProperty(node, "@id")); // will be -1 or 1234
|
||||
id = int.Parse(_contentStore.GetDocumentProperty(_umbracoContext, node, "@id")); // will be -1 or 1234
|
||||
domainUri = id > 0 ? DomainUriAtNode(id, current) : null;
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ namespace Umbraco.Web.Routing
|
||||
}
|
||||
else
|
||||
{
|
||||
var node = _contentStore.GetDocumentById(nodeId);
|
||||
var node = _contentStore.GetDocumentById(_umbracoContext, nodeId);
|
||||
if (node == null)
|
||||
return new string[] { "#" }; // legacy wrote to the log here...
|
||||
|
||||
@@ -155,9 +155,9 @@ namespace Umbraco.Web.Routing
|
||||
domainUris = DomainUrisAtNode(id, current);
|
||||
while (!domainUris.Any() && id > 0)
|
||||
{
|
||||
pathParts.Add(_contentStore.GetDocumentProperty(node, UrlNameProperty));
|
||||
pathParts.Add(_contentStore.GetDocumentProperty(_umbracoContext, node, UrlNameProperty));
|
||||
node = node.Parent; //set to parent node
|
||||
id = int.Parse(_contentStore.GetDocumentProperty(node, "@id")); // will be -1 or 1234
|
||||
id = int.Parse(_contentStore.GetDocumentProperty(_umbracoContext, node, "@id")); // will be -1 or 1234
|
||||
domainUris = id > 0 ? DomainUrisAtNode(id, current) : new Uri[] { };
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace Umbraco.Web.Routing
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RoutingContext"/> class.
|
||||
/// </summary>
|
||||
/// <param name="umbracoContext"> </param>
|
||||
/// <param name="documentLookups">The document lookups resolver.</param>
|
||||
/// <param name="documentLastChanceLookup"> </param>
|
||||
/// <param name="contentStore">The content store.</param>
|
||||
@@ -20,7 +21,7 @@ namespace Umbraco.Web.Routing
|
||||
UmbracoContext umbracoContext,
|
||||
IEnumerable<IDocumentLookup> documentLookups,
|
||||
IDocumentLastChanceLookup documentLastChanceLookup,
|
||||
ContentStore contentStore,
|
||||
IContentStore contentStore,
|
||||
NiceUrlProvider niceUrlResolver)
|
||||
{
|
||||
this.UmbracoContext = umbracoContext;
|
||||
@@ -48,7 +49,7 @@ namespace Umbraco.Web.Routing
|
||||
/// <summary>
|
||||
/// Gets the content store.
|
||||
/// </summary>
|
||||
internal ContentStore ContentStore { get; private set; }
|
||||
internal IContentStore ContentStore { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the nice urls provider.
|
||||
|
||||
@@ -238,7 +238,8 @@
|
||||
<Compile Include="..\SolutionInfo.cs">
|
||||
<Link>Properties\SolutionInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="ContentStore.cs" />
|
||||
<Compile Include="XmlContentStore.cs" />
|
||||
<Compile Include="ContentStoreResolver.cs" />
|
||||
<Compile Include="DocumentNotFoundHttpHandler.cs" />
|
||||
<Compile Include="IContentStore.cs" />
|
||||
<Compile Include="Models\XmlDocument.cs" />
|
||||
|
||||
@@ -58,16 +58,14 @@ namespace Umbraco.Web
|
||||
RoutesCacheResolver.Current.RoutesCache);
|
||||
UmbracoContext.Current = umbracoContext;
|
||||
|
||||
//create a content store
|
||||
var contentStore = new ContentStore(umbracoContext);
|
||||
//create the nice urls
|
||||
var niceUrls = new NiceUrlProvider(contentStore, umbracoContext);
|
||||
var niceUrls = new NiceUrlProvider(ContentStoreResolver.Current.ContentStore, umbracoContext);
|
||||
//create the RoutingContext
|
||||
var routingContext = new RoutingContext(
|
||||
umbracoContext,
|
||||
DocumentLookupsResolver.Current.DocumentLookups,
|
||||
LastChanceLookupResolver.Current.LastChanceLookup,
|
||||
contentStore,
|
||||
ContentStoreResolver.Current.ContentStore,
|
||||
niceUrls);
|
||||
//assign the routing context back to the umbraco context
|
||||
umbracoContext.RoutingContext = routingContext;
|
||||
|
||||
@@ -63,6 +63,8 @@ namespace Umbraco.Web
|
||||
{
|
||||
base.InitializeResolvers();
|
||||
|
||||
ContentStoreResolver.Current = new ContentStoreResolver(new XmlContentStore());
|
||||
|
||||
FilteredControllerFactoriesResolver.Current = new FilteredControllerFactoriesResolver(
|
||||
//add all known factories, devs can then modify this list on application startup either by binding to events
|
||||
//or in their own global.asax
|
||||
|
||||
@@ -10,16 +10,11 @@ using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Used for the new routing system
|
||||
/// <summary>
|
||||
/// An IContentStore which uses the Xml cache system to return data
|
||||
/// </summary>
|
||||
internal class ContentStore : IContentStore
|
||||
internal class XmlContentStore : IContentStore
|
||||
{
|
||||
/// <summary>
|
||||
/// Delegate to return the current UmbracoContext
|
||||
/// </summary>
|
||||
private readonly UmbracoContext _umbracoContext;
|
||||
|
||||
private IDocument ConvertToDocument(XmlNode xmlNode)
|
||||
{
|
||||
@@ -29,22 +24,12 @@ namespace Umbraco.Web
|
||||
return new Models.XmlDocument(xmlNode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor accepting a delegate to resolve the UmbracoContext
|
||||
/// </summary>
|
||||
/// <param name="umbracoContext"></param>
|
||||
public ContentStore(UmbracoContext umbracoContext)
|
||||
{
|
||||
if (umbracoContext == null) throw new ArgumentNullException("umbracoContext");
|
||||
_umbracoContext = umbracoContext;
|
||||
}
|
||||
|
||||
public IDocument GetDocumentById(int nodeId)
|
||||
public IDocument GetDocumentById(UmbracoContext umbracoContext, int nodeId)
|
||||
{
|
||||
return ConvertToDocument(GetXml().GetElementById(nodeId.ToString()));
|
||||
return ConvertToDocument(GetXml(umbracoContext).GetElementById(nodeId.ToString()));
|
||||
}
|
||||
|
||||
public IDocument GetDocumentByRoute(string route, bool? hideTopLevelNode = null)
|
||||
public IDocument GetDocumentByRoute(UmbracoContext umbracoContext, string route, bool? hideTopLevelNode = null)
|
||||
{
|
||||
//set the default to be what is in the settings
|
||||
if (hideTopLevelNode == null)
|
||||
@@ -67,10 +52,10 @@ namespace Umbraco.Web
|
||||
|
||||
var xpath = CreateXpathQuery(startNodeId, path, hideTopLevelNode.Value);
|
||||
|
||||
return ConvertToDocument(GetXml().SelectSingleNode(xpath));
|
||||
return ConvertToDocument(GetXml(umbracoContext).SelectSingleNode(xpath));
|
||||
}
|
||||
|
||||
public IDocument GetDocumentByUrlAlias(int rootNodeId, string alias)
|
||||
public IDocument GetDocumentByUrlAlias(UmbracoContext umbracoContext, int rootNodeId, string alias)
|
||||
{
|
||||
|
||||
// the alias may be "foo/bar" or "/foo/bar"
|
||||
@@ -89,7 +74,7 @@ namespace Umbraco.Web
|
||||
|
||||
var xpath = xpathBuilder.ToString();
|
||||
|
||||
return ConvertToDocument(GetXml().SelectSingleNode(xpath));
|
||||
return ConvertToDocument(GetXml(umbracoContext).SelectSingleNode(xpath));
|
||||
}
|
||||
|
||||
//public IDocument GetNodeParent(IDocument node)
|
||||
@@ -97,7 +82,7 @@ namespace Umbraco.Web
|
||||
// return node.Parent;
|
||||
//}
|
||||
|
||||
public string GetDocumentProperty(IDocument node, string propertyAlias)
|
||||
public string GetDocumentProperty(UmbracoContext umbracoContext, IDocument node, string propertyAlias)
|
||||
{
|
||||
if (propertyAlias.StartsWith("@"))
|
||||
{
|
||||
@@ -120,9 +105,9 @@ namespace Umbraco.Web
|
||||
}
|
||||
}
|
||||
|
||||
XmlDocument GetXml()
|
||||
XmlDocument GetXml(UmbracoContext umbracoContext)
|
||||
{
|
||||
return _umbracoContext.GetXml();
|
||||
return umbracoContext.GetXml();
|
||||
}
|
||||
|
||||
static readonly char[] SlashChar = new char[] { '/' };
|
||||
Reference in New Issue
Block a user