using Raven.Client.Documents; using Raven.Client.Documents.Linq; using Raven.Client.Documents.Session; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using zero.Core.Api; using zero.Core.Entities; using zero.Core.Entities.Messages; using zero.Core.Extensions; using zero.Core.Messages; using zero.Core.Utils; namespace zero.Core.Routing { public class PageUrlProvider : IUrlProvider { public string Alias => "zero.pages"; public const string PAGE_COLLECTION = "page"; public const string PAGE_TYPE = "pageType"; protected IDocumentStore Raven { get; private set; } protected IMessageAggregator Messages { get; private set; } protected IPageUrlResolver PageUrlResolver { get; set; } protected IApplicationContext Context { get; private set; } public PageUrlProvider(IDocumentStore raven, IMessageAggregator messages, IPageUrlResolver pageUrlResolver, IApplicationContext context) { Raven = raven; Messages = messages; PageUrlResolver = pageUrlResolver; Context = context; } /// public async Task Resolve(IRoute route) { PageRoute resolved = new PageRoute(route); List ids = new List(); RouteReference reference = route.References.SingleOrDefault(x => x.Collection == PAGE_COLLECTION); ids.Add(reference.Id); ids.AddRange(route.Dependencies); using IAsyncDocumentSession session = Raven.OpenAsyncSession(); Dictionary pages = await session.LoadAsync(ids); if (!pages.TryGetValue(reference.Id, out IPage page) || page.AppId != route.AppId) { return null; } resolved.Page = page; resolved.Parents = pages.Where(x => x.Key != reference.Id).Select(x => x.Value).ToList(); return resolved; } /// public async Task> Run() { using IAsyncDocumentSession session = Raven.OpenAsyncSession(); List allRoutes = new List(); IList pages = await session.Query().ToListAsync(); IEnumerable> groupedPages = pages.GroupBy(x => x.AppId); foreach (var group in groupedPages) { IApplicationContext context = await Context.ForId(group.Key); IList routes = TraversePageChildren(context, null, new List() { }, group); allRoutes.AddRange(routes); } return allRoutes; } protected IRoute BuildRoute(IApplicationContext context, IPage page, IEnumerable parents) { UrlInfo info = PageUrlResolver.GetUrl(context, page, parents); IRoute route = new Route() { Id = String.Concat("routes.", IdGenerator.Create()), AppId = context.AppId, Url = info.IsUrl ? info.Text.EnsureStartsWith('/') : null, ProviderAlias = Alias }; route.Params.Add(PAGE_TYPE, page.PageTypeAlias); route.References.Add(new RouteReference(page.Id, PAGE_COLLECTION)); if (parents != null) { foreach (IPage parent in parents) { route.Dependencies.Add(parent.Id); } } return route; } IList TraversePageChildren(IApplicationContext context, 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(context, page, parents); routes.Add(route); routes.AddRange(TraversePageChildren(context, page, parents.Union(new List() { page }), allPages)); } return routes; } } }