using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using Umbraco.Core;
using Umbraco.Core.Configuration;
namespace Umbraco.Web.Mvc
{
///
/// A custom area for controllers that are plugins
///
internal class PluginControllerArea : AreaRegistration
{
private readonly IEnumerable _surfaceControllers;
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(IEnumerable pluginControllers)
{
//TODO: When we have other future plugin controllers we need to combine them all into one list here to do our validation.
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 surface controllers
_surfaceControllers = controllers.Where(x => TypeHelper.IsTypeAssignableFrom(x.ControllerType));
}
public override void RegisterArea(AreaRegistrationContext context)
{
MapRouteSurfaceControllers(context.Routes, _surfaceControllers);
}
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)
{
this.RouteControllerPlugin(s.ControllerName, s.ControllerType, routes, "", "Index", UrlParameter.Optional, "surface");
}
}
}
}