From f2442b25f658230a5ac15666d0b17ad043d8cef4 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Fri, 1 Feb 2013 19:25:12 +0600 Subject: [PATCH 01/13] Close 4.11.4 branch From da7fea47c63c4e4408fe0080f44a4bcd5376e92c Mon Sep 17 00:00:00 2001 From: Stephan Date: Sun, 3 Feb 2013 14:34:04 -0100 Subject: [PATCH 02/13] U4-1441 - refactor (fix) legacy NotFoundHandler support --- .../Routing/DefaultLastChanceLookup.cs | 228 ------------------ .../Routing/LastChanceLookupResolver.cs | 10 +- src/Umbraco.Web/Routing/LookupByAlias.cs | 1 - src/Umbraco.Web/Routing/LookupByLegacy404.cs | 52 ++++ .../Routing/LookupByNotFoundHandlers.cs | 143 +++++++++++ .../Routing/NotFoundHandlerHelper.cs | 139 +++++++++++ src/Umbraco.Web/Umbraco.Web.csproj | 4 +- src/Umbraco.Web/WebBootManager.cs | 13 +- 8 files changed, 353 insertions(+), 237 deletions(-) delete mode 100644 src/Umbraco.Web/Routing/DefaultLastChanceLookup.cs create mode 100644 src/Umbraco.Web/Routing/LookupByLegacy404.cs create mode 100644 src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs create mode 100644 src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs diff --git a/src/Umbraco.Web/Routing/DefaultLastChanceLookup.cs b/src/Umbraco.Web/Routing/DefaultLastChanceLookup.cs deleted file mode 100644 index 674a6e64a4..0000000000 --- a/src/Umbraco.Web/Routing/DefaultLastChanceLookup.cs +++ /dev/null @@ -1,228 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Reflection; -using System.Web; -using System.Xml; -using Umbraco.Core.Logging; -using Umbraco.Core.Models; -using umbraco.IO; -using umbraco.interfaces; - -namespace Umbraco.Web.Routing -{ - /// - /// Provides an implementation of that handles backward compatilibty with legacy INotFoundHandler. - /// - internal class DefaultLastChanceLookup : IDocumentLastChanceLookup - { - // notes - // - // at the moment we load the legacy INotFoundHandler - // excluding those that have been replaced by proper lookups, - // and run them. - // - // when we finaly obsolete INotFoundHandler, we'll have to move - // over here code from legacy requestHandler.hande404, which - // basically uses umbraco.library.GetCurrentNotFoundPageId(); - // which also would need to be refactored / migrated here. - // - // the best way to do this would be to create a DefaultLastChanceLookup2 - // that would do everything by itself, and let ppl use it if they - // want, then make it the default one, then remove this one. - - /// - /// Tries to find and assign an Umbraco document to a PublishedContentRequest. - /// - /// The PublishedContentRequest. - /// A value indicating whether an Umbraco document was found and assigned. - public bool TrySetDocument(PublishedContentRequest docRequest) - { - docRequest.PublishedContent = HandlePageNotFound(docRequest); - return docRequest.HasNode; - } - - #region Copied over from presentation.requestHandler - - //FIXME: this is temporary and should be obsoleted - - string GetLegacyUrlForNotFoundHandlers(PublishedContentRequest docRequest) - { - // that's not backward-compatible because when requesting "/foo.aspx" - // 4.9 : url = "foo.aspx" - // 4.10 : url = "/foo" - //return docRequest.Uri.AbsolutePath; - - // so we have to run the legacy code for url preparation :-( - - // code from requestModule.UmbracoRewrite - string tmp = HttpContext.Current.Request.Path.ToLower(); - - // note: requestModule.UmbracoRewrite also does some confusing stuff - // with stripping &umbPage from the querystring?! ignored. - - // code from requestHandler.cleanUrl - string root = Umbraco.Core.IO.SystemDirectories.Root.ToLower(); - if (!string.IsNullOrEmpty(root) && tmp.StartsWith(root)) - tmp = tmp.Substring(root.Length); - tmp = tmp.TrimEnd('/'); - if (tmp == "/default.aspx") - tmp = string.Empty; - else if (tmp == root) - tmp = string.Empty; - - // code from UmbracoDefault.Page_PreInit - if (tmp != "" && HttpContext.Current.Request["umbPageID"] == null) - { - string tryIntParse = tmp.Replace("/", "").Replace(".aspx", string.Empty); - int result; - if (int.TryParse(tryIntParse, out result)) - tmp = tmp.Replace(".aspx", string.Empty); - } - else if (!string.IsNullOrEmpty(HttpContext.Current.Request["umbPageID"])) - { - int result; - if (int.TryParse(HttpContext.Current.Request["umbPageID"], out result)) - { - tmp = HttpContext.Current.Request["umbPageID"]; - } - } - - // code from requestHandler.ctor - if (tmp != "") - tmp = tmp.Substring(1); - - return tmp; - } - - IPublishedContent HandlePageNotFound(PublishedContentRequest docRequest) - { - LogHelper.Debug("Running for url='{0}'.", () => docRequest.Uri.AbsolutePath); - - //XmlNode currentPage = null; - IPublishedContent currentPage = null; - var url = GetLegacyUrlForNotFoundHandlers(docRequest); - - foreach (var handler in GetNotFoundHandlers()) - { - if (handler.Execute(url) && handler.redirectID > 0) - { - //currentPage = umbracoContent.GetElementById(handler.redirectID.ToString()); - currentPage = docRequest.RoutingContext.PublishedContentStore.GetDocumentById( - docRequest.RoutingContext.UmbracoContext, - handler.redirectID); - - // FIXME - could it be null? - - LogHelper.Debug("Handler '{0}' found node with id={1}.", () => handler.GetType().FullName, () => handler.redirectID); - - //// check for caching - //if (handler.CacheUrl) - //{ - // if (url.StartsWith("/")) - // url = "/" + url; - - // var cacheKey = (currentDomain == null ? "" : currentDomain.Name) + url; - // var culture = currentDomain == null ? null : currentDomain.Language.CultureAlias; - // SetCache(cacheKey, new CacheEntry(handler.redirectID.ToString(), culture)); - - // HttpContext.Current.Trace.Write("NotFoundHandler", - // string.Format("Added to cache '{0}', {1}.", url, handler.redirectID)); - //} - - break; - } - } - - return currentPage; - } - - static IEnumerable _customHandlerTypes = null; - static readonly object CustomHandlerTypesLock = new object(); - - IEnumerable InitializeNotFoundHandlers() - { - // initialize handlers - // create the definition cache - - LogHelper.Debug("Registering custom handlers."); - - var customHandlerTypes = new List(); - - var customHandlers = new XmlDocument(); - customHandlers.Load(Umbraco.Core.IO.IOHelper.MapPath(Umbraco.Core.IO.SystemFiles.NotFoundhandlersConfig)); - - foreach (XmlNode n in customHandlers.DocumentElement.SelectNodes("notFound")) - { - var assemblyName = n.Attributes.GetNamedItem("assembly").Value; - - var typeName = n.Attributes.GetNamedItem("type").Value; - string ns = assemblyName; - var nsAttr = n.Attributes.GetNamedItem("namespace"); - if (nsAttr != null && !string.IsNullOrWhiteSpace(nsAttr.Value)) - ns = nsAttr.Value; - - if (assemblyName == "umbraco" && (ns + "." + typeName) != "umbraco.handle404") - { - // skip those that are in umbraco.dll because we have replaced them with IDocumentLookups - // but do not skip "handle404" as that's the built-in legacy final handler, and for the time - // being people will have it in their config. - continue; - } - - LogHelper.Debug("Registering '{0}.{1},{2}'.", () => ns, () => typeName, () => assemblyName); - - Type type = null; - try - { - //TODO: This isn't a good way to load the assembly, its already in the Domain so we should be getting the type - // this loads the assembly into the wrong assembly load context!! - - var assembly = Assembly.LoadFrom(Umbraco.Core.IO.IOHelper.MapPath(Umbraco.Core.IO.SystemDirectories.Bin + "/" + assemblyName + ".dll")); - type = assembly.GetType(ns + "." + typeName); - } - catch (Exception e) - { - LogHelper.Error("Error registering handler, ignoring.", e); - } - - if (type != null) - customHandlerTypes.Add(type); - } - - return customHandlerTypes; - } - - IEnumerable GetNotFoundHandlers() - { - // instanciate new handlers - // using definition cache - - lock (CustomHandlerTypesLock) - { - if (_customHandlerTypes == null) - _customHandlerTypes = InitializeNotFoundHandlers(); - } - - var handlers = new List(); - - foreach (var type in _customHandlerTypes) - { - try - { - var handler = Activator.CreateInstance(type) as INotFoundHandler; - if (handler != null) - handlers.Add(handler); - } - catch (Exception e) - { - LogHelper.Error(string.Format("Error instanciating handler {0}, ignoring.", type.FullName), e); - } - } - - return handlers; - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/Routing/LastChanceLookupResolver.cs b/src/Umbraco.Web/Routing/LastChanceLookupResolver.cs index 0feadc8a4b..fc77661f95 100644 --- a/src/Umbraco.Web/Routing/LastChanceLookupResolver.cs +++ b/src/Umbraco.Web/Routing/LastChanceLookupResolver.cs @@ -8,9 +8,13 @@ namespace Umbraco.Web.Routing /// internal sealed class LastChanceLookupResolver : SingleObjectResolverBase { - - internal LastChanceLookupResolver(IDocumentLastChanceLookup lastChanceLookup) - : base(lastChanceLookup) + internal LastChanceLookupResolver() + : base(true) + { + } + + internal LastChanceLookupResolver(IDocumentLastChanceLookup lastChanceLookup) + : base(lastChanceLookup, true) { } diff --git a/src/Umbraco.Web/Routing/LookupByAlias.cs b/src/Umbraco.Web/Routing/LookupByAlias.cs index 0c0c023d23..530f12fcd6 100644 --- a/src/Umbraco.Web/Routing/LookupByAlias.cs +++ b/src/Umbraco.Web/Routing/LookupByAlias.cs @@ -24,7 +24,6 @@ namespace Umbraco.Web.Routing /// A value indicating whether an Umbraco document was found and assigned. public bool TrySetDocument(PublishedContentRequest docRequest) { - IPublishedContent node = null; if (docRequest.Uri.AbsolutePath != "/") // no alias if "/" diff --git a/src/Umbraco.Web/Routing/LookupByLegacy404.cs b/src/Umbraco.Web/Routing/LookupByLegacy404.cs new file mode 100644 index 0000000000..be73fa81c4 --- /dev/null +++ b/src/Umbraco.Web/Routing/LookupByLegacy404.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Umbraco.Core; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; + +namespace Umbraco.Web.Routing +{ + internal class LookupByLegacy404 : IPublishedContentLookup + { + /// + /// Tries to find and assign an Umbraco document to a PublishedContentRequest. + /// + /// The PublishedContentRequest. + /// A value indicating whether an Umbraco document was found and assigned. + public bool TrySetDocument(PublishedContentRequest pcr) + { + LogHelper.Debug("Looking for a page to handle 404."); + + // TODO - replace the whole logic and stop calling into library! + var error404 = global::umbraco.library.GetCurrentNotFoundPageId(); + var id = int.Parse(error404); + + IPublishedContent content = null; + + if (id > 0) + { + LogHelper.Debug("Got id={0}.", () => id); + + content = pcr.RoutingContext.PublishedContentStore.GetDocumentById( + pcr.RoutingContext.UmbracoContext, + id); + + if (content == null) + LogHelper.Debug("Could not find content with that id."); + else + LogHelper.Debug("Found corresponding content."); + } + else + { + LogHelper.Debug("Got nothing."); + } + + pcr.PublishedContent = content; + pcr.Is404 = true; + return content != null; + } + } +} diff --git a/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs b/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs new file mode 100644 index 0000000000..09ba92d506 --- /dev/null +++ b/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Reflection; +using System.Web; +using System.Xml; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; +using umbraco.IO; +using umbraco.interfaces; + +namespace Umbraco.Web.Routing +{ + /// + /// Provides an implementation of that handles backward compatilibty with legacy INotFoundHandler. + /// + internal class LookupByNotFoundHandlers : IPublishedContentLookup + { + // notes + // + // at the moment we load the legacy INotFoundHandler + // excluding those that have been replaced by proper finders, + // and run them. + + /// + /// Tries to find and assign an Umbraco document to a PublishedContentRequest. + /// + /// The PublishedContentRequest. + /// A value indicating whether an Umbraco document was found and assigned. + public bool TrySetDocument(PublishedContentRequest docRequest) + { + HandlePageNotFound(docRequest); + return docRequest.HasNode; + } + + #region Copied over and adapted from presentation.requestHandler + + //FIXME: this is temporary and should be obsoleted + + void HandlePageNotFound(PublishedContentRequest docRequest) + { + LogHelper.Debug("Running for url='{0}'.", () => docRequest.Uri.AbsolutePath); + + var url = NotFoundHandlerHelper.GetLegacyUrlForNotFoundHandlers(); + + foreach (var handler in GetNotFoundHandlers()) + { + IPublishedContentLookup lookup = null; + + LogHelper.Debug("Handler '{0}'.", () => handler.GetType().FullName); + + // replace with our own implementation + if (handler is global::umbraco.SearchForAlias) + lookup = new LookupByAlias(); + else if (handler is global::umbraco.SearchForProfile) + lookup = new LookupByProfile(); + else if (handler is global::umbraco.SearchForTemplate) + lookup = new LookupByNiceUrlAndTemplate(); + else if (handler is global::umbraco.handle404) + lookup = new LookupByLegacy404(); + + if (lookup != null) + { + LogHelper.Debug("Replace handler '{0}' by new lookup '{1}'.", () => handler.GetType().FullName, () => lookup.GetType().FullName); + if (lookup.TrySetDocument(docRequest)) + { + // do NOT set docRequest.PublishedContent again here as + // it would clear any template that the finder might have set + LogHelper.Debug("Lookup '{0}' found node with id={1}.", () => lookup.GetType().FullName, () => docRequest.PublishedContent.Id); + if (docRequest.Is404) + LogHelper.Debug("Lookup '{0}' set status to 404.", () => lookup.GetType().FullName); + return; + } + } + + // else it's a legacy handler, run + + if (handler.Execute(url) && handler.redirectID > 0) + { + docRequest.PublishedContent = docRequest.RoutingContext.PublishedContentStore.GetDocumentById( + docRequest.RoutingContext.UmbracoContext, + handler.redirectID); + + if (!docRequest.HasNode) + { + LogHelper.Debug("Handler '{0}' found node with id={1} which is not valid.", () => handler.GetType().FullName, () => handler.redirectID); + break; + } + + LogHelper.Debug("Handler '{0}' found valid node with id={1}.", () => handler.GetType().FullName, () => handler.redirectID); + + if (docRequest.RoutingContext.UmbracoContext.HttpContext.Response.StatusCode == 404) + { + LogHelper.Debug("Handler '{0}' set status code to 404.", () => handler.GetType().FullName); + docRequest.Is404 = true; + } + + //// check for caching + //if (handler.CacheUrl) + //{ + // if (url.StartsWith("/")) + // url = "/" + url; + + // var cacheKey = (currentDomain == null ? "" : currentDomain.Name) + url; + // var culture = currentDomain == null ? null : currentDomain.Language.CultureAlias; + // SetCache(cacheKey, new CacheEntry(handler.redirectID.ToString(), culture)); + + // HttpContext.Current.Trace.Write("NotFoundHandler", + // string.Format("Added to cache '{0}', {1}.", url, handler.redirectID)); + //} + + break; + } + } + } + + IEnumerable GetNotFoundHandlers() + { + // instanciate new handlers + // using definition cache + + var handlers = new List(); + + foreach (var type in NotFoundHandlerHelper.CustomHandlerTypes) + { + try + { + var handler = Activator.CreateInstance(type) as INotFoundHandler; + if (handler != null) + handlers.Add(handler); + } + catch (Exception e) + { + LogHelper.Error(string.Format("Error instanciating handler {0}, ignoring.", type.FullName), e); + } + } + + return handlers; + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs b/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs new file mode 100644 index 0000000000..595c8fd7c9 --- /dev/null +++ b/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; +using System.Xml; +using System.Reflection; + +using Umbraco.Core; +using Umbraco.Core.Logging; + +namespace Umbraco.Web.Routing +{ + // provides internal access to legacy url -- should get rid of it eventually + internal static class NotFoundHandlerHelper + { + const string ContextKey = "Umbraco.Web.Routing.NotFoundHandlerHelper.Url"; + + static NotFoundHandlerHelper() + { + InitializeNotFoundHandlers(); + } + + public static string GetLegacyUrlForNotFoundHandlers() + { + // that's not backward-compatible because when requesting "/foo.aspx" + // 4.9 : url = "foo.aspx" + // 4.10 : url = "/foo" + //return pcr.Uri.AbsolutePath; + + // so we have to run the legacy code for url preparation :-( + + var httpContext = HttpContext.Current; + + if (httpContext == null) + return ""; + + var url = httpContext.Items[ContextKey] as string; + if (url != null) + return url; + + // code from requestModule.UmbracoRewrite + string tmp = httpContext.Request.Path.ToLower(); + + // note: requestModule.UmbracoRewrite also did some stripping of &umbPage + // from the querystring... that was in v3.x to fix some issues with pre-forms + // auth. Paul Sterling confirmed in jan. 2013 that we can get rid of it. + + // code from requestHandler.cleanUrl + string root = Umbraco.Core.IO.SystemDirectories.Root.ToLower(); + if (!string.IsNullOrEmpty(root) && tmp.StartsWith(root)) + tmp = tmp.Substring(root.Length); + tmp = tmp.TrimEnd('/'); + if (tmp == "/default.aspx") + tmp = string.Empty; + else if (tmp == root) + tmp = string.Empty; + + // code from UmbracoDefault.Page_PreInit + if (tmp != "" && httpContext.Request["umbPageID"] == null) + { + string tryIntParse = tmp.Replace("/", "").Replace(".aspx", string.Empty); + int result; + if (int.TryParse(tryIntParse, out result)) + tmp = tmp.Replace(".aspx", string.Empty); + } + else if (!string.IsNullOrEmpty(httpContext.Request["umbPageID"])) + { + int result; + if (int.TryParse(httpContext.Request["umbPageID"], out result)) + { + tmp = httpContext.Request["umbPageID"]; + } + } + + // code from requestHandler.ctor + if (tmp != "") + tmp = tmp.Substring(1); + + httpContext.Items[ContextKey] = tmp; + return tmp; + } + + static IEnumerable _customHandlerTypes = null; + + static void InitializeNotFoundHandlers() + { + // initialize handlers + // create the definition cache + + LogHelper.Debug("Registering custom handlers."); + + var customHandlerTypes = new List(); + + var customHandlers = new XmlDocument(); + customHandlers.Load(Umbraco.Core.IO.IOHelper.MapPath(Umbraco.Core.IO.SystemFiles.NotFoundhandlersConfig)); + + foreach (XmlNode n in customHandlers.DocumentElement.SelectNodes("notFound")) + { + var assemblyName = n.Attributes.GetNamedItem("assembly").Value; + var typeName = n.Attributes.GetNamedItem("type").Value; + + string ns = assemblyName; + var nsAttr = n.Attributes.GetNamedItem("namespace"); + if (nsAttr != null && !string.IsNullOrWhiteSpace(nsAttr.Value)) + ns = nsAttr.Value; + + LogHelper.Debug("Registering '{0}.{1},{2}'.", () => ns, () => typeName, () => assemblyName); + + Type type = null; + try + { + //TODO: This isn't a good way to load the assembly, its already in the Domain so we should be getting the type + // this loads the assembly into the wrong assembly load context!! + + var assembly = Assembly.LoadFrom(Umbraco.Core.IO.IOHelper.MapPath(Umbraco.Core.IO.SystemDirectories.Bin + "/" + assemblyName + ".dll")); + type = assembly.GetType(ns + "." + typeName); + } + catch (Exception e) + { + LogHelper.Error("Error registering handler, ignoring.", e); + } + + if (type != null) + customHandlerTypes.Add(type); + } + + _customHandlerTypes = customHandlerTypes; + } + + public static IEnumerable CustomHandlerTypes + { + get + { + return _customHandlerTypes; + } + } + } +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 0a275a4e38..051977688a 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -315,8 +315,10 @@ + + @@ -398,7 +400,7 @@ - + diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs index b4aed9339d..a6ead39ab5 100644 --- a/src/Umbraco.Web/WebBootManager.cs +++ b/src/Umbraco.Web/WebBootManager.cs @@ -221,7 +221,9 @@ namespace Umbraco.Web typeof (RenderControllerFactory) }); - LastChanceLookupResolver.Current = new LastChanceLookupResolver(new DefaultLastChanceLookup()); + // the legacy 404 will run from within LookupByNotFoundHandlers below + // so for the time being there is no last chance lookup + LastChanceLookupResolver.Current = new LastChanceLookupResolver(); DocumentLookupsResolver.Current = new DocumentLookupsResolver( //add all known resolvers in the correct order, devs can then modify this list on application startup either by binding to events @@ -231,9 +233,12 @@ namespace Umbraco.Web typeof (LookupByPageIdQuery), typeof (LookupByNiceUrl), typeof (LookupByIdPath), - typeof (LookupByNiceUrlAndTemplate), - typeof (LookupByProfile), - typeof (LookupByAlias) + // these will be handled by LookupByNotFoundHandlers + // so they can be enabled/disabled even though resolvers are not public yet + //typeof (LookupByNiceUrlAndTemplate), + //typeof (LookupByProfile), + //typeof (LookupByAlias), + typeof (LookupByNotFoundHandlers) }); RoutesCacheResolver.Current = new RoutesCacheResolver(new DefaultRoutesCache(_isForTesting == false)); From 8d06d39a629a0d3ad2caaf2e0b4f2983e22386dc Mon Sep 17 00:00:00 2001 From: Stephan Date: Mon, 4 Feb 2013 11:59:30 -0100 Subject: [PATCH 03/13] Create branch for 4.11.5 From 3e1120612b087bb3327767c4fdfc9c2cdc4dae97 Mon Sep 17 00:00:00 2001 From: Stephan Date: Mon, 4 Feb 2013 12:00:58 -0100 Subject: [PATCH 04/13] Update version number --- src/Umbraco.Core/Configuration/GlobalSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Configuration/GlobalSettings.cs b/src/Umbraco.Core/Configuration/GlobalSettings.cs index 7086b67c7a..67eefd07a2 100644 --- a/src/Umbraco.Core/Configuration/GlobalSettings.cs +++ b/src/Umbraco.Core/Configuration/GlobalSettings.cs @@ -28,7 +28,7 @@ namespace Umbraco.Core.Configuration #region Private static fields // CURRENT UMBRACO VERSION ID - private const string CurrentUmbracoVersion = "4.11.4"; + private const string CurrentUmbracoVersion = "4.11.5"; private static string _reservedUrlsCache; private static string _reservedPathsCache; From a65ca205de745ab16c4c11d201a39fbc4e378c4e Mon Sep 17 00:00:00 2001 From: Stephan Date: Tue, 5 Feb 2013 16:29:10 -0100 Subject: [PATCH 05/13] U4-1441 - fix issue with IIS taking over custom errors --- src/Umbraco.Web/Routing/PublishedContentRequest.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Umbraco.Web/Routing/PublishedContentRequest.cs b/src/Umbraco.Web/Routing/PublishedContentRequest.cs index 093b942a33..62bc7d8f9b 100644 --- a/src/Umbraco.Web/Routing/PublishedContentRequest.cs +++ b/src/Umbraco.Web/Routing/PublishedContentRequest.cs @@ -77,6 +77,7 @@ namespace Umbraco.Web.Routing if (this.Is404) { httpContext.Response.StatusCode = 404; + httpContext.Response.TrySkipIisCustomErrors = true; if (!this.HasNode) { @@ -135,6 +136,7 @@ namespace Umbraco.Web.Routing // here .Is404 _has_ to be true httpContext.Response.StatusCode = 404; + httpContext.Response.TrySkipIisCustomErrors = true; if (!this.HasNode) { From 3ebb21391608cbb0936a4806e6ee3b65b206c1d7 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Wed, 6 Feb 2013 19:18:42 +0600 Subject: [PATCH 06/13] Patches installer issue. --- .../umbraco.presentation/install/utills/p.aspx.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Umbraco.Web/umbraco.presentation/install/utills/p.aspx.cs b/src/Umbraco.Web/umbraco.presentation/install/utills/p.aspx.cs index d7c99e7f47..8f27a85dd7 100644 --- a/src/Umbraco.Web/umbraco.presentation/install/utills/p.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/install/utills/p.aspx.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Security.Authentication; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; +using Umbraco.Core; using umbraco.DataLayer.Utility.Installer; using umbraco.DataLayer; @@ -57,6 +59,12 @@ namespace umbraco.presentation.install.utills [System.Web.Script.Services.ScriptMethod] public static string installOrUpgrade() { + //if its not configured then we can continue + if (ApplicationContext.Current == null || ApplicationContext.Current.IsConfigured) + { + throw new AuthenticationException("The application is already configured"); + } + Helper.setProgress(5, "Opening database connection...", ""); IInstallerUtility installer; From f1b31052025466e1b3b0e99f7a647cc4a62b17db Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Wed, 6 Feb 2013 20:56:47 +0600 Subject: [PATCH 07/13] Patch for #U4-1653 - media library cache refresh issue --- .../web.Template.ShandemVaio.Debug.config | 4 +- .../LibraryCacheRefresher.cs | 39 +++++++++---------- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/Umbraco.Web.UI/web.Template.ShandemVaio.Debug.config b/src/Umbraco.Web.UI/web.Template.ShandemVaio.Debug.config index 30a793e0e0..381d69a4be 100644 --- a/src/Umbraco.Web.UI/web.Template.ShandemVaio.Debug.config +++ b/src/Umbraco.Web.UI/web.Template.ShandemVaio.Debug.config @@ -17,9 +17,7 @@ - + value="server=.\sqlexpress;database=v4;user id=sa;password=test;Application Name=Umbraco41"/> 0) { - Member.AfterSave += new Member.SaveEventHandler(Member_AfterSave); - Member.BeforeDelete += new Member.DeleteEventHandler(Member_BeforeDelete); - Media.AfterSave += new Media.SaveEventHandler(Media_AfterSave); - Media.BeforeDelete += new Media.DeleteEventHandler(Media_BeforeDelete); + Member.AfterSave += MemberAfterSave; + Member.BeforeDelete += MemberBeforeDelete; + Media.AfterSave += MediaAfterSave; + Media.BeforeDelete += MediaBeforeDelete; + //we need to do this before the move so that we still have the item's current path + //in order to invalidate the media cache. Pretty sure this was why the BeforeDelete was + //occuring as well which must have been before we had a recycle bin for media. + //see : http://issues.umbraco.org/issue/U4-1653 + CMSNode.BeforeMove += MediaBeforeMove; } - - // now handled directly by the IRoutesCache implementation - //content.AfterUpdateDocumentCache += new content.DocumentCacheEventHandler(content_AfterUpdateDocumentCache); - //content.AfterRefreshContent += new content.RefreshContentEventHandler(content_AfterRefreshContent); } - //void content_AfterRefreshContent(Document sender, RefreshContentEventArgs e) - //{ - // library.ClearNiceUrlCache(); - //} + static void MediaBeforeMove(object sender, MoveEventArgs e) + { + if (!(sender is Media)) + return; - //void content_AfterUpdateDocumentCache(Document sender, DocumentCacheEventArgs e) - //{ - // library.ClearNiceUrlCache(); - //} + library.ClearLibraryCacheForMedia(((Media) sender).Id); + } - void Member_BeforeDelete(Member sender, DeleteEventArgs e) + static void MemberBeforeDelete(Member sender, DeleteEventArgs e) { library.ClearLibraryCacheForMember(sender.Id); } - void Media_BeforeDelete(Media sender, DeleteEventArgs e) + static void MediaBeforeDelete(Media sender, DeleteEventArgs e) { library.ClearLibraryCacheForMedia(sender.Id); } - void Media_AfterSave(Media sender, SaveEventArgs e) + static void MediaAfterSave(Media sender, SaveEventArgs e) { library.ClearLibraryCacheForMedia(sender.Id); } - void Member_AfterSave(Member sender, SaveEventArgs e) + static void MemberAfterSave(Member sender, SaveEventArgs e) { library.ClearLibraryCacheForMember(sender.Id); } From 9cedf5da4c987e50a254e762967024b62001dc8d Mon Sep 17 00:00:00 2001 From: Stephan Date: Fri, 8 Feb 2013 08:08:36 -0100 Subject: [PATCH 08/13] U4-1441 - make trySkipIisCustomError value a setting --- .../Configuration/UmbracoSettings.cs | 166 ++++++++---------- .../config/umbracoSettings.Release.config | 9 + .../config/umbracoSettings.config | 9 + .../Routing/PublishedContentRequest.cs | 4 +- 4 files changed, 93 insertions(+), 95 deletions(-) diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings.cs b/src/Umbraco.Core/Configuration/UmbracoSettings.cs index beab6537b3..a3bba29984 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings.cs @@ -25,7 +25,37 @@ namespace Umbraco.Core.Configuration /// internal class UmbracoSettings { - /// + private static bool GetKeyWithOverride(string key, bool defaultValue, bool? overrideValue) + { + if (overrideValue.HasValue) + return overrideValue.Value; + + bool value; + string stringValue = GetKey(key); + + if (string.IsNullOrWhiteSpace(stringValue)) + return defaultValue; + if (bool.TryParse(stringValue, out value)) + return value; + return defaultValue; + } + + private static int GetKeyWithOverride(string key, int defaultValue, int? overrideValue) + { + if (overrideValue.HasValue) + return overrideValue.Value; + + int value; + string stringValue = GetKey(key); + + if (string.IsNullOrWhiteSpace(stringValue)) + return defaultValue; + if (int.TryParse(stringValue, out value)) + return value; + return defaultValue; + } + + /// /// Used in unit testing to reset all config items that were set with property setters (i.e. did not come from config) /// internal static void ResetSetters() @@ -35,6 +65,7 @@ namespace Umbraco.Core.Configuration _useLegacySchema = null; _useDomainPrefixes = null; _umbracoLibraryCacheDuration = null; + _trySkipIisCustomErrors = null; } internal const string TempFriendlyXmlChildContainerNodename = ""; // "children"; @@ -202,6 +233,7 @@ namespace Umbraco.Core.Configuration return value != null ? value.Attributes["assembly"].Value : ""; } } + /// /// Gets the type of an external logger that can be used to store log items in 3rd party systems /// @@ -350,24 +382,13 @@ namespace Umbraco.Core.Configuration { get { - try - { - if (_useDomainPrefixes.HasValue) - return _useDomainPrefixes.Value; - bool result; - if (bool.TryParse(GetKey("/settings/requestHandler/useDomainPrefixes"), out result)) - return result; - return false; - } - catch - { - return false; - } + // default: false + return GetKeyWithOverride("/settings/requestHandler/useDomainPrefixes", false, _useDomainPrefixes); } - // for unit tests only internal set { - _useDomainPrefixes = value; + // for unit tests only + _useDomainPrefixes = value; } } @@ -381,31 +402,14 @@ namespace Umbraco.Core.Configuration { get { - try - { - if (GlobalSettings.UseDirectoryUrls) - { - if (_addTrailingSlash.HasValue) - return _addTrailingSlash.Value; - bool result; - if (bool.TryParse(GetKey("/settings/requestHandler/addTrailingSlash"), out result)) - return result; - return false; - } - else - { - return false; - } - } - catch - { - return false; - } + // default: false + return GlobalSettings.UseDirectoryUrls + && GetKeyWithOverride("/settings/requestHandler/addTrailingSlash", false, _addTrailingSlash); } - // for unit tests only internal set { - _addTrailingSlash = value; + // for unit tests only + _addTrailingSlash = value; } } @@ -622,31 +626,34 @@ namespace Umbraco.Core.Configuration { get { - if (_forceSafeAliases.HasValue) - return _forceSafeAliases.Value; - - string forceSafeAlias = GetKey("/settings/content/ForceSafeAliases"); - if (String.IsNullOrEmpty(forceSafeAlias)) - return true; - else - { - try - { - return bool.Parse(forceSafeAlias); - } - catch - { - return true; - } - } + // default: true + return GetKeyWithOverride("/settings/content/ForceSafeAliases", true, _forceSafeAliases); } internal set { - //used for unit testing + // used for unit testing _forceSafeAliases = value; } } + private static bool? _trySkipIisCustomErrors; + + /// + /// Gets or sets a value indicating where to try to skip IIS custom errors. + /// + public static bool TrySkipIisCustomErrors + { + get + { + // default: false + return GetKeyWithOverride("/settings/TrySkipIisCustomErrors", false, _trySkipIisCustomErrors); + } + internal set + { + // used for unit testing + _trySkipIisCustomErrors = value; + } + } /// /// Gets the allowed image file types. @@ -676,26 +683,14 @@ namespace Umbraco.Core.Configuration { get { - if (_umbracoLibraryCacheDuration.HasValue) - return _umbracoLibraryCacheDuration.Value; - - string libraryCacheDuration = GetKey("/settings/content/UmbracoLibraryCacheDuration"); - if (String.IsNullOrEmpty(libraryCacheDuration)) - return 1800; - else - { - try - { - return int.Parse(libraryCacheDuration); - } - catch - { - return 1800; - } - } - + // default: 1800 + return GetKeyWithOverride("/settings/content/UmbracoLibraryCacheDuration", 1800, _umbracoLibraryCacheDuration); } - internal set { _umbracoLibraryCacheDuration = value; } + internal set + { + // for unit tests only + _umbracoLibraryCacheDuration = value; + } } /// @@ -1051,27 +1046,12 @@ namespace Umbraco.Core.Configuration { get { - try - { - if (_useLegacySchema.HasValue) - return _useLegacySchema.Value; - - string value = GetKey("/settings/content/UseLegacyXmlSchema"); - bool result; - if (!string.IsNullOrEmpty(value) && bool.TryParse(value, out result)) - return result; - return true; - } - catch (Exception) - { - //default. TODO: When we change this to a real config section we won't have to worry about parse errors - // and should handle defaults with unit tests properly. - return false; - } + // default: true + return GetKeyWithOverride("/settings/content/UseLegacyXmlSchema", true, _useLegacySchema); } internal set { - //used for unit testing + // used for unit testing _useLegacySchema = value; } } diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.Release.config b/src/Umbraco.Web.UI/config/umbracoSettings.Release.config index d70b455d11..9c0978693b 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.Release.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.Release.config @@ -236,4 +236,13 @@ + + false + diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.config b/src/Umbraco.Web.UI/config/umbracoSettings.config index 372777126a..10764d0526 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.config @@ -192,4 +192,13 @@ + + false + \ No newline at end of file diff --git a/src/Umbraco.Web/Routing/PublishedContentRequest.cs b/src/Umbraco.Web/Routing/PublishedContentRequest.cs index 62bc7d8f9b..32ea063fe9 100644 --- a/src/Umbraco.Web/Routing/PublishedContentRequest.cs +++ b/src/Umbraco.Web/Routing/PublishedContentRequest.cs @@ -77,7 +77,7 @@ namespace Umbraco.Web.Routing if (this.Is404) { httpContext.Response.StatusCode = 404; - httpContext.Response.TrySkipIisCustomErrors = true; + httpContext.Response.TrySkipIisCustomErrors = Umbraco.Core.Configuration.UmbracoSettings.TrySkipIisCustomErrors; if (!this.HasNode) { @@ -136,7 +136,7 @@ namespace Umbraco.Web.Routing // here .Is404 _has_ to be true httpContext.Response.StatusCode = 404; - httpContext.Response.TrySkipIisCustomErrors = true; + httpContext.Response.TrySkipIisCustomErrors = Umbraco.Core.Configuration.UmbracoSettings.TrySkipIisCustomErrors; if (!this.HasNode) { From 9af9c3fe774b66d80109efa66056d9ecb97f4f82 Mon Sep 17 00:00:00 2001 From: Stephan Date: Fri, 8 Feb 2013 07:36:35 -0100 Subject: [PATCH 09/13] U4-1441 - change trySkipIisCustomError config key --- .../Configuration/UmbracoSettings.cs | 31 ++++++++++++++++--- .../config/umbracoSettings.Release.config | 16 ++++++---- .../config/umbracoSettings.config | 16 ++++++---- 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings.cs b/src/Umbraco.Core/Configuration/UmbracoSettings.cs index a3bba29984..554f8c7e19 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings.cs @@ -156,11 +156,32 @@ namespace Umbraco.Core.Configuration { EnsureSettingsDocument(); + string attrName = null; + var pos = key.IndexOf('@'); + if (pos > 0) + { + attrName = key.Substring(pos + 1); + key = key.Substring(0, pos - 1); + } + var node = UmbracoSettingsXmlDoc.DocumentElement.SelectSingleNode(key); - if (node == null || node.FirstChild == null || node.FirstChild.Value == null) - return string.Empty; - return node.FirstChild.Value; - } + if (node == null) + return string.Empty; + + if (pos < 0) + { + if (node.FirstChild == null || node.FirstChild.Value == null) + return string.Empty; + return node.FirstChild.Value; + } + else + { + var attr = node.Attributes[attrName]; + if (attr == null) + return string.Empty; + return attr.Value; + } + } /// /// Gets a value indicating whether the media library will create new directories in the /media directory. @@ -646,7 +667,7 @@ namespace Umbraco.Core.Configuration get { // default: false - return GetKeyWithOverride("/settings/TrySkipIisCustomErrors", false, _trySkipIisCustomErrors); + return GetKeyWithOverride("/settings/web.routing/@trySkipIisCustomErrors", false, _trySkipIisCustomErrors); } internal set { diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.Release.config b/src/Umbraco.Web.UI/config/umbracoSettings.Release.config index 9c0978693b..5144e8bfac 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.Release.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.Release.config @@ -237,12 +237,16 @@ - false + + diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.config b/src/Umbraco.Web.UI/config/umbracoSettings.config index 10764d0526..1fafe2f61b 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.config @@ -193,12 +193,16 @@ - false + + \ No newline at end of file From 6d87174cc1a94f45a491ce5bc654d12c7e107da9 Mon Sep 17 00:00:00 2001 From: Stephan Date: Fri, 8 Feb 2013 07:54:16 -0100 Subject: [PATCH 10/13] U4-1441 - improve logging --- src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs b/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs index 09ba92d506..311efcbcc3 100644 --- a/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs +++ b/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs @@ -39,9 +39,8 @@ namespace Umbraco.Web.Routing void HandlePageNotFound(PublishedContentRequest docRequest) { - LogHelper.Debug("Running for url='{0}'.", () => docRequest.Uri.AbsolutePath); - var url = NotFoundHandlerHelper.GetLegacyUrlForNotFoundHandlers(); + LogHelper.Debug("Running for legacy url='{0}'.", () => url); foreach (var handler in GetNotFoundHandlers()) { From 598d66ac7f6f99fc249df361b10920b377703096 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Thu, 14 Feb 2013 23:14:43 +0600 Subject: [PATCH 11/13] Imports patch to fix: #U4-1718 --- src/Umbraco.Core/CoreBootManager.cs | 23 ++++++---- .../ApplicationEventsResolver.cs | 46 +++++++++++++++++-- .../BootManagers/CoreBootManagerTests.cs | 46 +++++++++++++++++-- 3 files changed, 97 insertions(+), 18 deletions(-) diff --git a/src/Umbraco.Core/CoreBootManager.cs b/src/Umbraco.Core/CoreBootManager.cs index 9443a8abce..534c523e15 100644 --- a/src/Umbraco.Core/CoreBootManager.cs +++ b/src/Umbraco.Core/CoreBootManager.cs @@ -110,15 +110,15 @@ namespace Umbraco.Core if (_isStarted) throw new InvalidOperationException("The boot manager has already been initialized"); - if (afterStartup != null) - { - afterStartup(ApplicationContext.Current); - } - //call OnApplicationStarting of each application events handler ApplicationEventsResolver.Current.ApplicationEventHandlers .ForEach(x => x.OnApplicationStarting(UmbracoApplication, ApplicationContext)); + if (afterStartup != null) + { + afterStartup(ApplicationContext.Current); + } + _isStarted = true; return this; @@ -140,15 +140,18 @@ namespace Umbraco.Core //stop the timer and log the output _timer.Dispose(); - if (afterComplete != null) - { - afterComplete(ApplicationContext.Current); - } - //call OnApplicationStarting of each application events handler ApplicationEventsResolver.Current.ApplicationEventHandlers .ForEach(x => x.OnApplicationStarted(UmbracoApplication, ApplicationContext)); + //Now, startup all of our legacy startup handler + ApplicationEventsResolver.Current.InstantiateLegacyStartupHanlders(); + + if (afterComplete != null) + { + afterComplete(ApplicationContext.Current); + } + _isComplete = true; // we're ready to serve content! diff --git a/src/Umbraco.Core/ObjectResolution/ApplicationEventsResolver.cs b/src/Umbraco.Core/ObjectResolution/ApplicationEventsResolver.cs index 7f5b6f6365..c706740861 100644 --- a/src/Umbraco.Core/ObjectResolution/ApplicationEventsResolver.cs +++ b/src/Umbraco.Core/ObjectResolution/ApplicationEventsResolver.cs @@ -8,27 +8,49 @@ namespace Umbraco.Core.ObjectResolution /// /// A resolver to return all IApplicationEvents objects /// - internal sealed class ApplicationEventsResolver : ManyObjectsResolverBase + internal sealed class ApplicationEventsResolver : ManyObjectsResolverBase { - /// + private readonly LegacyStartupHandlerResolver _legacyResolver; + + /// /// Constructor /// /// internal ApplicationEventsResolver(IEnumerable applicationEventHandlers) : base(applicationEventHandlers) { - + //create the legacy resolver and only include the legacy types + _legacyResolver = new LegacyStartupHandlerResolver( + applicationEventHandlers.Where(x => !TypeHelper.IsTypeAssignableFrom(x))); } - /// + /// + /// Override in order to only return types of IApplicationEventHandler and above, + /// do not include the legacy types of IApplicationStartupHandler + /// + protected override IEnumerable InstanceTypes + { + get { return base.InstanceTypes.Where(TypeHelper.IsTypeAssignableFrom); } + } + + /// /// Gets the implementations. /// public IEnumerable ApplicationEventHandlers { - get { return Values.OfType(); } + get { return Values; } } + /// + /// Create instances of all of the legacy startup handlers + /// + public void InstantiateLegacyStartupHanlders() + { + //this will instantiate them all + var handlers = _legacyResolver.LegacyStartupHandlers; + } + protected override bool SupportsClear { get { return false; } @@ -44,5 +66,19 @@ namespace Umbraco.Core.ObjectResolution get { return false; } } + private class LegacyStartupHandlerResolver : ManyObjectsResolverBase + { + internal LegacyStartupHandlerResolver(IEnumerable legacyStartupHandlers) + : base(legacyStartupHandlers) + { + + } + + public IEnumerable LegacyStartupHandlers + { + get { return Values; } + } + } + } } \ No newline at end of file diff --git a/src/Umbraco.Tests/BootManagers/CoreBootManagerTests.cs b/src/Umbraco.Tests/BootManagers/CoreBootManagerTests.cs index 067c30aeb3..0227e68908 100644 --- a/src/Umbraco.Tests/BootManagers/CoreBootManagerTests.cs +++ b/src/Umbraco.Tests/BootManagers/CoreBootManagerTests.cs @@ -6,6 +6,7 @@ using System.Web; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.ObjectResolution; +using umbraco.interfaces; namespace Umbraco.Tests.BootManagers { @@ -53,12 +54,14 @@ namespace Umbraco.Tests.BootManagers protected override void InitializeApplicationEventsResolver() { //create an empty resolver so we can add our own custom ones (don't type find) - ApplicationEventsResolver.Current = new ApplicationEventsResolver( - Enumerable.Empty()) + ApplicationEventsResolver.Current = new ApplicationEventsResolver(new Type[] + { + typeof(LegacyStartupHandler), + typeof(TestApplicationEventHandler) + }) { CanResolveBeforeFrozen = true }; - ApplicationEventsResolver.Current.AddType(); } protected override void InitializeResolvers() @@ -67,6 +70,19 @@ namespace Umbraco.Tests.BootManagers } } + /// + /// Test legacy startup handler + /// + public class LegacyStartupHandler : IApplicationStartupHandler + { + public static bool Initialized = false; + + public LegacyStartupHandler() + { + Initialized = true; + } + } + /// /// test event handler /// @@ -102,5 +118,29 @@ namespace Umbraco.Tests.BootManagers Assert.IsTrue(TestApplicationEventHandler.Started); } + [Test] + public void Ensure_Legacy_Startup_Handlers_Not_Started_Until_Complete() + { + EventHandler starting = (sender, args) => + { + Assert.IsTrue(TestApplicationEventHandler.Initialized); + Assert.IsTrue(TestApplicationEventHandler.Starting); + Assert.IsFalse(LegacyStartupHandler.Initialized); + }; + EventHandler started = (sender, args) => + { + Assert.IsTrue(TestApplicationEventHandler.Started); + Assert.IsTrue(LegacyStartupHandler.Initialized); + }; + TestApp.ApplicationStarting += starting; + TestApp.ApplicationStarted += started; + + _testApp.StartApplication(_testApp, new EventArgs()); + + TestApp.ApplicationStarting -= starting; + TestApp.ApplicationStarting -= started; + + } + } } From ef86d2f1f1f3c7c88674267649b675d4de33de0f Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Thu, 14 Feb 2013 23:26:29 +0600 Subject: [PATCH 12/13] Manually applies patch for #U4-1718 --- src/Umbraco.Web/ApplicationEventsResolver.cs | 103 +++++++++++++------ src/Umbraco.Web/WebBootManager.cs | 3 + 2 files changed, 73 insertions(+), 33 deletions(-) diff --git a/src/Umbraco.Web/ApplicationEventsResolver.cs b/src/Umbraco.Web/ApplicationEventsResolver.cs index 93edaae441..1478ef6cbf 100644 --- a/src/Umbraco.Web/ApplicationEventsResolver.cs +++ b/src/Umbraco.Web/ApplicationEventsResolver.cs @@ -1,49 +1,86 @@ using System; using System.Collections.Generic; using System.Linq; +using Umbraco.Core; using Umbraco.Core.ObjectResolution; using umbraco.interfaces; namespace Umbraco.Web { - /// - /// A resolver to return all IApplicationEvents objects - /// - internal sealed class ApplicationEventsResolver : ManyObjectsResolverBase - { + /// + /// A resolver to return all IApplicationEvents objects + /// + internal sealed class ApplicationEventsResolver : ManyObjectsResolverBase + { - /// - /// Constructor - /// - /// - internal ApplicationEventsResolver(IEnumerable applicationEventHandlers) - : base(applicationEventHandlers) - { + private readonly LegacyStartupHandlerResolver _legacyResolver; - } + /// + /// Constructor + /// + /// + internal ApplicationEventsResolver(IEnumerable applicationEventHandlers) + : base(applicationEventHandlers) + { + //create the legacy resolver and only include the legacy types + _legacyResolver = new LegacyStartupHandlerResolver( + applicationEventHandlers.Where(x => !TypeHelper.IsTypeAssignableFrom(x))); + } - /// - /// Gets the implementations. - /// - public IEnumerable ApplicationEventHandlers - { - get { return Values.OfType(); } - } + /// + /// Override in order to only return types of IApplicationEventHandler and above, + /// do not include the legacy types of IApplicationStartupHandler + /// + protected override IEnumerable InstanceTypes + { + get { return base.InstanceTypes.Where(TypeHelper.IsTypeAssignableFrom); } + } - protected override bool SupportsClear - { - get { return false; } - } + /// + /// Gets the implementations. + /// + public IEnumerable ApplicationEventHandlers + { + get { return Values; } + } - protected override bool SupportsInsert - { - get { return false; } - } + /// + /// Create instances of all of the legacy startup handlers + /// + public void InstantiateLegacyStartupHanlders() + { + //this will instantiate them all + var handlers = _legacyResolver.LegacyStartupHandlers; + } - protected override bool SupportsRemove - { - get { return false; } - } + protected override bool SupportsClear + { + get { return false; } + } - } + protected override bool SupportsInsert + { + get { return false; } + } + + protected override bool SupportsRemove + { + get { return false; } + } + + private class LegacyStartupHandlerResolver : ManyObjectsResolverBase + { + internal LegacyStartupHandlerResolver(IEnumerable legacyStartupHandlers) + : base(legacyStartupHandlers) + { + + } + + public IEnumerable LegacyStartupHandlers + { + get { return Values; } + } + } + + } } \ No newline at end of file diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs index a6ead39ab5..6edccc967f 100644 --- a/src/Umbraco.Web/WebBootManager.cs +++ b/src/Umbraco.Web/WebBootManager.cs @@ -130,6 +130,9 @@ namespace Umbraco.Web ApplicationEventsResolver.Current.ApplicationEventHandlers .ForEach(x => x.OnApplicationStarted(_umbracoApplication, ApplicationContext)); + //Now, startup all of our legacy startup handler + ApplicationEventsResolver.Current.InstantiateLegacyStartupHanlders(); + // we're ready to serve content! ApplicationContext.IsReady = true; From dfb2a31f26a51636d8931e54f74f08f6334d5c31 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Thu, 14 Feb 2013 23:29:11 +0600 Subject: [PATCH 13/13] Fixes up examine config for internal indexes: #U4-1710 --- .../config/ExamineIndex.Release.config | 32 ++-------------- src/Umbraco.Web.UI/config/ExamineIndex.config | 37 +++---------------- 2 files changed, 8 insertions(+), 61 deletions(-) diff --git a/src/Umbraco.Web.UI/config/ExamineIndex.Release.config b/src/Umbraco.Web.UI/config/ExamineIndex.Release.config index ce180cd9c2..2db20e00f9 100644 --- a/src/Umbraco.Web.UI/config/ExamineIndex.Release.config +++ b/src/Umbraco.Web.UI/config/ExamineIndex.Release.config @@ -8,37 +8,11 @@ More information and documentation can be found on CodePlex: http://umbracoexami --> - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/src/Umbraco.Web.UI/config/ExamineIndex.config b/src/Umbraco.Web.UI/config/ExamineIndex.config index c9d2eece88..9b0e81c3f4 100644 --- a/src/Umbraco.Web.UI/config/ExamineIndex.config +++ b/src/Umbraco.Web.UI/config/ExamineIndex.config @@ -7,36 +7,9 @@ Index/Search providers can be defined in the UmbracoSettings.config More information and documentation can be found on CodePlex: http://umbracoexamine.codeplex.com --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + \ No newline at end of file