Пример #1
0
        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]);
                    }
                }
            }
        }
Пример #2
0
        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);
        }