diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/PluginLoader.cs | 195 |
1 files changed, 134 insertions, 61 deletions
diff --git a/OpenSim/Framework/PluginLoader.cs b/OpenSim/Framework/PluginLoader.cs index cd76153..9104958 100644 --- a/OpenSim/Framework/PluginLoader.cs +++ b/OpenSim/Framework/PluginLoader.cs | |||
@@ -37,11 +37,21 @@ namespace OpenSim.Framework | |||
37 | /// <summary> | 37 | /// <summary> |
38 | /// Exception thrown if an incorrect number of plugins are loaded | 38 | /// Exception thrown if an incorrect number of plugins are loaded |
39 | /// </summary> | 39 | /// </summary> |
40 | public class PluginCountInvalidException : Exception | 40 | public class PluginConstraintViolatedException : Exception |
41 | { | 41 | { |
42 | public PluginCountInvalidException () : base() {} | 42 | public PluginConstraintViolatedException () : base() {} |
43 | public PluginCountInvalidException (string msg) : base(msg) {} | 43 | public PluginConstraintViolatedException (string msg) : base(msg) {} |
44 | public PluginCountInvalidException (string msg, Exception e) : base(msg, e) {} | 44 | public PluginConstraintViolatedException (string msg, Exception e) : base(msg, e) {} |
45 | } | ||
46 | |||
47 | /// <summary> | ||
48 | /// Classes wishing to impose constraints on plugin loading must implement | ||
49 | /// this class and pass it to PluginLoader AddConstraint() | ||
50 | /// </summary> | ||
51 | public interface IPluginConstraint | ||
52 | { | ||
53 | bool Fail (string extpoint); | ||
54 | string Message { get; } | ||
45 | } | 55 | } |
46 | 56 | ||
47 | /// <summary> | 57 | /// <summary> |
@@ -49,26 +59,42 @@ namespace OpenSim.Framework | |||
49 | /// </summary> | 59 | /// </summary> |
50 | public class PluginLoader <T> : IDisposable where T : IPlugin | 60 | public class PluginLoader <T> : IDisposable where T : IPlugin |
51 | { | 61 | { |
52 | private struct Range | ||
53 | { | ||
54 | public int min; | ||
55 | public int max; | ||
56 | public Range (int n, int x) { min=n; max=x; } | ||
57 | } | ||
58 | |||
59 | private const int max_loadable_plugins = 10000; | 62 | private const int max_loadable_plugins = 10000; |
60 | 63 | ||
61 | private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
62 | private List<T> loaded = new List<T>(); | 64 | private List<T> loaded = new List<T>(); |
63 | private List<string> extpoints = new List<string>(); | 65 | private List<string> extpoints = new List<string>(); |
64 | private Dictionary<string,Range> constraints = new Dictionary<string,Range>(); | 66 | private PluginInitialiserBase initialiser; |
67 | private Dictionary<string,IPluginConstraint> constraints | ||
68 | = new Dictionary<string,IPluginConstraint>(); | ||
69 | |||
70 | private static readonly ILog log | ||
71 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
65 | 72 | ||
66 | public delegate void Initialiser (IPlugin p); | 73 | public PluginInitialiserBase Initialiser |
67 | private void default_initialiser_ (IPlugin p) { p.Initialise(); } | 74 | { |
75 | set { initialiser = value; } | ||
76 | get { return initialiser; } | ||
77 | } | ||
78 | |||
79 | public List<T> Plugins | ||
80 | { | ||
81 | get { return loaded; } | ||
82 | } | ||
83 | |||
84 | public PluginLoader () | ||
85 | { | ||
86 | Initialiser = new PluginInitialiserBase(); | ||
87 | } | ||
68 | 88 | ||
69 | public PluginLoader (string dir) | 89 | public PluginLoader (PluginInitialiserBase init) |
70 | { | 90 | { |
71 | AddPluginDir (dir); | 91 | Initialiser = init; |
92 | } | ||
93 | |||
94 | public PluginLoader (PluginInitialiserBase init, string dir) | ||
95 | { | ||
96 | Initialiser = init; | ||
97 | AddPluginDir (dir); | ||
72 | } | 98 | } |
73 | 99 | ||
74 | public void AddPluginDir (string dir) | 100 | public void AddPluginDir (string dir) |
@@ -84,65 +110,45 @@ namespace OpenSim.Framework | |||
84 | extpoints.Add (extpoint); | 110 | extpoints.Add (extpoint); |
85 | } | 111 | } |
86 | 112 | ||
87 | public void AddConstrainedExtensionPoint (string extpoint, int min, int max) | 113 | public void AddConstraint (string extpoint, IPluginConstraint cons) |
88 | { | 114 | { |
89 | constraints.Add (extpoint, new Range (min, max)); | 115 | constraints.Add (extpoint, cons); |
90 | AddExtensionPoint (extpoint); | ||
91 | } | 116 | } |
92 | 117 | ||
93 | public void LoadAll (Initialiser initialise) | 118 | public void Load (string extpoint, string dir) |
94 | { | 119 | { |
95 | foreach (string pt in extpoints) | 120 | AddPluginDir (dir); |
96 | Load (pt, initialise); | 121 | AddExtensionPoint (extpoint); |
97 | } | 122 | Load(); |
98 | |||
99 | public void Load (string extpoint) | ||
100 | { | ||
101 | Load (extpoint, default_initialiser_); | ||
102 | } | ||
103 | |||
104 | public void Load (string extpoint, Initialiser initialise) | ||
105 | { | ||
106 | int min = 0; | ||
107 | int max = max_loadable_plugins; | ||
108 | |||
109 | if (constraints.ContainsKey (extpoint)) | ||
110 | { | ||
111 | min = constraints[extpoint].min; | ||
112 | max = constraints[extpoint].max; | ||
113 | } | ||
114 | |||
115 | Load (extpoint, initialise, min, max); | ||
116 | } | 123 | } |
117 | 124 | ||
118 | public void Load (string extpoint, Initialiser initialise, int min, int max) | 125 | public void Load () |
119 | { | 126 | { |
120 | suppress_console_output_ (true); | 127 | suppress_console_output_ (true); |
121 | AddinManager.Registry.Update (null); | 128 | AddinManager.Registry.Update (null); |
122 | suppress_console_output_ (false); | 129 | suppress_console_output_ (false); |
123 | 130 | ||
124 | ExtensionNodeList ns = AddinManager.GetExtensionNodes(extpoint); | 131 | foreach (string ext in extpoints) |
125 | |||
126 | if ((ns.Count < min) || (ns.Count > max)) | ||
127 | throw new PluginCountInvalidException | ||
128 | ("The number of plugins for " + extpoint + | ||
129 | " is constrained to the interval [" + min + ", " + max + "]"); | ||
130 | |||
131 | foreach (TypeExtensionNode n in ns) | ||
132 | { | 132 | { |
133 | T p = (T) n.CreateInstance(); | 133 | if (constraints.ContainsKey (ext)) |
134 | initialise (p); | 134 | { |
135 | Plugins.Add (p); | 135 | IPluginConstraint cons = constraints [ext]; |
136 | 136 | if (cons.Fail (ext)) | |
137 | log.Info("[PLUGINS]: Loading plugin " + n.Path); | 137 | throw new PluginConstraintViolatedException (cons.Message); |
138 | } | ||
139 | |||
140 | ExtensionNodeList ns = AddinManager.GetExtensionNodes (ext); | ||
141 | foreach (TypeExtensionNode n in ns) | ||
142 | { | ||
143 | T p = (T) n.CreateInstance(); | ||
144 | Initialiser.Initialise (p); | ||
145 | Plugins.Add (p); | ||
146 | |||
147 | log.Info("[PLUGINS]: Loading plugin " + n.Path); | ||
148 | } | ||
138 | } | 149 | } |
139 | } | 150 | } |
140 | 151 | ||
141 | public List<T> Plugins | ||
142 | { | ||
143 | get { return loaded; } | ||
144 | } | ||
145 | |||
146 | public void Dispose () | 152 | public void Dispose () |
147 | { | 153 | { |
148 | foreach (T p in Plugins) | 154 | foreach (T p in Plugins) |
@@ -174,6 +180,73 @@ namespace OpenSim.Framework | |||
174 | System.Console.SetOut(prev_console_); | 180 | System.Console.SetOut(prev_console_); |
175 | } | 181 | } |
176 | } | 182 | } |
183 | } | ||
184 | |||
185 | public class PluginCountConstraint : IPluginConstraint | ||
186 | { | ||
187 | private int min; | ||
188 | private int max; | ||
189 | |||
190 | public PluginCountConstraint (int exact) | ||
191 | { | ||
192 | min = exact; | ||
193 | max = exact; | ||
194 | } | ||
195 | |||
196 | public PluginCountConstraint (int minimum, int maximum) | ||
197 | { | ||
198 | min = minimum; | ||
199 | max = maximum; | ||
200 | } | ||
201 | |||
202 | public string Message | ||
203 | { | ||
204 | get | ||
205 | { | ||
206 | return "The number of plugins is constrained to the interval [" | ||
207 | + min + ", " + max + "]"; | ||
208 | } | ||
209 | } | ||
177 | 210 | ||
211 | public bool Fail (string extpoint) | ||
212 | { | ||
213 | ExtensionNodeList ns = AddinManager.GetExtensionNodes (extpoint); | ||
214 | if ((ns.Count < min) || (ns.Count > max)) | ||
215 | return true; | ||
216 | else | ||
217 | return false; | ||
218 | } | ||
219 | } | ||
220 | |||
221 | public class PluginFilenameConstraint : IPluginConstraint | ||
222 | { | ||
223 | private string filename; | ||
224 | |||
225 | public PluginFilenameConstraint (string name) | ||
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 | } | ||
238 | |||
239 | public bool Fail (string extpoint) | ||
240 | { | ||
241 | ExtensionNodeList ns = AddinManager.GetExtensionNodes (extpoint); | ||
242 | if (ns.Count != 1) | ||
243 | return true; | ||
244 | |||
245 | string[] path = ns[0].Path.Split('/'); | ||
246 | if (path [path.Length-1] == filename) | ||
247 | return false; | ||
248 | |||
249 | return true; | ||
250 | } | ||
178 | } | 251 | } |
179 | } | 252 | } |