Fix bugs in sizing TableLayoutPanel (Xamarin bug 18638)
[mono.git] / mcs / class / System.Web.Mvc2 / System.Web.Mvc / RouteCollectionExtensions.cs
1 /* ****************************************************************************\r
2  *\r
3  * Copyright (c) Microsoft Corporation. All rights reserved.\r
4  *\r
5  * This software is subject to the Microsoft Public License (Ms-PL). \r
6  * A copy of the license can be found in the license.htm file included \r
7  * in this distribution.\r
8  *\r
9  * You must not remove this notice, or any other, from this software.\r
10  *\r
11  * ***************************************************************************/\r
12 \r
13 namespace System.Web.Mvc {\r
14     using System;\r
15     using System.Diagnostics.CodeAnalysis;\r
16     using System.Web.Routing;\r
17 \r
18     public static class RouteCollectionExtensions {\r
19 \r
20         // This method returns a new RouteCollection containing only routes that matched a particular area.\r
21         // The Boolean out parameter is just a flag specifying whether any registered routes were area-aware.\r
22         private static RouteCollection FilterRouteCollectionByArea(RouteCollection routes, string areaName, out bool usingAreas) {\r
23             if (areaName == null) {\r
24                 areaName = String.Empty;\r
25             }\r
26 \r
27             usingAreas = false;\r
28             RouteCollection filteredRoutes = new RouteCollection();\r
29 \r
30             using (routes.GetReadLock()) {\r
31                 foreach (RouteBase route in routes) {\r
32                     string thisAreaName = AreaHelpers.GetAreaName(route) ?? String.Empty;\r
33                     usingAreas |= (thisAreaName.Length > 0);\r
34                     if (String.Equals(thisAreaName, areaName, StringComparison.OrdinalIgnoreCase)) {\r
35                         filteredRoutes.Add(route);\r
36                     }\r
37                 }\r
38             }\r
39 \r
40             // if areas are not in use, the filtered route collection might be incorrect\r
41             return (usingAreas) ? filteredRoutes : routes;\r
42         }\r
43 \r
44         public static VirtualPathData GetVirtualPathForArea(this RouteCollection routes, RequestContext requestContext, RouteValueDictionary values) {\r
45             return GetVirtualPathForArea(routes, requestContext, null /* name */, values);\r
46         }\r
47 \r
48         public static VirtualPathData GetVirtualPathForArea(this RouteCollection routes, RequestContext requestContext, string name, RouteValueDictionary values) {\r
49             bool usingAreas; // don't care about this value\r
50             return GetVirtualPathForArea(routes, requestContext, name, values, out usingAreas);\r
51         }\r
52 \r
53         internal static VirtualPathData GetVirtualPathForArea(this RouteCollection routes, RequestContext requestContext, string name, RouteValueDictionary values, out bool usingAreas) {\r
54             if (routes == null) {\r
55                 throw new ArgumentNullException("routes");\r
56             }\r
57 \r
58             if (!String.IsNullOrEmpty(name)) {\r
59                 // the route name is a stronger qualifier than the area name, so just pipe it through\r
60                 usingAreas = false;\r
61                 return routes.GetVirtualPath(requestContext, name, values);\r
62             }\r
63 \r
64             string targetArea = null;\r
65             if (values != null) {\r
66                 object targetAreaRawValue;\r
67                 if (values.TryGetValue("area", out targetAreaRawValue)) {\r
68                     targetArea = targetAreaRawValue as string;\r
69                 }\r
70                 else {\r
71                     // set target area to current area\r
72                     if (requestContext != null) {\r
73                         targetArea = AreaHelpers.GetAreaName(requestContext.RouteData);\r
74                     }\r
75                 }\r
76             }\r
77 \r
78             // need to apply a correction to the RVD if areas are in use\r
79             RouteValueDictionary correctedValues = values;\r
80             RouteCollection filteredRoutes = FilterRouteCollectionByArea(routes, targetArea, out usingAreas);\r
81             if (usingAreas) {\r
82                 correctedValues = new RouteValueDictionary(values);\r
83                 correctedValues.Remove("area");\r
84             }\r
85 \r
86             VirtualPathData vpd = filteredRoutes.GetVirtualPath(requestContext, correctedValues);\r
87             return vpd;\r
88         }\r
89 \r
90         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#",\r
91             Justification = "This is not a regular URL as it may contain special routing characters.")]\r
92         public static void IgnoreRoute(this RouteCollection routes, string url) {\r
93             IgnoreRoute(routes, url, null /* constraints */);\r
94         }\r
95 \r
96         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#",\r
97             Justification = "This is not a regular URL as it may contain special routing characters.")]\r
98         public static void IgnoreRoute(this RouteCollection routes, string url, object constraints) {\r
99             if (routes == null) {\r
100                 throw new ArgumentNullException("routes");\r
101             }\r
102             if (url == null) {\r
103                 throw new ArgumentNullException("url");\r
104             }\r
105 \r
106             IgnoreRouteInternal route = new IgnoreRouteInternal(url) {\r
107                 Constraints = new RouteValueDictionary(constraints)\r
108             };\r
109 \r
110             routes.Add(route);\r
111         }\r
112 \r
113         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#",\r
114             Justification = "This is not a regular URL as it may contain special routing characters.")]\r
115         public static Route MapRoute(this RouteCollection routes, string name, string url) {\r
116             return MapRoute(routes, name, url, null /* defaults */, (object)null /* constraints */);\r
117         }\r
118 \r
119         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#",\r
120             Justification = "This is not a regular URL as it may contain special routing characters.")]\r
121         public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults) {\r
122             return MapRoute(routes, name, url, defaults, (object)null /* constraints */);\r
123         }\r
124 \r
125         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#",\r
126             Justification = "This is not a regular URL as it may contain special routing characters.")]\r
127         public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints) {\r
128             return MapRoute(routes, name, url, defaults, constraints, null /* namespaces */);\r
129         }\r
130 \r
131         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#",\r
132             Justification = "This is not a regular URL as it may contain special routing characters.")]\r
133         public static Route MapRoute(this RouteCollection routes, string name, string url, string[] namespaces) {\r
134             return MapRoute(routes, name, url, null /* defaults */, null /* constraints */, namespaces);\r
135         }\r
136 \r
137         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#",\r
138             Justification = "This is not a regular URL as it may contain special routing characters.")]\r
139         public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, string[] namespaces) {\r
140             return MapRoute(routes, name, url, defaults, null /* constraints */, namespaces);\r
141         }\r
142 \r
143         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#",\r
144             Justification = "This is not a regular URL as it may contain special routing characters.")]\r
145         public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces) {\r
146             if (routes == null) {\r
147                 throw new ArgumentNullException("routes");\r
148             }\r
149             if (url == null) {\r
150                 throw new ArgumentNullException("url");\r
151             }\r
152 \r
153             Route route = new Route(url, new MvcRouteHandler()) {\r
154                 Defaults = new RouteValueDictionary(defaults),\r
155                 Constraints = new RouteValueDictionary(constraints),\r
156                 DataTokens = new RouteValueDictionary()\r
157             };\r
158 \r
159             if ((namespaces != null) && (namespaces.Length > 0)) {\r
160                 route.DataTokens["Namespaces"] = namespaces;\r
161             }\r
162 \r
163             routes.Add(name, route);\r
164 \r
165             return route;\r
166         }\r
167 \r
168         private sealed class IgnoreRouteInternal : Route {\r
169             public IgnoreRouteInternal(string url)\r
170                 : base(url, new StopRoutingHandler()) {\r
171             }\r
172 \r
173             public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary routeValues) {\r
174                 // Never match during route generation. This avoids the scenario where an IgnoreRoute with\r
175                 // fairly relaxed constraints ends up eagerly matching all generated URLs.\r
176                 return null;\r
177             }\r
178         }\r
179 \r
180     }\r
181 }\r