source: branches/Mainform refactoring/HeuristicLab.MainForm/3.2/MainFormManager.cs @ 2444

Last change on this file since 2444 was 2444, checked in by mkommend, 13 years ago

refactored MainFormManager to use linq syntax (ticket #771)

File size: 5.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21using System;
22using System.Collections.Generic;
23using System.Linq;
24using System.Text;
25using HeuristicLab.PluginInfrastructure;
26
27namespace HeuristicLab.MainForm {
28  public static class MainFormManager {
29    private static object locker;
30    private static IMainForm mainform;
31    private static Dictionary<Type, List<Type>> views;
32    private static Dictionary<Type, Type> defaultViews;
33
34    static MainFormManager() {
35      locker = new object();
36      views = new Dictionary<Type, List<Type>>();
37      defaultViews = new Dictionary<Type, Type>();
38    }
39
40    public static void RegisterMainForm(IMainForm mainform) {
41      lock (locker) {
42        if (MainFormManager.mainform == null) {
43          MainFormManager.mainform = mainform;
44
45          DiscoveryService ds = new DiscoveryService();
46          IEnumerable<Type> types =
47            from t in ds.GetTypes(typeof(IView))
48            where !t.IsAbstract && !t.IsInterface && !t.IsGenericType
49            select t;
50
51          foreach (Type t in types) {
52            foreach (Type viewableType in GetViewableType(t)) {
53              if (viewableType != null) {
54                if (!views.ContainsKey(viewableType))
55                  views[viewableType] = new List<Type>();
56                views[viewableType].Add(t);
57
58                object[] attributes = t.GetCustomAttributes(typeof(DefaultView), false);
59                if (attributes != null && attributes.Length == 1) {
60                  if (defaultViews.ContainsKey(viewableType))
61                    throw new ArgumentException("DefaultView for type " + viewableType + " is " + defaultViews[viewableType] +
62                      ". Can't register additional DefaultView " + t + ".");
63                  defaultViews[viewableType] = t;
64                }
65              }
66            }
67          }
68        } else
69          throw new ArgumentException("A mainform was already associated with the mainform manager.");
70      }
71    }
72
73    private static IEnumerable<Type> GetViewableType(Type t) {
74      IEnumerable<Type> interfaceTypes =
75       from type in t.GetInterfaces()
76       where type.Namespace == "HeuristicLab.MainForm" && type.Name.StartsWith("IView")  &&
77             type.IsGenericType && !type.IsGenericTypeDefinition
78       select type;
79
80      foreach (Type interfaceType in interfaceTypes) {     
81          yield return interfaceType.GetGenericArguments()[0];
82      }
83    }
84
85    public static IMainForm MainForm {
86      get { return mainform; }
87    }
88
89    public static T GetMainForm<T>() where T : IMainForm {
90      return (T)mainform;
91    }
92
93    public static IEnumerable<Type> GetViewTypes(Type viewableType) {
94      List<Type> viewsForType = new List<Type>();
95      foreach (KeyValuePair<Type, List<Type>> v in views) {
96        if (v.Key.IsAssignableFrom(viewableType))
97          viewsForType.AddRange(v.Value);
98      }
99      return viewsForType.Distinct();
100    }
101
102    public static bool ViewCanViewObject(IView view, object o) {
103      return GetViewTypes(o.GetType()).Contains(view.GetType());
104    }
105
106    public static Type GetDefaultViewType(Type viewableType) {
107      if (defaultViews.ContainsKey(viewableType))
108        return defaultViews[viewableType];
109      else {
110        List<Type> temp = (from t in defaultViews.Keys
111                           where t.IsAssignableFrom(viewableType)
112                           select t).ToList();
113        //no assignable type found
114        if (temp.Count == 0)
115          return null;
116        //only one assignable type found => return this one
117        else if (temp.Count == 1)
118          return defaultViews[temp[0]];
119        //more assignable types found => sort the types according to their assignable types
120        //and return most specific type => except there is a conflict
121        else {
122          temp.Sort(delegate(Type t1, Type t2) {
123            if (t1.IsAssignableFrom(t2))
124              return 1;
125            else if (t2.IsAssignableFrom(t1))
126              return -1;
127            else
128              return 0;
129          }
130          );
131          if (temp[1].IsAssignableFrom(temp[0]))
132            return defaultViews[temp[0]];
133          else
134            throw new Exception("Could not determine which is the default view for type " + viewableType.ToString() + ".");
135        }
136      }
137    }
138
139    public static IView<T> CreateDefaultView<T>(T objectToView) {
140      Type t = GetDefaultViewType(objectToView.GetType());
141      if (t == null)
142        return null;
143      else
144        return (IView<T>)Activator.CreateInstance(t);
145    }
146  }
147}
Note: See TracBrowser for help on using the repository browser.