Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }