/// <summary> /// Register the editor controllers /// </summary> /// <param name="builder"></param> /// <param name="typeFinder"></param> public virtual void RegisterEditorControllers(IContainerBuilder builder, TypeFinder typeFinder) { if (_editorControllersRegistered) { return; } using (DisposableTimer.Start(timer => { LogHelper.TraceIfEnabled <UmbracoComponentRegistrar>("RegisterEditorControllers start took {0}ms", () => timer); _editorControllersRegistered = true; })) { //now register each type in the container and also add it to our collection foreach (var t in FindTypesInRequiredAssemblies <AbstractEditorController>(typeFinder)) { var editorType = t; RegisterComponent <AbstractEditorController, EditorAttribute, EditorMetadata>( t, builder, true, (pluginDef, attribute, registrar) => registrar .WithMetadata <EditorMetadata, string>(am => am.ControllerName, UmbracoController.GetControllerName(editorType)) .WithMetadata <EditorMetadata, bool>(am => am.HasChildActionDashboards, attribute.HasChildActionDashboards) .WithMetadata <EditorMetadata, bool>(am => am.IsInternalUmbracoEditor, editorType.GetCustomAttributes(typeof(UmbracoEditorAttribute), false).Any())); } } }
public virtual void RegisterMacroEngines(IContainerBuilder builder, TypeFinder typeFinder) { if (_macroEnginesRegistered) { return; } using (DisposableTimer.Start(timer => { LogHelper.TraceIfEnabled <RebelComponentRegistrar>("RegisterMacroEngines start took {0}ms", () => timer); _macroEnginesRegistered = true; })) { //now register each type in the container and also add it to our collection); foreach (var t in FindTypesInRequiredAssemblies <AbstractMacroEngine>(typeFinder)) { var engineType = t; RegisterComponent <AbstractMacroEngine, MacroEngineAttribute, MacroEngineMetadata>( t, builder, true, (pluginDef, attribute, registrar) => registrar .WithMetadata <MacroEngineMetadata, string>(am => am.EngineName, attribute.EngineName) .WithMetadata <MacroEngineMetadata, bool>(am => am.IsInternalRebelEngine, engineType.GetCustomAttributes(typeof(RebelMacroEngineAttribute), false).Any()) .ScopedAs.Singleton()); //only need one each } } }
public void ReadWriterQueryById() { using (DisposableTimer.Start(x => Console.WriteLine("ReadWriterQueryById took {0}ms", x))) { // Test provider directly rather than going via Hive using (var uow = _xmlReader.CreateReadOnlyUnitOfWork()) { using (DisposableTimer.Start(x => Console.WriteLine("Query and resolution took {0}ms", x))) { var item = ((EntityRepositoryReader)uow.ReadRepository).QueryContext.Query().Where( x => x.Id == new HiveEntityUri(1048)).FirstOrDefault(); Assert.IsNotNull(item); Assert.AreEqual(item.Id.AsInt, 1048); } } using (var uow = _mappingGroup.CreateReadOnlyUnitOfWork()) { using (DisposableTimer.Start(x => Console.WriteLine("Query and resolution via Hive took {0}ms", x))) { var item = uow.ReadRepository.QueryContext.Query().Where( x => x.Id == new HiveEntityUri(1048)).FirstOrDefault(); Assert.IsNotNull(item); Assert.AreEqual(item.Id.AsInt, 1048); } } } }
/// <summary> /// Registers the permissions. /// </summary> /// <param name="builder">The builder.</param> /// <param name="typeFinder">The type finder.</param> public virtual void RegisterPermissions(IContainerBuilder builder, TypeFinder typeFinder) { if (_permissionsRegistered) { return; } using (DisposableTimer.Start(timer => { LogHelper.TraceIfEnabled <RebelComponentRegistrar>("RegisterPermissions start took {0}ms", () => timer); _permissionsRegistered = true; })) { foreach (var t in FindTypesInRequiredAssemblies <Permission>(typeFinder)) { RegisterComponent <Permission, PermissionAttribute, PermissionMetadata>(t, builder, true, (pluginDef, attribute, registrar) => registrar .WithMetadata <PermissionMetadata, string>(metadata => metadata.Name, attribute.Name) .WithMetadata <PermissionMetadata, string>(metadata => metadata.Type, attribute.Type) .WithMetadata <PermissionMetadata, UserType>(metadata => metadata.UserType, attribute.UserType) .ScopedAs.Singleton()); //only need one each } } }
/// <summary> /// Register the tree controllers /// </summary> /// <param name="builder"></param> /// <param name="typeFinder"></param> public virtual void RegisterTreeControllers(IContainerBuilder builder, TypeFinder typeFinder) { if (_treeControllersRegistered) { return; } using (DisposableTimer.Start(timer => { LogHelper.TraceIfEnabled <RebelComponentRegistrar>("RegisterTreeControllers start took {0}ms", () => timer); _treeControllersRegistered = true; })) { //now register each type in the container and also add it to our collection foreach (var t in FindTypesInRequiredAssemblies <TreeController>(typeFinder)) { var treeType = t; RegisterComponent <TreeController, TreeAttribute, TreeMetadata>(t, builder, true, (pluginDef, attribute, registrar) => registrar .WithMetadata <EditorMetadata, string>(am => am.ControllerName, RebelController.GetControllerName(treeType)) .WithMetadata <TreeMetadata, string>(am => am.TreeTitle, attribute.TreeTitle) .WithMetadata <TreeMetadata, bool>(am => am.IsInternalRebelTree, treeType.GetCustomAttributes(typeof(RebelTreeAttribute), false).Any())); } } }
/// <summary> /// Registers all tasks. /// </summary> /// <param name="builder">The builder.</param> /// <param name="typeFinder">The type finder.</param> /// <remarks></remarks> public virtual void RegisterTasks(IContainerBuilder builder, TypeFinder typeFinder) { if (_tasksRegistered) { return; } using (DisposableTimer.Start(timer => { LogHelper.TraceIfEnabled <RebelComponentRegistrar>("RegisterTasks start took {0}ms", () => timer); _tasksRegistered = true; })) { foreach (var t in FindTypesInRequiredAssemblies <AbstractTask>(typeFinder)) { RegisterComponent <AbstractTask, TaskAttribute, TaskMetadata>(t, builder, false, (pluginDef, attribute, registrar) => { //if there's no attribute since we're not requiring that all AbstractTasks have one, //then don't register it into IoC as it might be something like our 'Delegate' task //or another custom one that is added to the task manager at runtime if (attribute == null) { return; } registrar .WithMetadata <TaskMetadata, string>(metadata => metadata.TriggerName, attribute.Trigger) .WithMetadata <TaskMetadata, bool>(metadata => metadata.ContinueOnError, attribute.ContinueOnFailure) .ScopedAs.Singleton(); }); //only need one each } } }
/// <summary> /// Registers all RebelPropertyEditors /// </summary> /// <param name="builder"></param> /// <param name="typeFinder"></param> public virtual void RegisterPropertyEditors(IContainerBuilder builder, TypeFinder typeFinder) { if (_propEditorsRegistered) { return; } using (DisposableTimer.Start(timer => { LogHelper.TraceIfEnabled <RebelComponentRegistrar>("RegisterPropertyEditors start took {0}ms", () => timer); _propEditorsRegistered = true; })) { foreach (var t in FindTypesInRequiredAssemblies <PropertyEditor>(typeFinder)) { var propEditorType = t; //builder.ForType(propEditorType).Register(); RegisterComponent <PropertyEditor, PropertyEditorAttribute, PropertyEditorMetadata>(t, builder, true, (pluginDef, attribute, registrar) => registrar .WithMetadata <PropertyEditorMetadata, string>(am => am.Name, attribute.Name) .WithMetadata <PropertyEditorMetadata, string>(am => am.Alias, attribute.Alias) .WithMetadata <PropertyEditorMetadata, bool>(am => am.IsContentPropertyEditor, attribute.IsContentPropertyEditor) .WithMetadata <PropertyEditorMetadata, bool>(am => am.IsParameterEditor, attribute.IsParameterEditor) .WithMetadata <PropertyEditorMetadata, bool>(am => am.IsInternalRebelEditor, propEditorType.GetCustomAttributes(typeof(RebelPropertyEditorAttribute), false).Any())); } } }
/// <summary> /// Finds & Registers the Surface controllers /// </summary> /// <param name="builder"></param> /// <param name="typeFinder"></param> public virtual void RegisterSurfaceControllers(IContainerBuilder builder, TypeFinder typeFinder) { if (_surfaceControllersRegistered) { return; } using (DisposableTimer.Start(timer => { LogHelper.TraceIfEnabled <RebelComponentRegistrar>("RegisterSurfaceControllers start took {0}ms", () => timer); _surfaceControllersRegistered = true; })) { //now register each type in the container and also add it to our collection); foreach (var t in FindTypesInRequiredAssemblies <SurfaceController>(typeFinder)) { var surfaceType = t; RegisterComponent <SurfaceController, SurfaceAttribute, SurfaceMetadata>( t, builder, false, (pluginDef, attribute, registrar) => registrar .WithMetadata <SurfaceMetadata, string>(am => am.ControllerName, RebelController.GetControllerName(surfaceType)) .WithMetadata <SurfaceMetadata, bool>(am => am.HasChildActionMacros, surfaceType.GetMethods().Any(a => a.GetCustomAttributes(typeof(ChildActionOnlyAttribute), false).Any()))); } } }
/// <summary> /// Registers all menu items /// </summary> /// <param name="builder"></param> /// <param name="typeFinder"></param> public virtual void RegisterMenuItems(IContainerBuilder builder, TypeFinder typeFinder) { if (_menuItemsRegistered) { return; } using (DisposableTimer.Start(timer => { LogHelper.TraceIfEnabled <RebelComponentRegistrar>("RegisterMenuItems start took {0}ms", () => timer); _menuItemsRegistered = true; })) { foreach (var t in FindTypesInRequiredAssemblies <MenuItem>(typeFinder)) { RegisterComponent <MenuItem, MenuItemAttribute, MenuItemMetadata>(t, builder, true, (pluginDef, attribute, registrar) => registrar .WithMetadata <MenuItemMetadata, string>(am => am.Title, attribute.Title) .WithMetadata <MenuItemMetadata, bool>(am => am.SeperatorBefore, attribute.SeparatorBefore) .WithMetadata <MenuItemMetadata, bool>(am => am.SeperatorAfter, attribute.SeparatorAfter) .WithMetadata <MenuItemMetadata, string>(am => am.Icon, attribute.Icon) .WithMetadata <MenuItemMetadata, string>(am => am.OnClientClick, attribute.OnClientClick) .ScopedAs.Singleton()); //only need one each } } }
/// <summary> /// Returns an ActionResult for the specified Macro. /// </summary> /// <param name="macroAlias"></param> /// <param name="currentControllerContext"></param> /// <param name="isForRichTextEditor">If the request is to render the contents in the back office rich text editor</param> /// <param name="resolveContent">callback to get the 'Content' model</param> public ActionResult RenderMacro( string macroAlias, IDictionary <string, string> macroParams, ControllerContext currentControllerContext, bool isForRichTextEditor, Func <Content> resolveContent) { using (DisposableTimer.Start(timer => LogHelper.TraceIfEnabled <MacroRenderer>("RenderMacro for {0} took {1}ms", () => macroAlias, () => timer))) { try { // get the macro's model var macroModel = GetMacroModel(macroAlias); if (isForRichTextEditor && !macroModel.Item1.RenderContentInEditor) { return(NoRichTextRenderMode(macroAlias)); } else { return(GetMacroResult(macroAlias, () => macroModel.Item1, resolveContent, macroParams, currentControllerContext)); } } catch (ApplicationException ex) { //if there's an exception, display a friendly message and log the error var txt = "Macro.RenderingFailed.Message".Localize(this, new { Error = ex.Message, MacroName = macroAlias }); var title = "Macro.RenderingFailed.Title".Localize(); LogHelper.Error <MacroRenderer>(txt, ex); return(MacroError(txt, title)); } } }
public BootManager(HttpApplication app) { _timer = DisposableTimer.Start(timer => LogHelper.TraceIfEnabled <BootManager>("Application start took {0}ms", () => timer)); _app = app; LogHelper.TraceIfEnabled <BootManager>("Created"); _rebelWireup = new RebelContainerBuilder <HttpApplication>(_app); }
public static DisposableTimer Start(string sessionId, string startMessage, string endMessage, params IDataParameter[] parameters) { if (Enabled) { CustomQueryReporting.ReportQuery(sessionId, ProfilerLoggingPrefix + startMessage, parameters, 0, 0, 0); return(DisposableTimer.Start(x => CustomQueryReporting.ReportQuery(sessionId, ProfilerLoggingPrefix + endMessage, parameters, (int)x, (int)x, 0))); } return(DisposableTimer.Start( x => { })); }
/// <summary> /// Renders/executes the provided macro ActionResult. /// </summary> /// <remarks>Macro rendering time is traced.</remarks> private static string GetMacroStringOutput(string macroAlias, ActionResult ar, ControllerContext currentControllerContext) { using (DisposableTimer.Start(timer => LogHelper.TraceIfEnabled <MacroRenderer>("GetMacroStringOutput for {0} took {1}ms", () => macroAlias, () => timer))) { if (ar is ViewResultBase) { var viewResult = (ViewResultBase)ar; return(currentControllerContext.RenderViewResultAsString(viewResult)); } if (ar is ContentResult) { var contentResult = (ContentResult)ar; return(contentResult.Content); } throw new NotSupportedException("Its not possible to retreive the output of a macro that doesn't return a ViewResultBase"); } }
public virtual void RegisterDashboardMatchRules(IContainerBuilder builder, TypeFinder typeFinder) { if (_dashboardMatchRulesRegistered) { return; } using (DisposableTimer.Start(timer => { LogHelper.TraceIfEnabled <RebelComponentRegistrar>("RegisterDashboardMatchRules start took {0}ms", () => timer); _dashboardMatchRulesRegistered = true; })) { //now register each type in the container and also add it to our collection); foreach (var t in FindTypesInRequiredAssemblies <DashboardMatchRule>(typeFinder)) { RegisterComponent <DashboardMatchRule, DashboardRuleMetadata>(t, builder, null); } } }
/// <summary> /// Registers all RebelParameterEditors /// </summary> /// <param name="builder"></param> /// <param name="typeFinder"></param> public virtual void RegisterParameterEditors(IContainerBuilder builder, TypeFinder typeFinder) { if (_paramEditorsRegistered) { return; } using (DisposableTimer.Start(timer => { LogHelper.TraceIfEnabled <RebelComponentRegistrar>("RegisterParameterEditors start took {0}ms", () => timer); _paramEditorsRegistered = true; })) { foreach (var t in FindTypesInRequiredAssemblies <AbstractParameterEditor>(typeFinder)) { RegisterComponent <AbstractParameterEditor, ParameterEditorAttribute, ParameterEditorMetadata>(t, builder, true, (pluginDef, attribute, registrar) => registrar .WithMetadata <ParameterEditorMetadata, string>(am => am.Name, attribute.Name) .WithMetadata <ParameterEditorMetadata, string>(am => am.Alias, attribute.Alias) .WithMetadata <ParameterEditorMetadata, Guid>(am => am.PropertyEditorId, attribute.PropertyEditorId)); } } }
public IDisposable Step(string name) { LogHelper.Debug(typeof(LogProfiler), "Starting - " + name); return(DisposableTimer.Start(l => LogHelper.Info(typeof(LogProfiler), () => name + " (took " + l + "ms)"))); }
/// <summary> /// Finds a TypedEntity based on the Uri /// </summary> /// <param name="fullUrlIncludingDomain"></param> /// <param name="revisionStatusType"></param> /// <returns></returns> public EntityRouteResult FindEntityByUrl(Uri fullUrlIncludingDomain, RevisionStatusType revisionStatusType = null) { Mandate.ParameterNotNull(fullUrlIncludingDomain.Scheme, "Scheme"); var statusTypeCacheKey = (revisionStatusType != null) ? revisionStatusType.Alias : string.Empty; //cache key is full uri except query string and revision status var cacheKey = EntityMappedKey + "-" + fullUrlIncludingDomain.GetLeftPart(UriPartial.Path) + "-" + statusTypeCacheKey; //TODO: We need to change how the NiceUrls are cached because if we store them in one entry as a dictionary in cache, then // we can do a reverse lookup to see if we've already generated the URL for the entity which may match the fullUrlIncludingDomain, // if so, then all we have to do is return the entity with the cached ID. return(ApplicationContext.FrameworkContext.ApplicationCache .GetOrCreate(cacheKey, () => { using (DisposableTimer.Start(timer => LogHelper.TraceIfEnabled <DefaultRoutingEngine>("FindEntityByUrl (not from cache) for URL {0} took {1}ms", () => fullUrlIncludingDomain, () => timer))) { ReadonlyGroupUnitFactory <IContentStore> persistenceManager; using (DisposableTimer.TraceDuration <DefaultRoutingEngine>("FindEntityByUrl: Getting a reader", "FindEntityByUrl: Got a reader")) persistenceManager = ApplicationContext.Hive.GetReader <IContentStore>(fullUrlIncludingDomain); if (persistenceManager != null) { IReadonlyGroupUnit <IContentStore> readonlyGroupUnit; using (DisposableTimer.TraceDuration <DefaultRoutingEngine>("FindEntityByUrl: Opening a reader", "FindEntityByUrl: Opened a reader")) readonlyGroupUnit = persistenceManager.CreateReadonly(); using (var uow = readonlyGroupUnit) { //first, lets check if it's an ID URL var trimmedAppPath = _httpContext.Request.ApplicationPath.TrimEnd('/'); var appPathLength = trimmedAppPath.Length; // gate-check for the incoming url because some code (e.g. the alt-template checker) could be unaware of vdirs etc. var absolutePath = fullUrlIncludingDomain.AbsolutePath; var path = (absolutePath.Length < appPathLength) ? absolutePath : absolutePath.Substring(appPathLength, absolutePath.Length - appPathLength); var urlId = HiveId.TryParse(path.TrimStart('/')); if (urlId.Success && urlId.Result.ProviderGroupRoot != null) { LogHelper.TraceIfEnabled <DefaultRoutingEngine>("In FindEntityByUrl: Resolving entity by Id URL (Id: {0} ", () => urlId.Result.ToFriendlyString()); try { //var entityById = uow.Repositories.Revisions.GetLatestRevision<TypedEntity>(urlId.Result, revisionStatusType); var entityById = uow.Repositories.OfRevisionType(revisionStatusType).InIds(urlId.Result.AsEnumerableOfOne()).FirstOrDefault(); if (entityById == null) { LogHelper.Warn <DefaultRoutingEngine>("In FindEntityByUrl: Resolving entity by Id URL failed (Id: {0} ", urlId.Result.ToFriendlyString()); return null; } return new HttpRuntimeCacheParameters <EntityRouteResult>(new EntityRouteResult(entityById, EntityRouteStatus.SuccessById)); } catch (ArgumentException) { //this occurs if the Id parsed but 'not really' return null; } } TypedEntity lastItemFound; //is the current requesting hostname/port in our list ? if (DomainList.ContainsHostname(fullUrlIncludingDomain.Authority)) { //domain found so get the first item assigned to this domain LogHelper.TraceIfEnabled <DefaultRoutingEngine>("In FindEntityByUrl: Resolving entity by Domain URL {0}", () => fullUrlIncludingDomain.Authority); var hostnameEntry = DomainList[fullUrlIncludingDomain.Authority]; //lastRevisionFound = uow.Repositories.Revisions.GetLatestRevision<TypedEntity>(hostnameEntry.ContentId, revisionStatusType); lastItemFound = uow.Repositories.OfRevisionType(revisionStatusType).InIds(hostnameEntry.ContentId.AsEnumerableOfOne()).FirstOrDefault(); Mandate.That(lastItemFound != null, x => new InvalidOperationException("Could not find an entity with a revision status of '" + revisionStatusType.Alias + "', having a hostname '" + fullUrlIncludingDomain.Authority + "' and id: " + hostnameEntry.ContentId)); } else { //no domain found for the current request, so we need to find the first routable node that doesn't require a domain LogHelper.TraceIfEnabled <DefaultRoutingEngine>("In FindEntityByUrl: Resolving entity by Non-Domain URL"); //var root = uow.Repositories.Revisions.GetLatestRevision<TypedEntity>(FixedHiveIds.ContentVirtualRoot, revisionStatusType); //Mandate.That(root != null, x => new InvalidOperationException("Could not find the content root")); var domainListIds = DomainList.Select(d => d.ContentId).ToArray(); var firstLevelRelations = uow.Repositories.GetChildRelations(FixedHiveIds.ContentVirtualRoot, FixedRelationTypes.DefaultRelationType).OrderBy( x => x.Ordinal).ToArray(); //try to find a first level node that doesn't exist in our domain list var firstNonHostnameEntity = firstLevelRelations.FirstOrDefault(x => !domainListIds.Contains(x.DestinationId)); // Issue #U5-112 // If we have found no entities that are NOT assigned to a domain, given that we have already tried to find // content matching the current request's domain, we cannot route any content, therefore return null // Also return null if there is no content if (firstNonHostnameEntity == null || !firstLevelRelations.Any()) { return null; } var idToUse = firstNonHostnameEntity.DestinationId; using (DisposableTimer.TraceDuration <DefaultRoutingEngine>("FindEntityByUrl: Querying for " + idToUse, "FindEntityByUrl: Query")) lastItemFound = uow.Repositories.OfRevisionType(revisionStatusType).InIds(idToUse.AsEnumerableOfOne()).FirstOrDefault(); ////if there is no first level node anywhere, then there is no content. Show a friendly message //if (firstNonHostnameEntity == null && !firstLevelRelations.Any()) // return null; ////if we have a first level node not assigned to a domain, use the first, otherwise if all nodes are assigned to domains, then just use the first //var idToUse = firstNonHostnameEntity == null ? firstLevelRelations.First().DestinationId : firstNonHostnameEntity.DestinationId; //lastItemFound = uow.Repositories.OfRevisionType(revisionStatusType).InIds(idToUse.AsEnumerableOfOne()).FirstOrDefault(); } // Now we will have the path from the current application root like: // /this/is/a/path/to/a/document // Now we need to walk down the tree if (lastItemFound != null && !string.IsNullOrWhiteSpace(path) && path != "/") { using (DisposableTimer.TraceDuration <DefaultRoutingEngine>("FindEntityByUrl: Calling GetEntityByPath for " + lastItemFound.Id + " " + path, "FindEntityByUrl: GetEntityByPath")) lastItemFound = uow .Repositories .GetEntityByPath <TypedEntity>(lastItemFound.Id, path, revisionStatusType, true); } if (lastItemFound == null) { return new HttpRuntimeCacheParameters <EntityRouteResult>( new EntityRouteResult(null, EntityRouteStatus.FailedNotFoundByName)); } return new HttpRuntimeCacheParameters <EntityRouteResult>( new EntityRouteResult(lastItemFound, EntityRouteStatus.SuccessWithoutHostname)); } } return null; } })); }
/// <summary> /// Finds a TypedEntity based on the Uri /// </summary> /// <param name="fullUrlIncludingDomain"></param> /// <param name="revisionStatusType"></param> /// <returns></returns> public EntityRouteResult FindEntityByUrl(Uri fullUrlIncludingDomain, RevisionStatusType revisionStatusType) { Mandate.ParameterNotNull(fullUrlIncludingDomain.Scheme, "Scheme"); //cache key is full uri except query string and revision status var cacheKey = EntityMappedKey + "-" + fullUrlIncludingDomain.GetLeftPart(UriPartial.Path) + "-" + revisionStatusType; //TODO: We need to change how the NiceUrls are cached because if we store them in one entry as a dictionary in cache, then // we can do a reverse lookup to see if we've already generated the URL for the entity which may match the fullUrlIncludingDomain, // if so, then all we have to do is return the entity with the cached ID. return(ApplicationContext.FrameworkContext.ApplicationCache .GetOrCreate(cacheKey, () => { using (DisposableTimer.Start(timer => LogHelper.TraceIfEnabled <DefaultRoutingEngine>("FindEntityByUrl for URL {0} took {1}ms", () => fullUrlIncludingDomain, () => timer))) { var persistenceManager = ApplicationContext.Hive.GetReader <IContentStore>(fullUrlIncludingDomain); if (persistenceManager != null) { using (var uow = persistenceManager.CreateReadonly()) { //first, lets check if it's an ID URL var path = fullUrlIncludingDomain.AbsolutePath.Substring( _httpContext.Request.ApplicationPath.TrimEnd('/').Length, fullUrlIncludingDomain.AbsolutePath.Length - _httpContext.Request.ApplicationPath.TrimEnd('/').Length); var urlId = HiveId.TryParse(path.TrimStart('/')); if (urlId.Success && urlId.Result.ProviderGroupRoot != null) { LogHelper.TraceIfEnabled <DefaultRoutingEngine>("Resolving entity by Id URL (Id: {0} ", () => urlId.Result.ToFriendlyString()); try { var entityById = uow.Repositories.Revisions.GetLatestRevision <TypedEntity>(urlId.Result, revisionStatusType); if (entityById == null) { LogHelper.Warn <DefaultRoutingEngine>("Resolving entity by Id URL failed (Id: {0} ", urlId.Result.ToFriendlyString()); return null; } return new HttpRuntimeCacheParameters <EntityRouteResult>( new EntityRouteResult(entityById.Item, EntityRouteStatus.SuccessById)); } catch (ArgumentException) { //this occurs if the Id parsed but 'not really' return null; } } Revision <TypedEntity> lastRevisionFound; TypedEntity lastItemFound; //is the current requesting hostname/port in our list ? if (DomainList.ContainsHostname(fullUrlIncludingDomain.Authority)) { //domain found so get the first item assigned to this domain LogHelper.TraceIfEnabled <DefaultRoutingEngine>("Resolving entity by Domain URL"); var hostnameEntry = DomainList[fullUrlIncludingDomain.Authority]; lastRevisionFound = uow.Repositories.Revisions.GetLatestRevision <TypedEntity>(hostnameEntry.ContentId, revisionStatusType); Mandate.That(lastRevisionFound != null, x => new InvalidOperationException("Could not find an entity with a revision status of '" + revisionStatusType.Alias + "', having a hostname '" + fullUrlIncludingDomain.Authority + "' and id: " + hostnameEntry.ContentId)); lastItemFound = lastRevisionFound.Item; } else { //no domain found for the current request, so we need to find the first routable node that doesn't require a domain LogHelper.TraceIfEnabled <DefaultRoutingEngine>("Resolving entity by Non-Domain URL"); //var root = uow.Repositories.Revisions.GetLatestRevision<TypedEntity>(FixedHiveIds.ContentVirtualRoot, revisionStatusType); //Mandate.That(root != null, x => new InvalidOperationException("Could not find the content root")); var domainListIds = DomainList.Select(d => d.ContentId); var firstLevelRelations = uow.Repositories.GetChildRelations(FixedHiveIds.ContentVirtualRoot, FixedRelationTypes.DefaultRelationType).OrderBy( x => x.Ordinal).ToArray(); //try to find a first level node that doesn't exist in our domain list var firstNonHostnameEntity = firstLevelRelations.FirstOrDefault(x => !domainListIds.Contains(x.DestinationId)); //if there is no first level node anywhere, then there is no content. Show a friendly message if (firstNonHostnameEntity == null && firstLevelRelations.Count() == 0) { return null; } //if we have a first level node not assigned to a domain, use the first, otherwise if all nodes are assigned to domains, then just use the first lastRevisionFound = uow.Repositories.Revisions.GetLatestRevision <TypedEntity>( firstNonHostnameEntity == null ? firstLevelRelations.First().DestinationId : firstNonHostnameEntity.DestinationId, revisionStatusType); lastItemFound = lastRevisionFound != null ? lastRevisionFound.Item : null; } // Now we will have the path from the current application root like: // /this/is/a/path/to/a/document // Now we need to walk down the tree if (lastItemFound != null && !string.IsNullOrWhiteSpace(path) && path != "/") { lastItemFound = uow.Repositories.GetEntityByPath <TypedEntity>(lastItemFound.Id, path, revisionStatusType, true); } if (lastItemFound == null) { return new HttpRuntimeCacheParameters <EntityRouteResult>( new EntityRouteResult(null, EntityRouteStatus.FailedNotFoundByName)); } return new HttpRuntimeCacheParameters <EntityRouteResult>( new EntityRouteResult(lastItemFound, EntityRouteStatus.SuccessWithoutHostname)); } } return null; } })); }