using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Composing;
using Umbraco.Web.WebApi;
namespace Umbraco.Web.Mvc
{
///
/// A custom area for controllers that are plugins
///
internal class PluginControllerArea : AreaRegistration
{
private readonly IGlobalSettings _globalSettings;
private readonly IEnumerable _surfaceControllers;
private readonly IEnumerable _apiControllers;
private readonly string _areaName;
///
/// The constructor accepts all types of plugin controllers and will verify that ALL of them have the same areaName assigned to them
/// based on their PluginControllerAttribute. If they are not the same an exception will be thrown.
///
///
///
public PluginControllerArea(IGlobalSettings globalSettings, IEnumerable pluginControllers)
{
_globalSettings = globalSettings;
var controllers = pluginControllers.ToArray();
if (controllers.Any(x => x.AreaName.IsNullOrWhiteSpace()))
{
throw new InvalidOperationException("Cannot create a PluginControllerArea unless all plugin controllers assigned have a PluginControllerAttribute assigned");
}
_areaName = controllers.First().AreaName;
foreach(var c in controllers)
{
if (c.AreaName != _areaName)
{
throw new InvalidOperationException("Cannot create a PluginControllerArea unless all plugin controllers assigned have the same AreaName. The first AreaName found was " + _areaName + " however, the controller of type " + c.GetType().FullName + " has an AreaName of " + c.AreaName);
}
}
//get the controllers
_surfaceControllers = controllers.Where(x => TypeHelper.IsTypeAssignableFrom(x.ControllerType));
_apiControllers = controllers.Where(x => TypeHelper.IsTypeAssignableFrom(x.ControllerType));
}
public override void RegisterArea(AreaRegistrationContext context)
{
MapRouteSurfaceControllers(context.Routes, _surfaceControllers);
MapRouteApiControllers(context.Routes, _apiControllers);
}
public override string AreaName
{
get { return _areaName; }
}
///
/// Registers all surface controller routes
///
///
///
///
/// The routes will be:
///
/// /Umbraco/[AreaName]/[ControllerName]/[Action]/[Id]
///
private void MapRouteSurfaceControllers(RouteCollection routes, IEnumerable surfaceControllers)
{
foreach (var s in surfaceControllers)
{
var route = this.RouteControllerPlugin(_globalSettings, s.ControllerName, s.ControllerType, routes, "", "Index", UrlParameter.Optional, "surface");
//set the route handler to our SurfaceRouteHandler
route.RouteHandler = new SurfaceRouteHandler();
}
}
///
/// Registers all api controller routes
///
///
///
private void MapRouteApiControllers(RouteCollection routes, IEnumerable apiControllers)
{
foreach (var s in apiControllers)
{
this.RouteControllerPlugin(_globalSettings, s.ControllerName, s.ControllerType, routes, "", "", UrlParameter.Optional, "api",
isMvc: false,
areaPathPrefix: s.IsBackOffice ? "backoffice" : null);
}
}
}
}