internal static void ExpandOutGlobalRoutes(List <RouteRequestBuilder> possibleRoutePaths, string[] routeKeys) { foreach (var possibleRoutePath in possibleRoutePaths) { while (FindAndAddSegmentMatch(possibleRoutePath, routeKeys)) { ; } while (!possibleRoutePath.IsFullMatch) { NodeLocation nodeLocation = new NodeLocation(); nodeLocation.SetNode(possibleRoutePath.LowestChild); List <RouteRequestBuilder> pureGlobalRoutesMatch = new List <RouteRequestBuilder>(); while (nodeLocation.Shell != null && pureGlobalRoutesMatch.Count == 0) { SearchPath(nodeLocation.LowestChild, null, possibleRoutePath.RemainingSegments, pureGlobalRoutesMatch, 0, ignoreGlobalRoutes: false); nodeLocation.Pop(); } // nothing found or too many things found if (pureGlobalRoutesMatch.Count != 1 || pureGlobalRoutesMatch[0].GlobalRouteMatches.Count == 0) { break; } for (var i = 0; i < pureGlobalRoutesMatch[0].GlobalRouteMatches.Count; i++) { var match = pureGlobalRoutesMatch[0]; possibleRoutePath.AddGlobalRoute(match.GlobalRouteMatches[i], match.SegmentsMatched[i]); } } } }
internal static List <RouteRequestBuilder> GenerateRoutePaths(Shell shell, Uri request, Uri originalRequest) { request = FormatUri(request); originalRequest = FormatUri(originalRequest); var routeKeys = Routing.GetRouteKeys(); for (int i = 0; i < routeKeys.Length; i++) { routeKeys[i] = FormatUri(routeKeys[i]); } List <RouteRequestBuilder> possibleRoutePaths = new List <RouteRequestBuilder>(); if (!request.IsAbsoluteUri) { request = ConvertToStandardFormat(shell, request); } string localPath = request.LocalPath; bool relativeMatch = false; if (!originalRequest.IsAbsoluteUri && !originalRequest.OriginalString.StartsWith("/") && !originalRequest.OriginalString.StartsWith("\\")) { relativeMatch = true; } var segments = localPath.Split(_pathSeparator, StringSplitOptions.RemoveEmptyEntries); if (!relativeMatch) { for (int i = 0; i < routeKeys.Length; i++) { var route = routeKeys[i]; var uri = ConvertToStandardFormat(shell, new Uri(route, UriKind.RelativeOrAbsolute)); // Todo is this supported? if (uri.Equals(request)) { var builder = new RouteRequestBuilder(route, route, null, segments); return(new List <RouteRequestBuilder> { builder }); } } } var depthStart = 0; if (segments[0] == shell.Route) { segments = segments.Skip(1).ToArray(); depthStart = 1; } else { depthStart = 0; } if (relativeMatch && shell?.CurrentItem != null) { // retrieve current location var currentLocation = NodeLocation.Create(shell); while (currentLocation.Shell != null) { List <RouteRequestBuilder> pureRoutesMatch = new List <RouteRequestBuilder>(); List <RouteRequestBuilder> pureGlobalRoutesMatch = new List <RouteRequestBuilder>(); SearchPath(currentLocation.LowestChild, null, segments, pureRoutesMatch, 0); SearchPath(currentLocation.LowestChild, null, segments, pureGlobalRoutesMatch, 0, ignoreGlobalRoutes: false); pureRoutesMatch = GetBestMatches(pureRoutesMatch); pureGlobalRoutesMatch = GetBestMatches(pureGlobalRoutesMatch); if (pureRoutesMatch.Count > 0) { return(pureRoutesMatch); } if (pureGlobalRoutesMatch.Count > 0) { return(pureGlobalRoutesMatch); } currentLocation.Pop(); } string searchPath = String.Join("/", segments); if (routeKeys.Contains(searchPath)) { return(new List <RouteRequestBuilder> { new RouteRequestBuilder(searchPath, searchPath, null, segments) }); } RouteRequestBuilder builder = null; foreach (var segment in segments) { if (routeKeys.Contains(segment)) { if (builder == null) { builder = new RouteRequestBuilder(segment, segment, null, segments); } else { builder.AddGlobalRoute(segment, segment); } } } if (builder != null && builder.IsFullMatch) { return new List <RouteRequestBuilder> { builder } } ; } else { possibleRoutePaths.Clear(); SearchPath(shell, null, segments, possibleRoutePaths, depthStart); var bestMatches = GetBestMatches(possibleRoutePaths); if (bestMatches.Count > 0) { return(bestMatches); } bestMatches.Clear(); foreach (var possibleRoutePath in possibleRoutePaths) { while (routeKeys.Contains(possibleRoutePath.NextSegment) || routeKeys.Contains(possibleRoutePath.RemainingPath)) { if (routeKeys.Contains(possibleRoutePath.NextSegment)) { possibleRoutePath.AddGlobalRoute(possibleRoutePath.NextSegment, possibleRoutePath.NextSegment); } else { possibleRoutePath.AddGlobalRoute(possibleRoutePath.RemainingPath, possibleRoutePath.RemainingPath); } } while (!possibleRoutePath.IsFullMatch) { NodeLocation nodeLocation = new NodeLocation(); nodeLocation.SetNode(possibleRoutePath.LowestChild); List <RouteRequestBuilder> pureGlobalRoutesMatch = new List <RouteRequestBuilder>(); while (nodeLocation.Shell != null && pureGlobalRoutesMatch.Count == 0) { SearchPath(nodeLocation.LowestChild, null, possibleRoutePath.RemainingSegments, pureGlobalRoutesMatch, 0, ignoreGlobalRoutes: false); nodeLocation.Pop(); } // nothing found or too many things found if (pureGlobalRoutesMatch.Count != 1) { break; } for (var i = 0; i < pureGlobalRoutesMatch[0].GlobalRouteMatches.Count; i++) { var match = pureGlobalRoutesMatch[0]; possibleRoutePath.AddGlobalRoute(match.GlobalRouteMatches[i], match.SegmentsMatched[i]); } } } } possibleRoutePaths = GetBestMatches(possibleRoutePaths); return(possibleRoutePaths); }