Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Slave/3.4/PluginUtil.cs @ 6178

Last change on this file since 6178 was 5599, checked in by ascheibe, 14 years ago

#1233

  • rename 'Slave' namespace to 'SlaveCore' (and assemblies etc) to avoid problems with 'Slave' class
  • use svcutil (OKB-style)
File size: 6.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Reflection;
25using HeuristicLab.PluginInfrastructure;
26using System.Linq;
27using HeuristicLab.Common;
28
29namespace HeuristicLab.Clients.Hive.SlaveCore {
30  public static class PluginUtil {
31    #region Required Plugin Search
32
33    /// <summary>
34    /// Returns a list of plugins in which the type itself and all members
35    /// of the type are declared. Objectgraph is searched recursively.
36    /// </summary>
37    public static IEnumerable<IPluginDescription> GetDeclaringPlugins(IDeepCloneable obj) {
38      object clone = obj.Clone();
39      HashSet<Type> types = new HashSet<Type>();
40      HashSet<object> objects = new HashSet<object>();
41      string namespaceStart = "HeuristicLab.";
42      FindTypesInObject(clone, objects, types, namespaceStart, 10);
43      return GetDeclaringPlugins(types, namespaceStart);
44    }
45
46    /// <summary>
47    /// Returns the plugins (including dependencies) in which the given types are declared
48    /// </summary>
49    public static IEnumerable<IPluginDescription> GetDeclaringPlugins(IEnumerable<Type> types, string namespaceStart) {
50      HashSet<IPluginDescription> plugins = new HashSet<IPluginDescription>();
51      var hlTypes = types.Where(x => x.Namespace != null && x.Namespace.StartsWith(namespaceStart));
52      foreach (Type t in hlTypes) {
53        FindDeclaringPlugins(ApplicationManager.Manager.GetDeclaringPlugin(t), plugins);
54      }
55      return plugins;
56    }
57
58    /// <summary>
59    /// Finds the dependencies of the given plugin and adds it to the plugins hashset.
60    /// Also searches the dependencies recursively.
61    /// </summary>
62    public static void FindDeclaringPlugins(IPluginDescription plugin, HashSet<IPluginDescription> plugins) {
63      if (!plugins.Contains(plugin)) {
64        plugins.Add(plugin);
65        foreach (IPluginDescription dependency in plugin.Dependencies) {
66          FindDeclaringPlugins(dependency, plugins);
67        }
68      }
69    }
70
71    /// <summary>
72    /// Recursively finds all types used in type which are in a namespace which starts with namespaceStart
73    /// Be aware that search is not performed on attributes
74    /// </summary>
75    /// <param name="type">the type to be searched</param>
76    /// <param name="foundTypes">found types will be stored there, needed in order to avoid duplicates</param>
77    public static void FindTypes(Type type, HashSet<Type> foundTypes, string namespaceStart, int nonNamespaceSearchDepth) {
78      if (type.Namespace != null && type.Namespace.StartsWith(namespaceStart)) {
79        nonNamespaceSearchDepth = 10;
80      } else {
81        nonNamespaceSearchDepth--;
82      }
83
84      if (!foundTypes.Contains(type) && nonNamespaceSearchDepth > 0) {
85        foundTypes.Add(type);
86
87        if (type.IsGenericType) {
88          foreach (Type t in type.GetGenericArguments()) {
89            FindTypes(t, foundTypes, namespaceStart, nonNamespaceSearchDepth);
90          }
91        }
92
93        // constructors
94        foreach (ConstructorInfo info in type.GetConstructors()) {
95          foreach (ParameterInfo paramInfo in info.GetParameters()) {
96            FindTypes(paramInfo.ParameterType, foundTypes, namespaceStart, nonNamespaceSearchDepth);
97          }
98        }
99
100        // interfaces
101        foreach (Type t in type.GetInterfaces()) {
102          FindTypes(t, foundTypes, namespaceStart, nonNamespaceSearchDepth);
103        }
104
105        // events
106        foreach (EventInfo info in type.GetEvents()) {
107          FindTypes(info.EventHandlerType, foundTypes, namespaceStart, nonNamespaceSearchDepth);
108          FindTypes(info.DeclaringType, foundTypes, namespaceStart, nonNamespaceSearchDepth);
109        }
110
111        // methods
112        foreach (MethodInfo info in type.GetMethods()) {
113          foreach (ParameterInfo paramInfo in info.GetParameters()) {
114            FindTypes(paramInfo.ParameterType, foundTypes, namespaceStart, nonNamespaceSearchDepth);
115          }
116          FindTypes(info.ReturnType, foundTypes, namespaceStart, nonNamespaceSearchDepth);
117        }
118
119        // base type
120        if (type.BaseType != null) {
121          FindTypes(type.BaseType, foundTypes, namespaceStart, nonNamespaceSearchDepth);
122        }
123      }
124    }
125
126    public static void FindTypesInObject(object obj, HashSet<object> visitedObjects, HashSet<Type> types, string namespaceStart, int nonNamespaceSearchDepth) {
127      Type type = obj.GetType();
128      FindTypes(type, types, namespaceStart, nonNamespaceSearchDepth);
129
130      if (type.Namespace != null && type.Namespace.StartsWith(namespaceStart)) {
131        nonNamespaceSearchDepth = 10;
132      } else {
133        nonNamespaceSearchDepth--;
134      }
135
136      if (!visitedObjects.Contains(obj) && nonNamespaceSearchDepth > 0) {
137        visitedObjects.Add(obj);
138
139        // fields
140        foreach (FieldInfo info in GetAllFields(type)) {
141          var value = info.GetValue(obj);
142          if (value == null) {
143            FindTypes(info.FieldType, types, namespaceStart, nonNamespaceSearchDepth);
144          } else {
145            FindTypesInObject(value, visitedObjects, types, namespaceStart, nonNamespaceSearchDepth);
146          }
147        }
148      }
149    }
150
151    public static IEnumerable<FieldInfo> GetAllFields(Type t) {
152      BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy;
153      return t.GetFields(flags);
154    }
155    #endregion
156  }
157}
Note: See TracBrowser for help on using the repository browser.