diff --git a/src/Umbraco.Tests/ContentStoreTests.cs b/src/Umbraco.Tests/ContentStoreTests.cs index 0ada733670..7d51e586f9 100644 --- a/src/Umbraco.Tests/ContentStoreTests.cs +++ b/src/Umbraco.Tests/ContentStoreTests.cs @@ -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); } diff --git a/src/Umbraco.Tests/DocumentLookups/BaseTest.cs b/src/Umbraco.Tests/DocumentLookups/BaseTest.cs index 27085522ce..183c21d681 100644 --- a/src/Umbraco.Tests/DocumentLookups/BaseTest.cs +++ b/src/Umbraco.Tests/DocumentLookups/BaseTest.cs @@ -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, diff --git a/src/Umbraco.Web/ContentStoreResolver.cs b/src/Umbraco.Web/ContentStoreResolver.cs new file mode 100644 index 0000000000..25ca1d5e13 --- /dev/null +++ b/src/Umbraco.Web/ContentStoreResolver.cs @@ -0,0 +1,32 @@ +using Umbraco.Core.ObjectResolution; + +namespace Umbraco.Web +{ + /// + /// An object resolver to return the IContentStore + /// + internal class ContentStoreResolver : SingleObjectResolverBase + { + internal ContentStoreResolver(IContentStore contentStore) + { + Value = contentStore; + } + + /// + /// Can be used by developers at runtime to set their IContentStore at app startup + /// + /// + public void SetContentStore(IContentStore contentStore) + { + Value = contentStore; + } + + /// + /// Returns the IContentStore + /// + public IContentStore ContentStore + { + get { return Value; } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/IContentStore.cs b/src/Umbraco.Web/IContentStore.cs index 3cfe5cc60f..c09ea00579 100644 --- a/src/Umbraco.Web/IContentStore.cs +++ b/src/Umbraco.Web/IContentStore.cs @@ -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); } } \ No newline at end of file diff --git a/src/Umbraco.Web/Routing/DefaultLastChanceLookup.cs b/src/Umbraco.Web/Routing/DefaultLastChanceLookup.cs index 16e80e89d9..2a58df3f8f 100644 --- a/src/Umbraco.Web/Routing/DefaultLastChanceLookup.cs +++ b/src/Umbraco.Web/Routing/DefaultLastChanceLookup.cs @@ -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? diff --git a/src/Umbraco.Web/Routing/DocumentSearcher.cs b/src/Umbraco.Web/Routing/DocumentSearcher.cs index f25b890a1e..d259fdb9a7 100644 --- a/src/Umbraco.Web/Routing/DocumentSearcher.cs +++ b/src/Umbraco.Web/Routing/DocumentSearcher.cs @@ -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("{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("{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("{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) diff --git a/src/Umbraco.Web/Routing/LookupByAlias.cs b/src/Umbraco.Web/Routing/LookupByAlias.cs index 2128ad37f7..ab15ab9df0 100644 --- a/src/Umbraco.Web/Routing/LookupByAlias.cs +++ b/src/Umbraco.Web/Routing/LookupByAlias.cs @@ -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("Path \"{0}\" is an alias for id={1}", () => docRequest.Uri.AbsolutePath, () => docRequest.NodeId); diff --git a/src/Umbraco.Web/Routing/LookupById.cs b/src/Umbraco.Web/Routing/LookupById.cs index fb684ac4c9..0ed98d0baa 100644 --- a/src/Umbraco.Web/Routing/LookupById.cs +++ b/src/Umbraco.Web/Routing/LookupById.cs @@ -36,7 +36,10 @@ namespace Umbraco.Web.Routing if (nodeId > 0) { LogHelper.Debug("Id={0}", () => nodeId); - node = docRequest.RoutingContext.ContentStore.GetDocumentById(nodeId); + node = docRequest.RoutingContext.ContentStore.GetDocumentById( + docRequest.RoutingContext.UmbracoContext, + nodeId); + if (node != null) { docRequest.Node = node; diff --git a/src/Umbraco.Web/Routing/LookupByNiceUrl.cs b/src/Umbraco.Web/Routing/LookupByNiceUrl.cs index cbea836c60..de6ff0cf56 100644 --- a/src/Umbraco.Web/Routing/LookupByNiceUrl.cs +++ b/src/Umbraco.Web/Routing/LookupByNiceUrl.cs @@ -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("Cache miss, query"); - node = docreq.RoutingContext.ContentStore.GetDocumentByRoute(route); + node = docreq.RoutingContext.ContentStore.GetDocumentByRoute( + docreq.RoutingContext.UmbracoContext, + route); + if (node != null) { docreq.Node = node; diff --git a/src/Umbraco.Web/Routing/NiceUrlProvider.cs b/src/Umbraco.Web/Routing/NiceUrlProvider.cs index 5f60cee326..1b5ebfbe09 100644 --- a/src/Umbraco.Web/Routing/NiceUrlProvider.cs +++ b/src/Umbraco.Web/Routing/NiceUrlProvider.cs @@ -22,14 +22,14 @@ namespace Umbraco.Web.Routing /// /// The content store. /// The Umbraco context. - 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[] { }; } diff --git a/src/Umbraco.Web/Routing/RoutingContext.cs b/src/Umbraco.Web/Routing/RoutingContext.cs index d88aa4359e..0b3bc77c14 100644 --- a/src/Umbraco.Web/Routing/RoutingContext.cs +++ b/src/Umbraco.Web/Routing/RoutingContext.cs @@ -12,6 +12,7 @@ namespace Umbraco.Web.Routing /// /// Initializes a new instance of the class. /// + /// /// The document lookups resolver. /// /// The content store. @@ -20,7 +21,7 @@ namespace Umbraco.Web.Routing UmbracoContext umbracoContext, IEnumerable documentLookups, IDocumentLastChanceLookup documentLastChanceLookup, - ContentStore contentStore, + IContentStore contentStore, NiceUrlProvider niceUrlResolver) { this.UmbracoContext = umbracoContext; @@ -48,7 +49,7 @@ namespace Umbraco.Web.Routing /// /// Gets the content store. /// - internal ContentStore ContentStore { get; private set; } + internal IContentStore ContentStore { get; private set; } /// /// Gets the nice urls provider. diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 357d5dc0a6..40043c92ec 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -238,7 +238,8 @@ Properties\SolutionInfo.cs - + + diff --git a/src/Umbraco.Web/UmbracoModule.cs b/src/Umbraco.Web/UmbracoModule.cs index d2f42ed92c..006d765617 100644 --- a/src/Umbraco.Web/UmbracoModule.cs +++ b/src/Umbraco.Web/UmbracoModule.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; diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs index 3376a76ea2..4c223d62b8 100644 --- a/src/Umbraco.Web/WebBootManager.cs +++ b/src/Umbraco.Web/WebBootManager.cs @@ -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 diff --git a/src/Umbraco.Web/ContentStore.cs b/src/Umbraco.Web/XmlContentStore.cs similarity index 79% rename from src/Umbraco.Web/ContentStore.cs rename to src/Umbraco.Web/XmlContentStore.cs index e372c81b70..ba4bf0fb60 100644 --- a/src/Umbraco.Web/ContentStore.cs +++ b/src/Umbraco.Web/XmlContentStore.cs @@ -10,16 +10,11 @@ using umbraco.interfaces; namespace Umbraco.Web { - - /// - /// Used for the new routing system + /// + /// An IContentStore which uses the Xml cache system to return data /// - internal class ContentStore : IContentStore + internal class XmlContentStore : IContentStore { - /// - /// Delegate to return the current UmbracoContext - /// - private readonly UmbracoContext _umbracoContext; private IDocument ConvertToDocument(XmlNode xmlNode) { @@ -28,23 +23,13 @@ namespace Umbraco.Web return new Models.XmlDocument(xmlNode); } - - /// - /// Constructor accepting a delegate to resolve the UmbracoContext - /// - /// - 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[] { '/' };