static List <RouteRequestBuilder> SearchForGlobalRoutes( string[] segments, Uri startingFrom, NodeLocation currentLocation, string[] routeKeys) { List <RouteRequestBuilder> pureGlobalRoutesMatch = new List <RouteRequestBuilder>(); string newPath = String.Join(_pathSeparator, segments); var currentSegments = RetrievePaths(startingFrom.OriginalString); var newSegments = CollapsePath(newPath, currentSegments, true).ToArray(); List <string> fullRouteWithNewSegments = new List <string>(currentSegments); fullRouteWithNewSegments.AddRange(newSegments); // This is used to calculate if the global route matches RouteRequestBuilder routeRequestBuilder = new RouteRequestBuilder(fullRouteWithNewSegments.ToArray()); // add shell element routes routeRequestBuilder.AddMatch(currentLocation); // add routes that are contributed by global routes for (var i = 0; i < currentSegments.Length; i++) { var currentSeg = currentSegments[i]; if (routeRequestBuilder.FullSegments.Count <= i || currentSeg != routeRequestBuilder.FullSegments[i]) { routeRequestBuilder.AddGlobalRoute(currentSeg, currentSeg); } } var existingGlobalRoutes = routeRequestBuilder.GlobalRouteMatches.ToList(); ExpandOutGlobalRoutes(new List <RouteRequestBuilder> { routeRequestBuilder }, routeKeys); if (routeRequestBuilder.IsFullMatch) { RouteRequestBuilder requestBuilderWithNewSegments = new RouteRequestBuilder(newSegments); var additionalRouteMatches = routeRequestBuilder.GlobalRouteMatches; for (int i = existingGlobalRoutes.Count; i < additionalRouteMatches.Count; i++) { requestBuilderWithNewSegments.AddGlobalRoute(additionalRouteMatches[i], segments[i - existingGlobalRoutes.Count]); } pureGlobalRoutesMatch.Add(requestBuilderWithNewSegments); } return(pureGlobalRoutesMatch); }
static bool FindAndAddSegmentMatch(RouteRequestBuilder possibleRoutePath, string[] routeKeys) { // First search by collapsing global routes if user is registering routes like "route1/route2/route3" foreach (var routeKey in routeKeys) { var collapsedRoutes = CollapsePath(routeKey, possibleRoutePath.SegmentsMatched, true); var collapsedRoute = String.Join(_pathSeparator, collapsedRoutes); if (routeKey.StartsWith("//")) { var routeKeyPaths = routeKey.Split(_pathSeparators, StringSplitOptions.RemoveEmptyEntries); if (routeKeyPaths[0] == collapsedRoutes[0]) { collapsedRoute = "//" + collapsedRoute; } } string collapsedMatch = possibleRoutePath.GetNextSegmentMatch(collapsedRoute); if (!String.IsNullOrWhiteSpace(collapsedMatch)) { possibleRoutePath.AddGlobalRoute(routeKey, collapsedMatch); return(true); } // If the registered route is a combination of shell items and global routes then we might end up here // without the previous tree search finding the correct path if ((possibleRoutePath.Shell != null) && (possibleRoutePath.Item == null || possibleRoutePath.Section == null || possibleRoutePath.Content == null)) { var nextNode = possibleRoutePath.GetNodeLocation().WalkToNextNode(); while (nextNode != null) { // This means we've jumped to a branch that no longer corresponds with the route path we are searching if ((possibleRoutePath.Item != null && nextNode.Item != possibleRoutePath.Item) || (possibleRoutePath.Section != null && nextNode.Section != possibleRoutePath.Section) || (possibleRoutePath.Content != null && nextNode.Content != possibleRoutePath.Content)) { nextNode = nextNode.WalkToNextNode(); continue; } var leafSearch = new RouteRequestBuilder(possibleRoutePath); if (!leafSearch.AddMatch(nextNode)) { nextNode = nextNode.WalkToNextNode(); continue; } var collapsedLeafRoute = String.Join(_pathSeparator, CollapsePath(routeKey, leafSearch.SegmentsMatched, true)); if (routeKey.StartsWith("//")) { collapsedLeafRoute = "//" + collapsedLeafRoute; } string segmentMatch = leafSearch.GetNextSegmentMatch(collapsedLeafRoute); if (!String.IsNullOrWhiteSpace(segmentMatch)) { possibleRoutePath.AddMatch(nextNode); possibleRoutePath.AddGlobalRoute(routeKey, segmentMatch); return(true); } nextNode = nextNode.WalkToNextNode(); } } } // check for exact matches if (routeKeys.Contains(possibleRoutePath.NextSegment)) { possibleRoutePath.AddGlobalRoute(possibleRoutePath.NextSegment, possibleRoutePath.NextSegment); return(true); } return(false); }