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 |
|
---|
22 | using System;
|
---|
23 | using System.Collections.Generic;
|
---|
24 | using System.Reflection;
|
---|
25 | using HeuristicLab.PluginInfrastructure;
|
---|
26 | using System.Linq;
|
---|
27 | using HeuristicLab.Common;
|
---|
28 |
|
---|
29 | namespace 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 | }
|
---|