2020-03-13 14:10:33 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Reflection;
|
2020-05-29 00:33:49 +08:00
|
|
|
|
using AntDesign.Docs.Localization;
|
2020-03-13 14:10:33 +08:00
|
|
|
|
using Microsoft.AspNetCore.Components;
|
|
|
|
|
|
2020-05-29 00:33:49 +08:00
|
|
|
|
namespace AntDesign.Docs.Routing
|
2020-03-13 14:10:33 +08:00
|
|
|
|
{
|
|
|
|
|
public class RouteManager
|
|
|
|
|
{
|
|
|
|
|
public Route[] Routes { get; private set; }
|
|
|
|
|
|
2020-03-30 14:33:39 +08:00
|
|
|
|
private readonly ILanguageService _languageService;
|
|
|
|
|
|
|
|
|
|
public RouteManager(ILanguageService languageService)
|
|
|
|
|
{
|
|
|
|
|
_languageService = languageService;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-28 00:02:11 +08:00
|
|
|
|
public void Initialise(Assembly appAssembly)
|
2020-03-13 14:10:33 +08:00
|
|
|
|
{
|
2020-03-28 00:02:11 +08:00
|
|
|
|
var pageComponentTypes = appAssembly
|
2020-03-13 14:10:33 +08:00
|
|
|
|
.ExportedTypes
|
|
|
|
|
.Where(t => t.Namespace != null && (t.IsSubclassOf(typeof(ComponentBase))
|
|
|
|
|
&& t.Namespace.Contains(".Pages")));
|
|
|
|
|
|
|
|
|
|
var routesList = new List<Route>();
|
|
|
|
|
foreach (var pageType in pageComponentTypes)
|
|
|
|
|
{
|
|
|
|
|
if (pageType.FullName == null)
|
|
|
|
|
continue;
|
|
|
|
|
|
2020-03-17 13:42:54 +08:00
|
|
|
|
var uriSegments = pageType.FullName.Substring(pageType.FullName.IndexOf("Pages", StringComparison.Ordinal) + 6).Split('.');
|
|
|
|
|
|
|
|
|
|
var routeAttributes = pageType.GetCustomAttributes<RouteAttribute>(inherit: false);
|
|
|
|
|
|
|
|
|
|
if (!routeAttributes.Any())
|
|
|
|
|
{
|
2020-03-30 14:33:39 +08:00
|
|
|
|
routeAttributes = new[] { new RouteAttribute($"/{string.Join("/", uriSegments)}"), };
|
2020-03-17 13:42:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var templates = routeAttributes.Select(t => t.Template).ToArray();
|
|
|
|
|
var parsedTemplates = templates.Select(TemplateParser.ParseTemplate).ToArray();
|
|
|
|
|
var allRouteParameterNames = parsedTemplates
|
|
|
|
|
.SelectMany(GetParameterNames)
|
|
|
|
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
|
|
|
|
.ToArray();
|
|
|
|
|
|
|
|
|
|
foreach (var parsedTemplate in parsedTemplates)
|
2020-03-13 14:10:33 +08:00
|
|
|
|
{
|
2020-03-17 13:42:54 +08:00
|
|
|
|
var unusedRouteParameterNames = allRouteParameterNames
|
|
|
|
|
.Except(GetParameterNames(parsedTemplate), StringComparer.OrdinalIgnoreCase)
|
|
|
|
|
.ToArray();
|
|
|
|
|
|
|
|
|
|
var newRoute = new Route
|
|
|
|
|
{
|
|
|
|
|
PageType = pageType,
|
|
|
|
|
Template = parsedTemplate,
|
|
|
|
|
UnusedRouteParameterNames = unusedRouteParameterNames
|
|
|
|
|
};
|
2020-03-13 14:10:33 +08:00
|
|
|
|
|
2020-03-17 13:42:54 +08:00
|
|
|
|
routesList.Add(newRoute);
|
|
|
|
|
}
|
2020-03-13 14:10:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Routes = routesList.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-17 13:42:54 +08:00
|
|
|
|
public MatchResult Match(string relativeUri)
|
2020-03-13 14:10:33 +08:00
|
|
|
|
{
|
2020-03-30 14:33:39 +08:00
|
|
|
|
var originalUri = relativeUri;
|
|
|
|
|
|
|
|
|
|
if (relativeUri.IndexOf('?') > -1)
|
|
|
|
|
{
|
|
|
|
|
relativeUri = relativeUri.Substring(0, relativeUri.IndexOf('?'));
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-17 13:42:54 +08:00
|
|
|
|
var segments = relativeUri.Trim().Split('/', StringSplitOptions.RemoveEmptyEntries).Select(Uri.UnescapeDataString).ToArray();
|
2020-03-30 14:33:39 +08:00
|
|
|
|
|
2020-03-13 14:10:33 +08:00
|
|
|
|
if (segments.Length == 0)
|
|
|
|
|
{
|
2020-03-17 13:42:54 +08:00
|
|
|
|
var indexRoute = Routes.SingleOrDefault(x => x.PageType.FullName != null && x.PageType.FullName.ToLower().EndsWith("index"));
|
|
|
|
|
|
|
|
|
|
if (indexRoute != null)
|
|
|
|
|
{
|
|
|
|
|
return MatchResult.Match(indexRoute);
|
|
|
|
|
}
|
2020-03-13 14:10:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-30 14:33:39 +08:00
|
|
|
|
if (segments[0] == _languageService.CurrentCulture.Name)
|
|
|
|
|
{
|
|
|
|
|
segments = segments[1..];
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-13 14:10:33 +08:00
|
|
|
|
foreach (var route in Routes)
|
|
|
|
|
{
|
2020-03-30 14:33:39 +08:00
|
|
|
|
var matchResult = route.Match(segments, originalUri);
|
2020-03-13 14:10:33 +08:00
|
|
|
|
|
|
|
|
|
if (matchResult.IsMatch)
|
|
|
|
|
{
|
|
|
|
|
return matchResult;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return MatchResult.NoMatch();
|
|
|
|
|
}
|
2020-03-17 13:42:54 +08:00
|
|
|
|
|
|
|
|
|
private static string[] GetParameterNames(RouteTemplate routeTemplate)
|
|
|
|
|
{
|
|
|
|
|
return routeTemplate.Segments
|
|
|
|
|
.Where(s => s.IsParameter)
|
|
|
|
|
.Select(s => s.Value)
|
|
|
|
|
.ToArray();
|
|
|
|
|
}
|
2020-03-13 14:10:33 +08:00
|
|
|
|
}
|
|
|
|
|
}
|