using Microsoft.Extensions.Logging; using Raven.Client.Documents; using Raven.Client.Documents.Session; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using zero.Core.Entities; namespace zero.Core.Routing { public class PageRouteProvider : AbtractRouteProvider { protected const string REF_KEY = "page"; protected const string PAGE_TYPE_KEY = "pageType"; protected ILogger Logger { get; set; } protected IPageUrlBuilder UrlBuilder { get; set; } protected IPageEndpointResolver EndpointResolver { get; set; } public PageRouteProvider(ILogger logger, IPageUrlBuilder urlBuilder, IPageEndpointResolver endpointResolver) : base("zero.pages") { Logger = logger; UrlBuilder = urlBuilder; EndpointResolver = endpointResolver; } /// public override RouteProviderEndpoint MapEndpoint(IResolvedRoute route) { if (!(route is PageRoute)) { return base.MapEndpoint(route); } return EndpointResolver.GetEndpoint(route as PageRoute); } /// public override string GetRouteId(IPage model) => ID_PREFIX + model.Hash; /// public override async Task ResolveRoute(IAsyncDocumentSession session, IRoute route) { PageRoute resolved = new PageRoute(route); List ids = new List(); RouteReference reference = route.References.SingleOrDefault(x => x.Collection == REF_KEY); if (reference == null) { return null; } ids.Add(reference.Id); ids.AddRange(route.Dependencies); Dictionary pages = await session.LoadAsync(ids); if (!pages.TryGetValue(reference.Id, out IPage page)) { return null; } resolved.Page = page; resolved.Parents = pages.Where(x => x.Key != reference.Id).Select(x => x.Value).ToList(); return resolved; } /// public override async Task> GetAllRoutes(IAsyncDocumentSession session) { IList TraversePageChildren(IPage parent, IEnumerable parents, IEnumerable allPages) { List routes = new List(); IEnumerable currentPages = allPages.Where(x => x.ParentId == parent?.Id); foreach (IPage page in currentPages) { IRoute route = BuildRoute(page, parents, allPages); if (route != null) { routes.Add(route); } routes.AddRange(TraversePageChildren(page, parents.Union(new List() { page }), allPages)); } return routes; } IList pages = await session.Query().ToListAsync(); return TraversePageChildren(null, new List() { }, pages); } /// /// Build route entity from page /// protected virtual IRoute BuildRoute(IPage page, IEnumerable parents, IEnumerable allPages) { if (page is PageFolder) { return null; } IRoute route = new Route() { Id = GetRouteId(page), Url = UrlBuilder.GetUrl(page, parents), ProviderAlias = Alias }; route.Params.Add(PAGE_TYPE_KEY, page.PageTypeAlias); route.References.Add(new RouteReference(page.Id, REF_KEY)); if (parents != null) { foreach (IPage parent in parents) { route.Dependencies.Add(parent.Id); } } return route; } } }