Free cookie consent management tool by TermsFeed Policy Generator

source: branches/1265_HeuristicLab.Visualization/HeuristicLab.Visualization/3.3/PrimitiveAttribute.cs @ 17328

Last change on this file since 17328 was 13717, checked in by bburlacu, 9 years ago

#1265: Updated license year to 2016.

File size: 5.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 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
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Reflection;
26using HeuristicLab.PluginInfrastructure;
27using HeuristicLab.Visualization;
28
29namespace HeuristicLab.Networks.Views.NetworkVisualization {
30  [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
31  public sealed class PrimitiveAttribute : Attribute {
32    public Type VisualizableType { get; private set; }
33    public bool IsDefaultPrimitive { get; set; }
34
35    private static readonly Dictionary<Type, Type> defaultPrimitives = new Dictionary<Type, Type>();
36
37    static PrimitiveAttribute() {
38      var primitiveTypes = ApplicationManager.Manager.GetTypes(typeof(IPrimitive), true, true)
39                                                     .Where(x => !x.IsAbstract && !x.IsInterface && HasPrimitiveAttribute(x));
40
41      foreach (var primitiveType in primitiveTypes) {
42        foreach (var visualizableType in GetDefaultVisualizableTypes(primitiveType)) {
43          if (defaultPrimitives.ContainsKey(visualizableType))
44            throw new ArgumentException("DefaultPrimitive for type " + visualizableType + " is " + defaultPrimitives[visualizableType] +
45              ". Can't register additional DefaultPrimitive " + primitiveType + ".");
46          defaultPrimitives[visualizableType] = primitiveType;
47        }
48      }
49    }
50
51    public PrimitiveAttribute(Type visualizableType) {
52      VisualizableType = visualizableType;
53    }
54
55    public PrimitiveAttribute(Type visualizableType, bool isDefaultPrimitive)
56      : this(visualizableType) {
57      IsDefaultPrimitive = isDefaultPrimitive;
58    }
59
60    public static bool HasPrimitiveAttribute(MemberInfo primitiveType) {
61      var attributes = primitiveType.GetCustomAttributes(typeof(PrimitiveAttribute), false);
62      return attributes.Any();
63    }
64
65    public static bool CanVisualizeType(MemberInfo primitiveType, Type visualizable) {
66      var attributes = (PrimitiveAttribute[])primitiveType.GetCustomAttributes(typeof(PrimitiveAttribute), false);
67      return attributes.Any(x => visualizable.IsAssignableFrom(x.VisualizableType));
68    }
69
70    public static IEnumerable<Type> GetDefaultVisualizableTypes(Type primitiveType) {
71      var attributes = (PrimitiveAttribute[])primitiveType.GetCustomAttributes(typeof(PrimitiveAttribute), false);
72      return attributes.Where(x => x.IsDefaultPrimitive).Select(x => x.VisualizableType);
73    }
74
75    public static IEnumerable<Type> GetVisualizableTypes(Type primitiveType) {
76      var attributes = (PrimitiveAttribute[])primitiveType.GetCustomAttributes(typeof(PrimitiveAttribute), false);
77      return attributes.Select(x => x.VisualizableType);
78    }
79
80    public static IPrimitive CreateDefaultPrimitive(Type visualizableType, params object[] args) {
81      var t = GetDefaultPrimitiveType(visualizableType);
82      if (t == null) return null;
83
84      return (IPrimitive)Activator.CreateInstance(t, args);
85    }
86
87    // TODO: add support for generic types
88    public static Type GetDefaultPrimitiveType(Type visualizableType) {
89      var type = visualizableType;
90      while (type != null) {
91        Type primitiveType;
92        if (defaultPrimitives.TryGetValue(type, out primitiveType))
93          return primitiveType;
94
95        var nonInheritedInterfaces = type.GetInterfaces().Where(i => !i.IsAssignableFrom(type.BaseType));
96        var interfaces = new HashSet<Type>(nonInheritedInterfaces);
97
98        while (interfaces.Any()) {
99          interfaces.RemoveWhere(i => interfaces.Any(x => x.GetInterfaces().Contains(i)));
100
101          var defaultViewList = defaultPrimitives.Keys.Where(interfaces.Contains).Select(x => defaultPrimitives[x]).ToList();
102
103          foreach (Type viewType in defaultViewList)
104            if (defaultViewList.Any(t => t.IsSubclassOf(viewType)))
105              defaultViewList.Remove(viewType);
106
107          if (defaultViewList.Count == 1) return defaultViewList[0];
108          if (defaultViewList.Count > 1)
109            throw new InvalidOperationException("Could not determine which is the default primitive for type " + visualizableType +
110              " because more than one implemented interfaces have a default primitive.");
111
112          interfaces = new HashSet<Type>(interfaces.SelectMany(i => i.GetInterfaces()));
113        }
114
115        type = type.BaseType;
116      }
117
118      return null;
119    }
120  }
121}
Note: See TracBrowser for help on using the repository browser.