diff options
Diffstat (limited to 'OpenSim/Framework/PluginLoader.cs')
-rw-r--r-- | OpenSim/Framework/PluginLoader.cs | 170 |
1 files changed, 103 insertions, 67 deletions
diff --git a/OpenSim/Framework/PluginLoader.cs b/OpenSim/Framework/PluginLoader.cs index 9104958..2d61b2c 100644 --- a/OpenSim/Framework/PluginLoader.cs +++ b/OpenSim/Framework/PluginLoader.cs | |||
@@ -32,6 +32,7 @@ using System.Reflection; | |||
32 | using log4net; | 32 | using log4net; |
33 | using Mono.Addins; | 33 | using Mono.Addins; |
34 | 34 | ||
35 | |||
35 | namespace OpenSim.Framework | 36 | namespace OpenSim.Framework |
36 | { | 37 | { |
37 | /// <summary> | 38 | /// <summary> |
@@ -50,8 +51,17 @@ namespace OpenSim.Framework | |||
50 | /// </summary> | 51 | /// </summary> |
51 | public interface IPluginConstraint | 52 | public interface IPluginConstraint |
52 | { | 53 | { |
53 | bool Fail (string extpoint); | ||
54 | string Message { get; } | 54 | string Message { get; } |
55 | bool Apply (string extpoint); | ||
56 | } | ||
57 | |||
58 | /// <summary> | ||
59 | /// Classes wishing to select specific plugins from a range of possible options | ||
60 | /// must implement this class and pass it to PluginLoader Load() | ||
61 | /// </summary> | ||
62 | public interface IPluginFilter | ||
63 | { | ||
64 | bool Apply (ExtensionNode plugin); | ||
55 | } | 65 | } |
56 | 66 | ||
57 | /// <summary> | 67 | /// <summary> |
@@ -64,18 +74,22 @@ namespace OpenSim.Framework | |||
64 | private List<T> loaded = new List<T>(); | 74 | private List<T> loaded = new List<T>(); |
65 | private List<string> extpoints = new List<string>(); | 75 | private List<string> extpoints = new List<string>(); |
66 | private PluginInitialiserBase initialiser; | 76 | private PluginInitialiserBase initialiser; |
77 | |||
67 | private Dictionary<string,IPluginConstraint> constraints | 78 | private Dictionary<string,IPluginConstraint> constraints |
68 | = new Dictionary<string,IPluginConstraint>(); | 79 | = new Dictionary<string,IPluginConstraint>(); |
69 | 80 | ||
81 | private Dictionary<string,IPluginFilter> filters | ||
82 | = new Dictionary<string,IPluginFilter>(); | ||
83 | |||
70 | private static readonly ILog log | 84 | private static readonly ILog log |
71 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 85 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
72 | 86 | ||
73 | public PluginInitialiserBase Initialiser | 87 | public PluginInitialiserBase Initialiser |
74 | { | 88 | { |
75 | set { initialiser = value; } | 89 | set { initialiser = value; } |
76 | get { return initialiser; } | 90 | get { return initialiser; } |
77 | } | 91 | } |
78 | 92 | ||
79 | public List<T> Plugins | 93 | public List<T> Plugins |
80 | { | 94 | { |
81 | get { return loaded; } | 95 | get { return loaded; } |
@@ -84,25 +98,19 @@ namespace OpenSim.Framework | |||
84 | public PluginLoader () | 98 | public PluginLoader () |
85 | { | 99 | { |
86 | Initialiser = new PluginInitialiserBase(); | 100 | Initialiser = new PluginInitialiserBase(); |
101 | initialise_plugin_dir_ ("."); | ||
87 | } | 102 | } |
88 | 103 | ||
89 | public PluginLoader (PluginInitialiserBase init) | 104 | public PluginLoader (PluginInitialiserBase init) |
90 | { | 105 | { |
91 | Initialiser = init; | 106 | Initialiser = init; |
107 | initialise_plugin_dir_ ("."); | ||
92 | } | 108 | } |
93 | 109 | ||
94 | public PluginLoader (PluginInitialiserBase init, string dir) | 110 | public PluginLoader (PluginInitialiserBase init, string dir) |
95 | { | 111 | { |
96 | Initialiser = init; | 112 | Initialiser = init; |
97 | AddPluginDir (dir); | 113 | initialise_plugin_dir_ (dir); |
98 | } | ||
99 | |||
100 | public void AddPluginDir (string dir) | ||
101 | { | ||
102 | suppress_console_output_ (true); | ||
103 | AddinManager.Initialize (dir); | ||
104 | AddinManager.Registry.Update (null); | ||
105 | suppress_console_output_ (false); | ||
106 | } | 114 | } |
107 | 115 | ||
108 | public void AddExtensionPoint (string extpoint) | 116 | public void AddExtensionPoint (string extpoint) |
@@ -114,50 +122,88 @@ namespace OpenSim.Framework | |||
114 | { | 122 | { |
115 | constraints.Add (extpoint, cons); | 123 | constraints.Add (extpoint, cons); |
116 | } | 124 | } |
117 | 125 | ||
118 | public void Load (string extpoint, string dir) | 126 | public void AddFilter (string extpoint, IPluginFilter filter) |
127 | { | ||
128 | filters.Add (extpoint, filter); | ||
129 | } | ||
130 | |||
131 | public void Load (string extpoint) | ||
119 | { | 132 | { |
120 | AddPluginDir (dir); | ||
121 | AddExtensionPoint (extpoint); | 133 | AddExtensionPoint (extpoint); |
122 | Load(); | 134 | Load(); |
123 | } | 135 | } |
124 | 136 | ||
125 | public void Load () | 137 | public void Load () |
126 | { | 138 | { |
127 | suppress_console_output_ (true); | ||
128 | AddinManager.Registry.Update (null); | ||
129 | suppress_console_output_ (false); | ||
130 | |||
131 | foreach (string ext in extpoints) | 139 | foreach (string ext in extpoints) |
132 | { | 140 | { |
141 | log.Info("[PLUGINS]: Loading extension point " + ext); | ||
142 | |||
133 | if (constraints.ContainsKey (ext)) | 143 | if (constraints.ContainsKey (ext)) |
134 | { | 144 | { |
135 | IPluginConstraint cons = constraints [ext]; | 145 | IPluginConstraint cons = constraints [ext]; |
136 | if (cons.Fail (ext)) | 146 | if (cons.Apply (ext)) |
137 | throw new PluginConstraintViolatedException (cons.Message); | 147 | log.Error ("[PLUGINS]: " + ext + " failed constraint: " + cons.Message); |
138 | } | 148 | } |
139 | 149 | ||
140 | ExtensionNodeList ns = AddinManager.GetExtensionNodes (ext); | 150 | IPluginFilter filter = null; |
141 | foreach (TypeExtensionNode n in ns) | 151 | |
142 | { | 152 | if (filters.ContainsKey (ext)) |
143 | T p = (T) n.CreateInstance(); | 153 | filter = filters [ext]; |
144 | Initialiser.Initialise (p); | ||
145 | Plugins.Add (p); | ||
146 | 154 | ||
147 | log.Info("[PLUGINS]: Loading plugin " + n.Path); | 155 | foreach (TypeExtensionNode node in AddinManager.GetExtensionNodes (ext)) |
156 | { | ||
157 | log.Info("[PLUGINS]: Trying plugin " + node.Path); | ||
158 | |||
159 | if ((filter != null) && (filter.Apply (node) == false)) | ||
160 | continue; | ||
161 | |||
162 | T plugin = (T) node.CreateInstance(); | ||
163 | Initialiser.Initialise (plugin); | ||
164 | Plugins.Add (plugin); | ||
148 | } | 165 | } |
149 | } | 166 | } |
150 | } | 167 | } |
151 | 168 | ||
152 | public void Dispose () | 169 | public void Dispose () |
153 | { | 170 | { |
154 | foreach (T p in Plugins) | 171 | foreach (T plugin in Plugins) |
155 | p.Dispose (); | 172 | plugin.Dispose (); |
156 | } | 173 | } |
157 | 174 | ||
158 | public void ClearCache() | 175 | private void initialise_plugin_dir_ (string dir) |
159 | { | 176 | { |
160 | // The Mono addin manager (in Mono.Addins.dll version 0.2.0.0) occasionally seems to corrupt its addin cache | 177 | if (AddinManager.IsInitialized == true) |
178 | return; | ||
179 | |||
180 | log.Info("[PLUGINS]: Initialzing"); | ||
181 | |||
182 | AddinManager.AddinLoadError += on_addinloaderror_; | ||
183 | AddinManager.AddinLoaded += on_addinloaded_; | ||
184 | |||
185 | clear_registry_(); | ||
186 | |||
187 | suppress_console_output_ (true); | ||
188 | AddinManager.Initialize (dir); | ||
189 | AddinManager.Registry.Update (null); | ||
190 | suppress_console_output_ (false); | ||
191 | } | ||
192 | |||
193 | private void on_addinloaded_(object sender, AddinEventArgs args) | ||
194 | { | ||
195 | log.Info ("[PLUGINS]: Plugin Loaded: " + args.AddinId); | ||
196 | } | ||
197 | |||
198 | private void on_addinloaderror_(object sender, AddinErrorEventArgs args) | ||
199 | { | ||
200 | log.Error ("[PLUGINS]: Plugin Error: " + args.Message); | ||
201 | } | ||
202 | |||
203 | private void clear_registry_ () | ||
204 | { | ||
205 | // The Mono addin manager (in Mono.Addins.dll version 0.2.0.0) | ||
206 | // occasionally seems to corrupt its addin cache | ||
161 | // Hence, as a temporary solution we'll remove it before each startup | 207 | // Hence, as a temporary solution we'll remove it before each startup |
162 | if (Directory.Exists("addin-db-000")) | 208 | if (Directory.Exists("addin-db-000")) |
163 | Directory.Delete("addin-db-000", true); | 209 | Directory.Delete("addin-db-000", true); |
@@ -182,6 +228,9 @@ namespace OpenSim.Framework | |||
182 | } | 228 | } |
183 | } | 229 | } |
184 | 230 | ||
231 | /// <summary> | ||
232 | /// Constraint that bounds the number of plugins to be loaded. | ||
233 | /// </summary> | ||
185 | public class PluginCountConstraint : IPluginConstraint | 234 | public class PluginCountConstraint : IPluginConstraint |
186 | { | 235 | { |
187 | private int min; | 236 | private int min; |
@@ -208,45 +257,32 @@ namespace OpenSim.Framework | |||
208 | } | 257 | } |
209 | } | 258 | } |
210 | 259 | ||
211 | public bool Fail (string extpoint) | 260 | public bool Apply (string extpoint) |
212 | { | 261 | { |
213 | ExtensionNodeList ns = AddinManager.GetExtensionNodes (extpoint); | 262 | int count = AddinManager.GetExtensionNodes (extpoint).Count; |
214 | if ((ns.Count < min) || (ns.Count > max)) | ||
215 | return true; | ||
216 | else | ||
217 | return false; | ||
218 | } | ||
219 | } | ||
220 | 263 | ||
221 | public class PluginFilenameConstraint : IPluginConstraint | 264 | if ((count < min) || (count > max)) |
222 | { | 265 | throw new PluginConstraintViolatedException (Message); |
223 | private string filename; | ||
224 | 266 | ||
225 | public PluginFilenameConstraint (string name) | 267 | return true; |
226 | { | ||
227 | filename = name; | ||
228 | |||
229 | } | ||
230 | |||
231 | public string Message | ||
232 | { | ||
233 | get | ||
234 | { | ||
235 | return "The plugin must have the following name: " + filename; | ||
236 | } | ||
237 | } | 268 | } |
269 | } | ||
270 | |||
271 | /// <summary> | ||
272 | /// Filters out which plugin to load based on its "Id", which is name given by the namespace or by Mono.Addins. | ||
273 | /// </summary> | ||
274 | public class PluginIdFilter : IPluginFilter | ||
275 | { | ||
276 | private string id; | ||
238 | 277 | ||
239 | public bool Fail (string extpoint) | 278 | public PluginIdFilter (string id) |
240 | { | 279 | { |
241 | ExtensionNodeList ns = AddinManager.GetExtensionNodes (extpoint); | 280 | this.id = id; |
242 | if (ns.Count != 1) | 281 | } |
243 | return true; | ||
244 | 282 | ||
245 | string[] path = ns[0].Path.Split('/'); | 283 | public bool Apply (ExtensionNode plugin) |
246 | if (path [path.Length-1] == filename) | 284 | { |
247 | return false; | 285 | return (plugin.Id == id); |
248 | |||
249 | return true; | ||
250 | } | 286 | } |
251 | } | 287 | } |
252 | } | 288 | } |