Example #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]);
                    }
                }
            }
        }
Example #2
0
            public NodeLocation WalkToNextNode()
            {
                int itemIndex    = 0;
                int sectionIndex = 0;
                int contentIndex = 0;

                if (Item != null)
                {
                    itemIndex = Shell.Items.IndexOf(Item);
                }

                if (Section != null)
                {
                    sectionIndex = Item.Items.IndexOf(Section);
                }

                if (Content != null)
                {
                    contentIndex = Section.Items.IndexOf(Content) + 1;
                }

                for (int i = itemIndex; i < Shell.Items.Count; i++)
                {
                    for (int j = sectionIndex; j < Shell.Items[i].Items.Count; j++)
                    {
                        for (int k = contentIndex; k < Shell.Items[i].Items[j].Items.Count;)
                        {
                            var nodeLocation = new NodeLocation();
                            nodeLocation.SetNode(Shell.Items[i]);
                            nodeLocation.SetNode(Shell.Items[i].Items[j]);
                            nodeLocation.SetNode(Shell.Items[i].Items[j].Items[k]);
                            return(nodeLocation);
                        }

                        contentIndex = 0;
                    }

                    sectionIndex = 0;
                }

                return(null);
            }
			public static NodeLocation Create(Shell shell)
			{
				NodeLocation location = new NodeLocation();
				location.SetNode(
					(object)shell.CurrentItem?.CurrentItem?.CurrentItem ??
					(object)shell.CurrentItem?.CurrentItem ??
					(object)shell.CurrentItem ??
					(object)shell);

				return location;
			}
Example #4
0
        static void SearchPath(
            object node,
            RouteRequestBuilder currentMatchedPath,
            string[] segments,
            List <RouteRequestBuilder> possibleRoutePaths,
            int depthToStart,
            int myDepth = -1,
            NodeLocation currentLocation = null,
            bool ignoreGlobalRoutes      = true)
        {
            if (node is GlobalRouteItem && ignoreGlobalRoutes)
            {
                return;
            }

            ++myDepth;
            currentLocation = currentLocation ?? new NodeLocation();
            currentLocation.SetNode(node);

            IEnumerable items = null;

            if (depthToStart > myDepth)
            {
                items = GetItems(node);
                if (items == null)
                {
                    return;
                }

                foreach (var nextNode in items)
                {
                    SearchPath(nextNode, null, segments, possibleRoutePaths, depthToStart, myDepth, currentLocation, ignoreGlobalRoutes);
                }
                return;
            }

            string shellSegment = GetRoute(node);
            string userSegment  = null;

            if (currentMatchedPath == null)
            {
                userSegment = segments[0];
            }
            else
            {
                userSegment = currentMatchedPath.NextSegment;
            }

            if (userSegment == null)
            {
                return;
            }

            RouteRequestBuilder builder = null;

            if (shellSegment == userSegment || Routing.IsImplicit(shellSegment))
            {
                if (currentMatchedPath == null)
                {
                    builder = new RouteRequestBuilder(shellSegment, userSegment, node, segments);
                }
                else
                {
                    builder = new RouteRequestBuilder(currentMatchedPath);
                    builder.AddMatch(shellSegment, userSegment, node);
                }

                if (!Routing.IsImplicit(shellSegment) || shellSegment == userSegment)
                {
                    possibleRoutePaths.Add(builder);
                }
            }

            items = GetItems(node);
            if (items == null)
            {
                return;
            }

            foreach (var nextNode in items)
            {
                SearchPath(nextNode, builder, segments, possibleRoutePaths, depthToStart, myDepth, currentLocation, ignoreGlobalRoutes);
            }
        }
        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);
        }