// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Web.Routing;
namespace System.Web.Mvc.Routing
{
internal static class DirectRouteExtensions
{
///
/// Gets the precedence or this route.
///
public static decimal GetPrecedence(this RouteData routeData)
{
return GetRouteDataTokenValue(routeData, RouteDataTokenKeys.Precedence);
}
///
/// Gets the precedence or this route.
///
public static decimal GetPrecedence(this Route route)
{
return GetRouteDataTokenValue(route, RouteDataTokenKeys.Precedence);
}
///
/// Sets the precedence of this Route.
///
public static void SetPrecedence(this Route route, decimal precedence)
{
SetRouteDataTokenValue(route, RouteDataTokenKeys.Precedence, precedence);
}
///
/// Gets the order or this route.
///
public static int GetOrder(this RouteData routeData)
{
return GetRouteDataTokenValue(routeData, RouteDataTokenKeys.Order);
}
///
/// Gets the order or this route.
///
public static int GetOrder(this Route route)
{
return GetRouteDataTokenValue(route, RouteDataTokenKeys.Order);
}
///
/// Sets the order of this Route.
///
public static void SetOrder(this Route route, int order)
{
SetRouteDataTokenValue(route, RouteDataTokenKeys.Order, order);
}
///
/// Gets a value indicating whether or not the route is a direct route to an action.
///
public static bool GetTargetIsAction(this RouteData routeData)
{
return GetRouteDataTokenValue(routeData, RouteDataTokenKeys.TargetIsAction);
}
///
/// Gets a value indicating whether or not the route is a direct route to an action.
///
public static bool GetTargetIsAction(this Route route)
{
return GetRouteDataTokenValue(route, RouteDataTokenKeys.TargetIsAction);
}
///
/// Sets a value indicating whether or not the route is a direct route to an action.
///
public static void SetTargetIsAction(this Route route, bool targetIsAction)
{
SetRouteDataTokenValue(route, RouteDataTokenKeys.TargetIsAction, targetIsAction);
}
///
/// Gets the ControllerDescriptor that matches this Route.
///
public static ControllerDescriptor GetTargetControllerDescriptor(this Route route)
{
var actions = GetTargetActionDescriptors(route);
ControllerDescriptor controller = null;
foreach (var action in actions)
{
if (controller == null)
{
controller = action.ControllerDescriptor;
}
else if (controller != action.ControllerDescriptor)
{
// Don't provide a single controller descriptor if multiple controllers match.
return null;
}
}
return controller;
}
///
/// Gets the ControllerDescriptor that matches this Route.
///
public static ControllerDescriptor GetTargetControllerDescriptor(this RouteData routeData)
{
var actions = GetTargetActionDescriptors(routeData);
ControllerDescriptor controller = null;
foreach (var action in actions)
{
if (controller == null)
{
controller = action.ControllerDescriptor;
}
else if (controller != action.ControllerDescriptor)
{
// Don't provide a single controller descriptor if multiple controllers match.
return null;
}
}
return controller;
}
public static Type GetTargetControllerType(this RouteData routeData)
{
ControllerDescriptor controllerDescriptor = routeData.GetTargetControllerDescriptor();
return controllerDescriptor == null ? null : controllerDescriptor.ControllerType;
}
///
/// Gets the target actions that can be matched if this route is matched.
///
public static ActionDescriptor[] GetTargetActionDescriptors(this RouteData routeData)
{
return GetRouteDataTokenValue(routeData, RouteDataTokenKeys.Actions);
}
///
/// Gets the target actions that can be matched if this route is matched.
///
public static ActionDescriptor[] GetTargetActionDescriptors(this Route route)
{
return GetRouteDataTokenValue(route, RouteDataTokenKeys.Actions);
}
///
/// Sets the target actions that can be matched if this route is matched.
///
public static void SetTargetActionDescriptors(this Route route, ActionDescriptor[] actionDescriptors)
{
if (actionDescriptors == null || actionDescriptors.Length == 0)
{
throw Error.ParameterCannotBeNullOrEmpty("actionDescriptors");
}
SetRouteDataTokenValue(route, RouteDataTokenKeys.Actions, actionDescriptors);
}
public static bool HasDirectRouteMatch(this RouteData routeData)
{
if (routeData == null)
{
throw Error.ArgumentNull("routeData");
}
return routeData.Values.ContainsKey(RouteDataTokenKeys.DirectRouteMatches);
}
public static IEnumerable GetDirectRouteMatches(this RouteData routeData)
{
return GetRouteDataValue>(routeData, RouteDataTokenKeys.DirectRouteMatches) ?? Enumerable.Empty();
}
public static void SetDirectRouteMatches(this RouteData routeData, IEnumerable matches)
{
if (matches == null || !matches.Any())
{
throw Error.ParameterCannotBeNullOrEmpty("matches");
}
SetRouteDataValue(routeData, RouteDataTokenKeys.DirectRouteMatches, matches);
}
public static bool IsDirectRoute(this RouteBase routeBase)
{
Route route = routeBase as Route;
if (route == null)
{
return false;
}
else
{
// All direct routes need to have actions associated.
return route.GetTargetActionDescriptors() != null;
}
}
private static T GetRouteDataTokenValue(this Route route, string key)
{
if (route == null)
{
throw Error.ArgumentNull("route");
}
if (key == null)
{
throw Error.ArgumentNull("key");
}
T value;
if (route.DataTokens != null && route.DataTokens.TryGetValue(key, out value))
{
return value;
}
else
{
return default(T);
}
}
private static T GetRouteDataTokenValue(this RouteData routeData, string key)
{
if (routeData == null)
{
throw Error.ArgumentNull("route");
}
if (key == null)
{
throw Error.ArgumentNull("key");
}
return GetRouteDataTokenValue(routeData.Route as Route, key);
}
private static void SetRouteDataTokenValue(this Route route, string key, T value)
{
if (route == null)
{
throw Error.ArgumentNull("route");
}
if (key == null)
{
throw Error.ArgumentNull("key");
}
if (route.DataTokens == null)
{
route.DataTokens = new RouteValueDictionary();
}
route.DataTokens[key] = value;
}
private static T GetRouteDataValue(this RouteData routeData, string key)
{
if (routeData == null)
{
throw Error.ArgumentNull("routeData");
}
if (key == null)
{
throw Error.ArgumentNull("key");
}
T value;
if (routeData.Values.TryGetValue(key, out value))
{
return value;
}
else
{
return default(T);
}
}
private static void SetRouteDataValue(this RouteData routeData, string key, T value)
{
if (routeData == null)
{
throw Error.ArgumentNull("routeData");
}
if (key == null)
{
throw Error.ArgumentNull("key");
}
routeData.Values[key] = value;
}
}
}