Go to the documentation of this file.00001 using System;
00002 using System.Collections.Generic;
00003 using System.Linq;
00004 using System.Web.Mvc;
00005 using N2.Definitions;
00006 using N2.Engine;
00007
00008 namespace N2.Web.Mvc
00009 {
00010 [Service(typeof(IControllerMapper))]
00011 public class ControllerMapper : IControllerMapper
00012 {
00013 private readonly IDictionary<Type, string> _controllerMap = new Dictionary<Type, string>();
00014 private readonly IDictionary<string, string[]> _controllerActionMap = new Dictionary<string, string[]>();
00015
00016 public ControllerMapper(ITypeFinder typeFinder, IDefinitionManager definitionManager)
00017 {
00018 IList<ControlsAttribute> controllerDefinitions = FindControllers(typeFinder);
00019 foreach (ItemDefinition id in definitionManager.GetDefinitions())
00020 {
00021 IAdapterDescriptor controllerDefinition = GetControllerFor(id.ItemType, controllerDefinitions);
00022 if(controllerDefinition != null)
00023 {
00024 ControllerMap[id.ItemType] = controllerDefinition.ControllerName;
00025
00026
00027
00028
00029 foreach (var finder in PathDictionary.GetFinders(id.ItemType).Where(f => f is ActionResolver))
00030 PathDictionary.RemoveFinder(id.ItemType, finder);
00031
00032
00033 var methods = new ReflectedControllerDescriptor(controllerDefinition.AdapterType)
00034 .GetCanonicalActions()
00035 .Select(m => m.ActionName).ToArray();
00036 var actionResolver = new ActionResolver(this, methods);
00037
00038 _controllerActionMap[controllerDefinition.ControllerName] = methods;
00039
00040 PathDictionary.PrependFinder(id.ItemType, actionResolver);
00041 }
00042 }
00043 }
00044
00045 public string GetControllerName(Type type)
00046 {
00047 string name;
00048 ControllerMap.TryGetValue(type, out name);
00049 return name;
00050 }
00051
00052 public bool ControllerHasAction(string controllerName, string actionName)
00053 {
00054 if(!_controllerActionMap.ContainsKey(controllerName))
00055 return false;
00056
00057 foreach(var action in _controllerActionMap[controllerName])
00058 {
00059 if(String.Equals(action, actionName, StringComparison.InvariantCultureIgnoreCase))
00060 return true;
00061 }
00062 return false;
00063 }
00064
00065 private IDictionary<Type, string> ControllerMap
00066 {
00067 get { return _controllerMap; }
00068 }
00069
00070 private static IAdapterDescriptor GetControllerFor(Type itemType, IList<ControlsAttribute> controllerDefinitions)
00071 {
00072 foreach (ControlsAttribute controllerDefinition in controllerDefinitions)
00073 {
00074 if (controllerDefinition.ItemType.IsAssignableFrom(itemType))
00075 {
00076 return controllerDefinition;
00077 }
00078 }
00079 return null;
00080 }
00081
00082 private static IList<ControlsAttribute> FindControllers(ITypeFinder typeFinder)
00083 {
00084 var controllerLookup = new Dictionary<Type, ControlsAttribute>();
00085 foreach (Type controllerType in typeFinder.Find(typeof(IController)))
00086 {
00087 foreach (ControlsAttribute attr in controllerType.GetCustomAttributes(typeof(ControlsAttribute), false))
00088 {
00089 if (controllerLookup.ContainsKey(attr.ItemType))
00090 throw new N2Exception("Duplicate controller " + controllerType.Name + " declared for item type " +
00091 attr.ItemType.Name +
00092 " The controller " + controllerLookup[attr.ItemType].AdapterType.Name +
00093 " already handles this type and two controllers cannot handle the same item type.");
00094
00095 attr.AdapterType = controllerType;
00096 controllerLookup.Add(attr.ItemType, attr);
00097 }
00098 }
00099
00100 var controllerDefinitions = new List<ControlsAttribute>(controllerLookup.Values);
00101 controllerDefinitions.Sort();
00102
00103 return controllerDefinitions;
00104 }
00105 }
00106 }