8
// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
10
// Permission is hereby granted, free of charge, to any person obtaining
11
// a copy of this software and associated documentation files (the
12
// "Software"), to deal in the Software without restriction, including
13
// without limitation the rights to use, copy, modify, merge, publish,
14
// distribute, sublicense, and/or sell copies of the Software, and to
15
// permit persons to whom the Software is furnished to do so, subject to
16
// the following conditions:
18
// The above copyright notice and this permission notice shall be
19
// included in all copies or substantial portions of the Software.
21
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32
using System.Collections;
34
using System.Reflection;
36
using System.Resources;
37
using System.Globalization;
39
using Mono.Addins.Description;
40
using Mono.Addins.Localization;
44
public class RuntimeAddin
51
Assembly[] assemblies;
52
RuntimeAddin[] depAddins;
53
ResourceManager[] resourceManagers;
54
AddinLocalizer localizer;
56
internal RuntimeAddin()
60
internal Assembly[] Assemblies {
61
get { return assemblies; }
65
get { return Addin.GetIdName (id); }
68
public string Version {
69
get { return Addin.GetIdVersion (id); }
72
internal Addin Addin {
76
public override string ToString ()
78
return ainfo.ToString ();
81
void CreateResourceManagers ()
83
ArrayList managersList = new ArrayList ();
85
// Search for embedded resource files
86
foreach (Assembly asm in assemblies)
88
foreach (string res in asm.GetManifestResourceNames ()) {
89
if (res.EndsWith (".resources"))
90
managersList.Add (new ResourceManager (res.Substring (0, res.Length - ".resources".Length), asm));
94
resourceManagers = (ResourceManager[]) managersList.ToArray (typeof(ResourceManager));
97
public string GetResourceString (string name)
99
return (string) GetResourceObject (name, true, null);
102
public string GetResourceString (string name, bool throwIfNotFound)
104
return (string) GetResourceObject (name, throwIfNotFound, null);
107
public string GetResourceString (string name, bool throwIfNotFound, CultureInfo culture)
109
return (string) GetResourceObject (name, throwIfNotFound, culture);
112
public object GetResourceObject (string name)
114
return GetResourceObject (name, true, null);
117
public object GetResourceObject (string name, bool throwIfNotFound)
119
return GetResourceObject (name, throwIfNotFound, null);
122
public object GetResourceObject (string name, bool throwIfNotFound, CultureInfo culture)
124
if (resourceManagers == null)
125
CreateResourceManagers ();
127
// Look in resources of this add-in
128
foreach (ResourceManager manager in resourceManagers)
130
object t = manager.GetObject (name, culture);
135
// Look in resources of dependent add-ins
136
foreach (RuntimeAddin addin in depAddins)
138
object t = addin.GetResourceObject (name, false, culture);
144
throw new InvalidOperationException ("Resource object '" + name + "' not found in add-in '" + id + "'");
150
public Type GetType (string typeName)
152
return GetType (typeName, true);
155
public Type GetType (string typeName, bool throwIfNotFound)
157
// Look in the addin assemblies
159
Type at = Type.GetType (typeName, false);
163
foreach (Assembly asm in assemblies) {
164
Type t = asm.GetType (typeName, false);
169
// Look in the dependent add-ins
170
foreach (RuntimeAddin addin in depAddins) {
171
Type t = addin.GetType (typeName, false);
177
throw new InvalidOperationException ("Type '" + typeName + "' not found in add-in '" + id + "'");
181
public object CreateInstance (string typeName)
183
return CreateInstance (typeName, true);
186
public object CreateInstance (string typeName, bool throwIfNotFound)
188
Type type = GetType (typeName, throwIfNotFound);
192
return Activator.CreateInstance (type, true);
195
public string GetFilePath (string fileName)
197
return Path.Combine (baseDirectory, fileName);
200
public string PrivateDataPath {
202
if (privatePath == null) {
203
privatePath = ainfo.PrivateDataPath;
204
if (!Directory.Exists (privatePath))
205
Directory.CreateDirectory (privatePath);
211
public Stream GetResource (string resourceName)
213
return GetResource (resourceName, false);
216
public Stream GetResource (string resourceName, bool throwIfNotFound)
218
// Look in the addin assemblies
220
foreach (Assembly asm in assemblies) {
221
Stream res = asm.GetManifestResourceStream (resourceName);
226
// Look in the dependent add-ins
227
foreach (RuntimeAddin addin in depAddins) {
228
Stream res = addin.GetResource (resourceName);
234
throw new InvalidOperationException ("Resource '" + resourceName + "' not found in add-in '" + id + "'");
239
public AddinLocalizer Localizer {
241
if (localizer != null)
244
return AddinManager.DefaultLocalizer;
248
internal AddinDescription Load (Addin iad)
252
ArrayList plugList = new ArrayList ();
253
ArrayList asmList = new ArrayList ();
255
AddinDescription description = iad.Description;
256
id = description.AddinId;
257
baseDirectory = description.BasePath;
259
// Load the main modules
260
LoadModule (description.MainModule, description.Namespace, plugList, asmList);
262
// Load the optional modules, if the dependencies are present
263
foreach (ModuleDescription module in description.OptionalModules) {
264
if (CheckAddinDependencies (module))
265
LoadModule (module, description.Namespace, plugList, asmList);
268
depAddins = (RuntimeAddin[]) plugList.ToArray (typeof(RuntimeAddin));
269
assemblies = (Assembly[]) asmList.ToArray (typeof(Assembly));
271
if (description.Localizer != null) {
272
string cls = description.Localizer.GetAttribute ("type");
274
// First try getting one of the stock localizers. If none of found try getting the type.
275
object fob = CreateInstance ("Mono.Addins.Localization." + cls + "Localizer", false);
277
fob = CreateInstance (cls, true);
279
IAddinLocalizerFactory factory = fob as IAddinLocalizerFactory;
281
throw new InvalidOperationException ("Localizer factory type '" + cls + "' must implement IAddinLocalizerFactory");
282
localizer = new AddinLocalizer (factory.CreateLocalizer (this, description.Localizer));
288
void LoadModule (ModuleDescription module, string ns, ArrayList plugList, ArrayList asmList)
290
// Load the assemblies
291
foreach (string s in module.Assemblies) {
294
// don't load the assembly if it's already loaded
295
string asmPath = Path.Combine (baseDirectory, s);
296
foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies ()) {
297
// Sorry, you can't load addins from
298
// dynamic assemblies as get_Location
299
// throws a NotSupportedException
300
if (a is System.Reflection.Emit.AssemblyBuilder) {
304
if (a.Location == asmPath) {
311
asm = Assembly.LoadFrom (asmPath);
317
// Collect dependent ids
318
foreach (Dependency dep in module.Dependencies) {
319
AddinDependency pdep = dep as AddinDependency;
321
RuntimeAddin adn = AddinManager.SessionService.GetAddin (Addin.GetFullId (ns, pdep.AddinId, pdep.Version));
325
AddinManager.ReportError ("Add-in dependency not loaded: " + pdep.FullAddinId, module.ParentAddinDescription.AddinId, null, false);
330
internal void UnloadExtensions ()
332
// Create the extension points (but do not load them)
333
AddinDescription emap = Addin.Description;
334
if (emap == null) return;
336
foreach (ExtensionNodeSet rel in emap.ExtensionNodeSets)
337
AddinManager.SessionService.UnregisterNodeSet (rel);
340
bool CheckAddinDependencies (ModuleDescription module)
342
foreach (Dependency dep in module.Dependencies) {
343
AddinDependency pdep = dep as AddinDependency;
344
if (pdep != null && !AddinManager.SessionService.IsAddinLoaded (pdep.FullAddinId))