diff options
author | Lluis Sanchez <lluis@novell.com> | 2010-05-20 18:29:56 +0400 |
---|---|---|
committer | Lluis Sanchez <lluis@novell.com> | 2010-05-20 18:29:56 +0400 |
commit | f1183df2745fd63a144c8905af762da7f59a4501 (patch) | |
tree | bb728e6128a60ab921376951dd8ab9d231fcd11f /Mono.Addins | |
parent | afea25471e31dca856114f77409b1b4d82fe6a71 (diff) | |
parent | dbb5c3ab0c608d00c499ae69194180e81745c855 (diff) |
* Mono.Addins/Mono.Addins.Database/IAssemblyReflector.cs:
* Mono.Addins/Mono.Addins.Database/DefaultAssemblyReflector.cs:
* Mono.Addins.CecilReflector/Mono.Addins.CecilReflector/Reflector.cs:
Added methods for getting resources from an assembly.
* Mono.Addins/Makefile.am:
* Mono.Addins/Mono.Addins.csproj: Updated.
* Mono.Addins/Mono.Addins/TreeNode.cs:
* Mono.Addins/Mono.Addins/AddinEngine.cs:
* Mono.Addins/Mono.Addins/RuntimeAddin.cs:
* Mono.Addins/Mono.Addins/AddinManager.cs:
* Mono.Addins/Mono.Addins/ExtensionTree.cs:
* Mono.Addins/Mono.Addins/ExtensionNode.cs:
* Mono.Addins/Mono.Addins/ConditionType.cs:
* Mono.Addins/Mono.Addins/AddinRegistry.cs:
* Mono.Addins/Mono.Addins/ExtensionContext.cs:
* Mono.Addins/Mono.Addins/AddinSessionService.cs:
* Mono.Addins/Mono.Addins.Database/AddinDatabase.cs:
* Mono.Addins/Mono.Addins.Description/Dependency.cs:
* Mono.Addins/Mono.Addins.Description/AddinDependency.cs:
* Mono.Addins/Mono.Addins.Description/NativeDependency.cs:
* Mono.Addins/Mono.Addins.Description/AssemblyDependency.cs: New
AddinEngine class, which can be used to support several engines in a
single domain.
* Mono.Addins/Mono.Addins/AddinAttribute.cs:
* Mono.Addins/Mono.Addins/AddinModuleAttribute.cs:
* Mono.Addins/Mono.Addins.Database/AddinScanner.cs:
* Mono.Addins/Mono.Addins/ImportAddinFileAttribute.cs:
* Mono.Addins/Mono.Addins/ImportAddinAssemblyAttribute.cs: Added
support for new add-in declaration attributes.
* Mono.Addins/Mono.Addins/AddinCategoryAttribute.cs: Removed.
* Mono.Addins/Mono.Addins/ExtensionPointAttribute.cs:
* Mono.Addins/Mono.Addins/TypeExtensionPointAttribute.cs: Use a better
name for the custom attribute type property.
svn path=/trunk/mono-addins/; revision=157628
Diffstat (limited to 'Mono.Addins')
26 files changed, 671 insertions, 344 deletions
diff --git a/Mono.Addins/ChangeLog b/Mono.Addins/ChangeLog index 8d8e7d8..119c163 100644 --- a/Mono.Addins/ChangeLog +++ b/Mono.Addins/ChangeLog @@ -1,3 +1,43 @@ +2010-05-20 Lluis Sanchez Gual <lluis@novell.com> + + * Makefile.am: + * Mono.Addins.csproj: Updated. + + * Mono.Addins/TreeNode.cs: + * Mono.Addins/AddinEngine.cs: + * Mono.Addins/RuntimeAddin.cs: + * Mono.Addins/AddinManager.cs: + * Mono.Addins/ExtensionTree.cs: + * Mono.Addins/ExtensionNode.cs: + * Mono.Addins/ConditionType.cs: + * Mono.Addins/AddinRegistry.cs: + * Mono.Addins/ExtensionContext.cs: + * Mono.Addins/AddinSessionService.cs: + * Mono.Addins.Database/AddinDatabase.cs: + * Mono.Addins.Description/Dependency.cs: + * Mono.Addins.Description/AddinDependency.cs: + * Mono.Addins.Description/NativeDependency.cs: + * Mono.Addins.Description/AssemblyDependency.cs: New + AddinEngine class, which can be used to support several + engines in a single domain. + + * Mono.Addins/AddinAttribute.cs: + * Mono.Addins/AddinModuleAttribute.cs: + * Mono.Addins.Database/AddinScanner.cs: + * Mono.Addins/ImportAddinFileAttribute.cs: + * Mono.Addins/ImportAddinAssemblyAttribute.cs: Added support + for new add-in declaration attributes. + + * Mono.Addins/AddinCategoryAttribute.cs: Removed. + + * Mono.Addins/ExtensionPointAttribute.cs: + * Mono.Addins/TypeExtensionPointAttribute.cs: Use a better + name for the custom attribute type property. + + * Mono.Addins.Database/IAssemblyReflector.cs: + * Mono.Addins.Database/DefaultAssemblyReflector.cs: Added + methods for getting resources from an assembly. + 2010-03-30 Lluis Sanchez Gual <lluis@novell.com> * Mono.Addins.Serialization/BinaryXmlReader.cs: Properly diff --git a/Mono.Addins/Makefile.am b/Mono.Addins/Makefile.am index 57f4272..a9f4937 100644 --- a/Mono.Addins/Makefile.am +++ b/Mono.Addins/Makefile.am @@ -69,17 +69,17 @@ FILES = \ Mono.Addins/Addin.cs \ Mono.Addins/AddinAttribute.cs \ Mono.Addins/AddinAuthorAttribute.cs \ - Mono.Addins/AddinCategoryAttribute.cs \ Mono.Addins/AddinDependencyAttribute.cs \ + Mono.Addins/AddinEngine.cs \ Mono.Addins/AddinErrorEventArgs.cs \ Mono.Addins/AddinEventArgs.cs \ Mono.Addins/AddinInfo.cs \ Mono.Addins/AddinLocalizer.cs \ Mono.Addins/AddinLocalizerGettextAttribute.cs \ Mono.Addins/AddinManager.cs \ + Mono.Addins/AddinModuleAttribute.cs \ Mono.Addins/AddinRegistry.cs \ Mono.Addins/AddinRootAttribute.cs \ - Mono.Addins/AddinSessionService.cs \ Mono.Addins/ConditionType.cs \ Mono.Addins/ConsoleProgressStatus.cs \ Mono.Addins/CustomExtensionAttribute.cs \ @@ -94,6 +94,8 @@ FILES = \ Mono.Addins/ExtensionTree.cs \ Mono.Addins/GettextCatalog.cs \ Mono.Addins/IAddinInstaller.cs \ + Mono.Addins/ImportAddinAssemblyAttribute.cs \ + Mono.Addins/ImportAddinFileAttribute.cs \ Mono.Addins/InstanceExtensionNode.cs \ Mono.Addins/IProgressStatus.cs \ Mono.Addins/MissingDependencyException.cs \ diff --git a/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs b/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs index dbbf4c1..6f83f53 100644 --- a/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs +++ b/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs @@ -59,9 +59,11 @@ namespace Mono.Addins.Database DatabaseConfiguration config = null; AddinRegistry registry; int lastDomainId; + AddinEngine addinEngine; - public AddinDatabase (AddinRegistry registry) + public AddinDatabase (AddinEngine addinEngine, AddinRegistry registry) { + this.addinEngine = addinEngine; this.registry = registry; addinDbDir = Path.Combine (registry.RegistryPath, "addin-db-" + VersionTag); fileDatabase = new FileDatabase (AddinDbDir); @@ -396,8 +398,8 @@ namespace Mono.Addins.Database Configuration.SetStatus (id, true, ainfo.AddinInfo.EnabledByDefault); SaveConfiguration (); - if (AddinManager.IsInitialized && AddinManager.Registry.RegistryPath == registry.RegistryPath) - AddinManager.SessionService.ActivateAddin (id); + if (addinEngine != null && addinEngine.IsInitialized) + addinEngine.ActivateAddin (id); } public void DisableAddin (string domain, string id) @@ -447,8 +449,8 @@ namespace Mono.Addins.Database throw; } - if (AddinManager.IsInitialized && AddinManager.Registry.RegistryPath == registry.RegistryPath) - AddinManager.SessionService.UnloadAddin (id); + if (addinEngine != null && addinEngine.IsInitialized) + addinEngine.UnloadAddin (id); } internal string GetDescriptionPath (string domain, string id) @@ -817,7 +819,8 @@ namespace Mono.Addins.Database rootSetupInfos = null; hostIndex = null; cachedAddinSetupInfos.Clear (); - AddinManager.SessionService.ResetCachedData (); + if (addinEngine != null) + addinEngine.ResetCachedData (); } @@ -917,7 +920,7 @@ namespace Mono.Addins.Database monitor.ReportError ("The add-in database could not be updated. It may be due to file corruption. Try running the setup repair utility", null); // Update the currently loaded add-ins - if (changesFound && domain != null && AddinManager.IsInitialized && AddinManager.Registry.RegistryPath == registry.RegistryPath) { + if (changesFound && domain != null && addinEngine != null && addinEngine.IsInitialized) { Hashtable newInstalled = new Hashtable (); foreach (Addin ainfo in GetInstalledAddins (domain, AddinType.All)) { newInstalled [ainfo.Id] = ainfo.Id; @@ -925,19 +928,19 @@ namespace Mono.Addins.Database foreach (string aid in installed.Keys) { if (!newInstalled.Contains (aid)) { - if (AddinManager.SessionService.IsAddinLoaded (aid)) { - RuntimeAddin ra = AddinManager.SessionService.GetAddin (aid); + if (addinEngine.IsAddinLoaded (aid)) { + RuntimeAddin ra = addinEngine.GetAddin (aid); if (!ra.Addin.Description.IsRoot) - AddinManager.SessionService.UnloadAddin (aid); + addinEngine.UnloadAddin (aid); } } } foreach (string aid in newInstalled.Keys) { if (!installed.Contains (aid)) { - Addin addin = AddinManager.Registry.GetAddin (aid); + Addin addin = addinEngine.Registry.GetAddin (aid); if (addin != null && !addin.Description.IsRoot) - AddinManager.SessionService.ActivateAddin (aid); + addinEngine.ActivateAddin (aid); } } } diff --git a/Mono.Addins/Mono.Addins.Database/AddinScanner.cs b/Mono.Addins/Mono.Addins.Database/AddinScanner.cs index 83968a0..9164ec1 100644 --- a/Mono.Addins/Mono.Addins.Database/AddinScanner.cs +++ b/Mono.Addins/Mono.Addins.Database/AddinScanner.cs @@ -546,15 +546,14 @@ namespace Mono.Addins.Database config = null; try { - Assembly asm = Util.LoadAssemblyForReflection (filePath); + object asm = reflector.LoadAssembly (filePath); // Get the config file from the resources, if there is one - foreach (string res in asm.GetManifestResourceNames ()) { + foreach (string res in reflector.GetResourceNames (asm)) { if (res.EndsWith (".addin") || res.EndsWith (".addin.xml")) { - using (Stream s = asm.GetManifestResourceStream (res)) { - string asmFile = new Uri (asm.CodeBase).LocalPath; - AddinDescription ad = AddinDescription.Read (s, Path.GetDirectoryName (asmFile)); + using (Stream s = reflector.GetResourceStream (asm, res)) { + AddinDescription ad = AddinDescription.Read (s, Path.GetDirectoryName (filePath)); if (config != null) { if (!config.IsExtensionModel && !ad.IsExtensionModel) { // There is more than one add-in definition @@ -570,7 +569,7 @@ namespace Mono.Addins.Database if (config == null) { // In this case, only scan the assembly if it has the Addin attribute. - AddinAttribute att = (AddinAttribute) Attribute.GetCustomAttribute (asm, typeof(AddinAttribute), false); + AddinAttribute att = (AddinAttribute) reflector.GetCustomAttribute (asm, typeof(AddinAttribute), false); if (att == null) return true; @@ -593,36 +592,46 @@ namespace Mono.Addins.Database } } - bool ScanDescription (IProgressStatus monitor, AddinDescription config, Assembly rootAssembly, AddinScanResult scanResult) + bool ScanDescription (IProgressStatus monitor, AddinDescription config, object rootAssembly, AddinScanResult scanResult) { // First of all scan the main module ArrayList assemblies = new ArrayList (); - ArrayList asmFiles = new ArrayList (); try { + string rootAsmFile = null; + + if (rootAssembly != null) { + ScanAssemblyAddinHeaders (config, rootAssembly, scanResult); + assemblies.Add (rootAssembly); + rootAsmFile = Path.GetFileName (config.AddinFile); + } + + // The assembly list may be modified while scanning the headears, so + // we use a for loop instead of a foreach + for (int n=0; n<config.MainModule.Assemblies.Count; n++) { + string s = config.MainModule.Assemblies [n]; + string asmFile = Util.GetFullPath (Path.Combine (config.BasePath, s)); + scanResult.AddPathToIgnore (asmFile); + if (s == rootAsmFile || config.MainModule.IgnorePaths.Contains (s)) + continue; + object asm = reflector.LoadAssembly (asmFile); + assemblies.Add (asm); + ScanAssemblyAddinHeaders (config, asm, scanResult); + ScanAssemblyImports (config.MainModule, asm); + } + // Add all data files to the ignore file list. It avoids scanning assemblies // which are included as 'data' in an add-in. - foreach (string df in config.AllFiles) { + foreach (string df in config.MainModule.DataFiles) { string file = Path.Combine (config.BasePath, df); scanResult.AddPathToIgnore (Util.GetFullPath (file)); } - foreach (string df in config.AllIgnorePaths) { + foreach (string df in config.MainModule.IgnorePaths) { string path = Path.Combine (config.BasePath, df); scanResult.AddPathToIgnore (Util.GetFullPath (path)); } - foreach (string s in config.MainModule.Assemblies) { - string asmFile = Path.Combine (config.BasePath, s); - asmFiles.Add (asmFile); - object asm = reflector.LoadAssembly (asmFile); - assemblies.Add (asm); - scanResult.AddPathToIgnore (Util.GetFullPath (asmFile)); - } - - foreach (object asm in assemblies) - ScanAssemblyAddinHeaders (config, asm, scanResult); - // The add-in id and version must be already assigned at this point // Clean host data from the index. New data will be added. @@ -630,7 +639,7 @@ namespace Mono.Addins.Database scanResult.HostIndex.RemoveHostData (config.AddinId, config.AddinFile); foreach (object asm in assemblies) - ScanAssemblyContents (config, asm, scanResult); + ScanAssemblyContents (config, config.MainModule, asm, scanResult); } catch (Exception ex) { ReportReflectionException (monitor, ex, config, scanResult); @@ -656,16 +665,29 @@ namespace Mono.Addins.Database foreach (ModuleDescription mod in config.OptionalModules) { try { assemblies.Clear (); - asmFiles.Clear (); - foreach (string s in mod.Assemblies) { + for (int n=0; n<mod.Assemblies.Count; n++) { + string s = mod.Assemblies [n]; + if (mod.IgnorePaths.Contains (s)) + continue; string asmFile = Path.Combine (config.BasePath, s); - asmFiles.Add (asmFile); object asm = reflector.LoadAssembly (asmFile); assemblies.Add (asm); scanResult.AddPathToIgnore (Util.GetFullPath (asmFile)); + ScanAssemblyImports (mod, asm); + } + // Add all data files to the ignore file list. It avoids scanning assemblies + // which are included as 'data' in an add-in. + foreach (string df in mod.DataFiles) { + string file = Path.Combine (config.BasePath, df); + scanResult.AddPathToIgnore (Util.GetFullPath (file)); } + foreach (string df in mod.IgnorePaths) { + string path = Path.Combine (config.BasePath, df); + scanResult.AddPathToIgnore (Util.GetFullPath (path)); + } + foreach (object asm in assemblies) - ScanAssemblyContents (config, asm, scanResult); + ScanAssemblyContents (config, mod, asm, scanResult); } catch (Exception ex) { ReportReflectionException (monitor, ex, config, scanResult); @@ -704,17 +726,15 @@ namespace Mono.Addins.Database config.Namespace = att.Namespace; if (att.Category.Length > 0) config.Category = att.Category; + if (att.CompatVersion.Length > 0) + config.CompatVersion = att.CompatVersion; + if (att.Url.Length > 0) + config.Url = att.Url; config.IsRoot = att is AddinRootAttribute; config.EnabledByDefault = att.EnabledByDefault; config.Flags = att.Flags; } - // Category - - object catt = reflector.GetCustomAttribute (asm, typeof(AddinCategoryAttribute), false); - if (catt != null && config.Category.Length == 0) - config.Category = ((AddinCategoryAttribute)catt).Name; - // Author attributes object[] atts = reflector.GetCustomAttributes (asm, typeof(AddinAuthorAttribute), false); @@ -727,7 +747,7 @@ namespace Mono.Addins.Database // Description - catt = reflector.GetCustomAttribute (asm, typeof(AssemblyDescriptionAttribute), false); + object catt = reflector.GetCustomAttribute (asm, typeof(AssemblyDescriptionAttribute), false); if (catt != null && config.Description.Length == 0) config.Description = ((AssemblyDescriptionAttribute)catt).Description; @@ -748,10 +768,40 @@ namespace Mono.Addins.Database node.SetAttribute ("location", locat.Catalog); config.Localizer = node; } + + // Optional modules + + atts = reflector.GetCustomAttributes (asm, typeof(AddinModuleAttribute), false); + foreach (AddinModuleAttribute mod in atts) { + if (mod.AssemblyFile.Length > 0) { + ModuleDescription module = new ModuleDescription (); + module.Assemblies.Add (mod.AssemblyFile); + config.OptionalModules.Add (module); + } + } } - void ScanAssemblyContents (AddinDescription config, object asm, AddinScanResult scanResult) + void ScanAssemblyImports (ModuleDescription module, object asm) { + object[] atts = reflector.GetCustomAttributes (asm, typeof(ImportAddinAssemblyAttribute), false); + foreach (ImportAddinAssemblyAttribute import in atts) { + if (!string.IsNullOrEmpty (import.FilePath)) { + module.Assemblies.Add (import.FilePath); + if (!import.Scan) + module.IgnorePaths.Add (import.FilePath); + } + } + atts = reflector.GetCustomAttributes (asm, typeof(ImportAddinFileAttribute), false); + foreach (ImportAddinFileAttribute import in atts) { + if (!string.IsNullOrEmpty (import.FilePath)) + module.DataFiles.Add (import.FilePath); + } + } + + void ScanAssemblyContents (AddinDescription config, ModuleDescription module, object asm, AddinScanResult scanResult) + { + bool isMainModule = module == config.MainModule; + // Get dependencies object[] deps = reflector.GetCustomAttributes (asm, typeof(AddinDependencyAttribute), false); @@ -759,24 +809,26 @@ namespace Mono.Addins.Database AddinDependency adep = new AddinDependency (); adep.AddinId = dep.Id; adep.Version = dep.Version; - config.MainModule.Dependencies.Add (adep); + module.Dependencies.Add (adep); } // Get extension points - object[] extPoints = reflector.GetCustomAttributes (asm, typeof(ExtensionPointAttribute), false); - foreach (ExtensionPointAttribute ext in extPoints) { - ExtensionPoint ep = config.AddExtensionPoint (ext.Path); - ep.Description = ext.Description; - ep.Name = ext.Name; - ExtensionNodeType nt = ep.AddExtensionNode (ext.NodeName, ext.NodeTypeName); - nt.CustomAttributeTypeName = ext.CustomAttributeTypeName; + if (isMainModule) { + object[] extPoints = reflector.GetCustomAttributes (asm, typeof(ExtensionPointAttribute), false); + foreach (ExtensionPointAttribute ext in extPoints) { + ExtensionPoint ep = config.AddExtensionPoint (ext.Path); + ep.Description = ext.Description; + ep.Name = ext.Name; + ExtensionNodeType nt = ep.AddExtensionNode (ext.NodeName, ext.NodeTypeName); + nt.CustomAttributeTypeName = ext.ExtensionAttributeTypeName; + } } // Look for extension nodes declared using assembly attributes foreach (CustomAttribute att in reflector.GetRawCustomAttributes (asm, typeof(CustomExtensionAttribute), true)) { - ExtensionNodeDescription elem = config.MainModule.AddExtensionNode ("%" + att.TypeName, "Type"); + ExtensionNodeDescription elem = module.AddExtensionNode ("%" + att.TypeName, "Type"); foreach (KeyValuePair<string,string> prop in att) elem.SetAttribute (prop.Key, prop.Value); } @@ -811,7 +863,7 @@ namespace Mono.Addins.Database path = eatt.Path; } - ExtensionNodeDescription elem = config.MainModule.AddExtensionNode (path, nodeName); + ExtensionNodeDescription elem = module.AddExtensionNode (path, nodeName); nodes [path] = elem; uniqueNode = elem; @@ -850,7 +902,7 @@ namespace Mono.Addins.Database // Look for extension points extensionAtts = reflector.GetCustomAttributes (t, typeof(TypeExtensionPointAttribute), false); - if (extensionAtts.Length > 0) { + if (extensionAtts.Length > 0 && isMainModule) { foreach (TypeExtensionPointAttribute epa in extensionAtts) { ExtensionPoint ep; @@ -865,7 +917,7 @@ namespace Mono.Addins.Database } nt.Id = epa.NodeName; nt.TypeName = epa.NodeType.FullName; - nt.CustomAttributeTypeName = epa.CustomAttributeTypeName; + nt.CustomAttributeTypeName = epa.ExtensionAttributeTypeName; ep.NodeSet.NodeTypes.Add (nt); ep.Description = epa.Description; ep.Name = epa.Name; @@ -876,7 +928,7 @@ namespace Mono.Addins.Database else { // Look for custom extension attribtues foreach (CustomAttribute att in reflector.GetRawCustomAttributes (t, typeof(CustomExtensionAttribute), true)) { - ExtensionNodeDescription elem = config.MainModule.AddExtensionNode ("%" + att.TypeName, "Type"); + ExtensionNodeDescription elem = module.AddExtensionNode ("%" + att.TypeName, "Type"); foreach (KeyValuePair<string,string> prop in att) elem.SetAttribute (prop.Key, prop.Value); } diff --git a/Mono.Addins/Mono.Addins.Database/DefaultAssemblyReflector.cs b/Mono.Addins/Mono.Addins.Database/DefaultAssemblyReflector.cs index 9adae84..9cf7bfe 100644 --- a/Mono.Addins/Mono.Addins.Database/DefaultAssemblyReflector.cs +++ b/Mono.Addins/Mono.Addins.Database/DefaultAssemblyReflector.cs @@ -44,6 +44,16 @@ namespace Mono.Addins.Database { return Util.LoadAssemblyForReflection (file); } + + public string[] GetResourceNames (object asm) + { + return ((Assembly)asm).GetManifestResourceNames (); + } + + public System.IO.Stream GetResourceStream (object asm, string resourceName) + { + return ((Assembly)asm).GetManifestResourceStream (resourceName); + } public object[] GetCustomAttributes (object obj, Type type, bool inherit) { diff --git a/Mono.Addins/Mono.Addins.Database/IAssemblyReflector.cs b/Mono.Addins/Mono.Addins.Database/IAssemblyReflector.cs index 79f7a9e..8ef8bb5 100644 --- a/Mono.Addins/Mono.Addins.Database/IAssemblyReflector.cs +++ b/Mono.Addins/Mono.Addins.Database/IAssemblyReflector.cs @@ -28,6 +28,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.IO; namespace Mono.Addins.Database { @@ -40,6 +41,8 @@ namespace Mono.Addins.Database object LoadAssembly (string file); object LoadAssemblyFromReference (object asmReference); + string[] GetResourceNames (object asm); + Stream GetResourceStream (object asm, string resourceName); IEnumerable GetAssemblyTypes (object asm); IEnumerable GetAssemblyReferences (object asm); diff --git a/Mono.Addins/Mono.Addins.Description/AddinDependency.cs b/Mono.Addins/Mono.Addins.Description/AddinDependency.cs index 3507f09..a526025 100644 --- a/Mono.Addins/Mono.Addins.Description/AddinDependency.cs +++ b/Mono.Addins/Mono.Addins.Description/AddinDependency.cs @@ -100,9 +100,9 @@ namespace Mono.Addins.Description get { return AddinId + " v" + version; } } - internal override bool CheckInstalled () + internal override bool CheckInstalled (AddinRegistry registry) { - Addin[] addins = AddinManager.Registry.GetAddins (); + Addin[] addins = registry.GetAddins (); foreach (Addin addin in addins) { if (addin.Id == id && addin.SupportsVersion (version)) { return true; diff --git a/Mono.Addins/Mono.Addins.Description/AssemblyDependency.cs b/Mono.Addins/Mono.Addins.Description/AssemblyDependency.cs index 7248ada..64a28d3 100644 --- a/Mono.Addins/Mono.Addins.Description/AssemblyDependency.cs +++ b/Mono.Addins/Mono.Addins.Description/AssemblyDependency.cs @@ -82,7 +82,7 @@ namespace Mono.Addins.Description } } - internal override bool CheckInstalled () + internal override bool CheckInstalled (AddinRegistry registry) { // TODO return true; diff --git a/Mono.Addins/Mono.Addins.Description/Dependency.cs b/Mono.Addins/Mono.Addins.Description/Dependency.cs index eb51852..0e63d52 100644 --- a/Mono.Addins/Mono.Addins.Description/Dependency.cs +++ b/Mono.Addins/Mono.Addins.Description/Dependency.cs @@ -45,6 +45,6 @@ namespace Mono.Addins.Description } public abstract string Name { get; } - internal abstract bool CheckInstalled (); + internal abstract bool CheckInstalled (AddinRegistry registry); } } diff --git a/Mono.Addins/Mono.Addins.Description/NativeDependency.cs b/Mono.Addins/Mono.Addins.Description/NativeDependency.cs index d192206..143beb2 100644 --- a/Mono.Addins/Mono.Addins.Description/NativeDependency.cs +++ b/Mono.Addins/Mono.Addins.Description/NativeDependency.cs @@ -41,7 +41,7 @@ namespace Mono.Addins.Description get { return "Native dependency"; } } - internal override bool CheckInstalled () + internal override bool CheckInstalled (AddinRegistry registry) { return false; } diff --git a/Mono.Addins/Mono.Addins.csproj b/Mono.Addins/Mono.Addins.csproj index a9469e1..0b4b9f3 100644 --- a/Mono.Addins/Mono.Addins.csproj +++ b/Mono.Addins/Mono.Addins.csproj @@ -31,7 +31,6 @@ <Compile Include="Mono.Addins\ExtensionNode.cs" /> <Compile Include="Mono.Addins\ExtensionTree.cs" /> <Compile Include="Mono.Addins\TreeNode.cs" /> - <Compile Include="Mono.Addins\AddinSessionService.cs" /> <Compile Include="Mono.Addins\RuntimeAddin.cs" /> <Compile Include="Mono.Addins\TreeNodeCollection.cs" /> <Compile Include="Mono.Addins\TypeExtensionNode.cs" /> @@ -117,7 +116,10 @@ <Compile Include="Mono.Addins\CustomExtensionAttribute.cs" /> <Compile Include="Mono.Addins\AddinAuthorAttribute.cs" /> <Compile Include="Mono.Addins\AddinLocalizerGettextAttribute.cs" /> - <Compile Include="Mono.Addins\AddinCategoryAttribute.cs" /> + <Compile Include="Mono.Addins\ImportAddinFileAttribute.cs" /> + <Compile Include="Mono.Addins\ImportAddinAssemblyAttribute.cs" /> + <Compile Include="Mono.Addins\AddinModuleAttribute.cs" /> + <Compile Include="Mono.Addins\AddinEngine.cs" /> </ItemGroup> <ItemGroup> <Content Include="Mono.Addins.dll.config"> diff --git a/Mono.Addins/Mono.Addins/AddinAttribute.cs b/Mono.Addins/Mono.Addins/AddinAttribute.cs index 047d080..72dcf8a 100644 --- a/Mono.Addins/Mono.Addins/AddinAttribute.cs +++ b/Mono.Addins/Mono.Addins/AddinAttribute.cs @@ -41,6 +41,8 @@ namespace Mono.Addins string category; bool enabledByDefault = true; AddinFlags flags; + string compatVersion; + string url; public AddinAttribute () { @@ -67,6 +69,11 @@ namespace Mono.Addins set { version = value; } } + public string CompatVersion { + get { return compatVersion != null ? compatVersion : string.Empty; } + set { compatVersion = value; } + } + public string Namespace { get { return ns != null ? ns : string.Empty; } set { ns = value; } @@ -77,6 +84,11 @@ namespace Mono.Addins set { category = value; } } + public string Url { + get { return url != null ? url : string.Empty; } + set { url = value; } + } + public bool EnabledByDefault { get { return this.enabledByDefault; } set { this.enabledByDefault = value; } diff --git a/Mono.Addins/Mono.Addins/AddinSessionService.cs b/Mono.Addins/Mono.Addins/AddinEngine.cs index 302e031..2131085 100644 --- a/Mono.Addins/Mono.Addins/AddinSessionService.cs +++ b/Mono.Addins/Mono.Addins/AddinEngine.cs @@ -38,43 +38,105 @@ using Mono.Addins.Localization; namespace Mono.Addins { - internal class AddinSessionService + public class AddinEngine: ExtensionContext { + bool initialized; + string startupDirectory; + AddinRegistry registry; + IAddinInstaller installer; + bool checkAssemblyLoadConflicts; Hashtable loadedAddins = new Hashtable (); - ExtensionContext defaultContext; Hashtable nodeSets = new Hashtable (); Hashtable autoExtensionTypes = new Hashtable (); Hashtable loadedAssemblies = new Hashtable (); AddinLocalizer defaultLocalizer; IProgressStatus defaultProgressStatus = new ConsoleProgressStatus (false); - internal void Initialize () + public static event AddinErrorEventHandler AddinLoadError; + public static event AddinEventHandler AddinLoaded; + public static event AddinEventHandler AddinUnloaded; + + public AddinEngine () + { + } + + public void Initialize (string configDir) + { + if (initialized) + return; + + Assembly asm = Assembly.GetEntryAssembly (); + if (asm == null) asm = Assembly.GetCallingAssembly (); + Initialize (configDir, asm); + } + + internal void Initialize (string configDir, Assembly startupAsm) { - defaultContext = new ExtensionContext (); + if (initialized) + return; + + Initialize (this); + + string asmFile = new Uri (startupAsm.CodeBase).LocalPath; + startupDirectory = System.IO.Path.GetDirectoryName (asmFile); + + string customDir = Environment.GetEnvironmentVariable ("MONO_ADDINS_REGISTRY"); + if (customDir != null && customDir.Length > 0) + configDir = customDir; + + if (configDir == null || configDir.Length == 0) + registry = AddinRegistry.GetGlobalRegistry (this, startupDirectory); + else + registry = new AddinRegistry (this, configDir, startupDirectory); + + if (registry.CreateHostAddinsFile (asmFile) || registry.UnknownDomain) + registry.Update (new ConsoleProgressStatus (false)); + + initialized = true; + ActivateRoots (); OnAssemblyLoaded (null, null); AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler (OnAssemblyLoaded); } - internal void Shutdown () + public void Shutdown () { + initialized = false; AppDomain.CurrentDomain.AssemblyLoad -= new AssemblyLoadEventHandler (OnAssemblyLoaded); - defaultContext = null; loadedAddins.Clear (); loadedAssemblies.Clear (); + registry.Dispose (); + registry = null; + startupDirectory = null; + Clear (); } public void InitializeDefaultLocalizer (IAddinLocalizer localizer) { + CheckInitialized (); if (localizer != null) defaultLocalizer = new AddinLocalizer (localizer); else defaultLocalizer = null; } + internal string StartupDirectory { + get { return startupDirectory; } + } + + public bool IsInitialized { + get { return initialized; } + } + + public IAddinInstaller DefaultInstaller { + get { return installer; } + set { installer = value; } + } + public AddinLocalizer DefaultLocalizer { get { + CheckInitialized (); if (defaultLocalizer != null) return defaultLocalizer; else @@ -83,11 +145,12 @@ namespace Mono.Addins } internal ExtensionContext DefaultContext { - get { return defaultContext; } + get { return this; } } public AddinLocalizer CurrentLocalizer { get { + CheckInitialized (); Assembly asm = Assembly.GetCallingAssembly (); RuntimeAddin addin = GetAddinForAssembly (asm); if (addin != null) @@ -99,25 +162,62 @@ namespace Mono.Addins public RuntimeAddin CurrentAddin { get { + CheckInitialized (); Assembly asm = Assembly.GetCallingAssembly (); return GetAddinForAssembly (asm); } } + public AddinRegistry Registry { + get { + CheckInitialized (); + return registry; + } + } + internal RuntimeAddin GetAddinForAssembly (Assembly asm) { return (RuntimeAddin) loadedAssemblies [asm]; } + // This method checks if the specified add-ins are installed. + // If some of the add-ins are not installed, it will use + // the installer assigned to the DefaultAddinInstaller property + // to install them. If the installation fails, or if DefaultAddinInstaller + // is not set, an exception will be thrown. + public void CheckInstalled (string message, params string[] addinIds) + { + ArrayList notInstalled = new ArrayList (); + foreach (string id in addinIds) { + Addin addin = Registry.GetAddin (id, false); + if (addin != null) { + // The add-in is already installed + // If the add-in is disabled, enable it now + if (!addin.Enabled) + addin.Enabled = true; + } else { + notInstalled.Add (id); + } + } + if (notInstalled.Count == 0) + return; + if (installer == null) + throw new InvalidOperationException ("Add-in installer not set"); + + // Install the add-ins + installer.InstallAddins (Registry, message, (string[]) notInstalled.ToArray (typeof(string))); + } + // Enables or disables conflict checking while loading assemblies. // Disabling makes loading faster, but less safe. - public bool CheckAssemblyLoadConflicts { + internal bool CheckAssemblyLoadConflicts { get { return checkAssemblyLoadConflicts; } set { checkAssemblyLoadConflicts = value; } } public bool IsAddinLoaded (string id) { + CheckInitialized (); return loadedAddins.Contains (Addin.GetIdName (id)); } @@ -128,12 +228,12 @@ namespace Mono.Addins internal void ActivateAddin (string id) { - defaultContext.ActivateAddinExtensions (id); + ActivateAddinExtensions (id); } internal void UnloadAddin (string id) { - defaultContext.RemoveAddinExtensions (id); + RemoveAddinExtensions (id); RuntimeAddin addin = GetAddin (id); if (addin != null) { @@ -143,19 +243,25 @@ namespace Mono.Addins foreach (Assembly asm in addin.Assemblies) loadedAssemblies.Remove (asm); } - AddinManager.ReportAddinUnload (id); + ReportAddinUnload (id); } } + public void LoadAddin (IProgressStatus statusMonitor, string id) + { + CheckInitialized (); + LoadAddin (statusMonitor, id, true); + } + internal bool LoadAddin (IProgressStatus statusMonitor, string id, bool throwExceptions) { try { if (IsAddinLoaded (id)) return true; - if (!AddinManager.Registry.IsAddinEnabled (id)) { + if (!Registry.IsAddinEnabled (id)) { string msg = GettextCatalog.GetString ("Disabled add-ins can't be loaded."); - AddinManager.ReportError (msg, id, null, false); + ReportError (msg, id, null, false); if (throwExceptions) throw new InvalidOperationException (msg); return false; @@ -187,7 +293,7 @@ namespace Mono.Addins return true; } catch (Exception ex) { - AddinManager.ReportError ("Add-in could not be loaded: " + ex.Message, id, ex, false); + ReportError ("Add-in could not be loaded: " + ex.Message, id, ex, false); if (statusMonitor != null) statusMonitor.ReportError ("Add-in '" + id + "' could not be loaded.", ex); if (throwExceptions) @@ -196,18 +302,17 @@ namespace Mono.Addins } } - internal void ResetCachedData () + internal override void ResetCachedData () { foreach (RuntimeAddin ad in loadedAddins.Values) ad.Addin.ResetCachedData (); - if (defaultContext != null) - defaultContext.ResetCachedData (); + base.ResetCachedData (); } bool InsertAddin (IProgressStatus statusMonitor, Addin iad) { try { - RuntimeAddin p = new RuntimeAddin (); + RuntimeAddin p = new RuntimeAddin (this); // Read the config file and load the add-in assemblies AddinDescription description = p.Load (iad); @@ -224,7 +329,7 @@ namespace Mono.Addins foreach (ConditionTypeDescription cond in description.ConditionTypes) { Type ctype = p.GetType (cond.TypeName, true); - defaultContext.RegisterCondition (cond.Id, ctype); + RegisterCondition (cond.Id, ctype); } } @@ -232,12 +337,12 @@ namespace Mono.Addins InsertExtensionPoint (p, ep); // Fire loaded event - defaultContext.NotifyAddinLoaded (p); - AddinManager.ReportAddinLoad (p.Id); + NotifyAddinLoaded (p); + ReportAddinLoad (p.Id); return true; } catch (Exception ex) { - AddinManager.ReportError ("Add-in could not be loaded", iad.Id, ex, false); + ReportError ("Add-in could not be loaded", iad.Id, ex, false); if (statusMonitor != null) statusMonitor.ReportError ("Add-in '" + iad.Id + "' could not be loaded.", ex); return false; @@ -252,7 +357,7 @@ namespace Mono.Addins internal void InsertExtensionPoint (RuntimeAddin addin, ExtensionPoint ep) { - defaultContext.CreateExtensionPoint (ep); + CreateExtensionPoint (ep); foreach (ExtensionNodeType nt in ep.NodeSet.NodeTypes) { if (nt.ObjectTypeName.Length > 0) { Type ntype = addin.GetType (nt.ObjectTypeName, true); @@ -271,7 +376,7 @@ namespace Mono.Addins depCheck.Push (id); - Addin iad = AddinManager.Registry.GetAddin (id); + Addin iad = Registry.GetAddin (id); if (iad == null || !iad.Enabled) { if (optional) return false; @@ -316,17 +421,17 @@ namespace Mono.Addins return true; } - public void RegisterNodeSet (ExtensionNodeSet nset) + internal void RegisterNodeSet (ExtensionNodeSet nset) { nodeSets [nset.Id] = nset; } - public void UnregisterNodeSet (ExtensionNodeSet nset) + internal void UnregisterNodeSet (ExtensionNodeSet nset) { nodeSets.Remove (nset.Id); } - public string GetNodeTypeAddin (ExtensionNodeSet nset, string type, string callingAddinId) + internal string GetNodeTypeAddin (ExtensionNodeSet nset, string type, string callingAddinId) { ExtensionNodeType nt = FindType (nset, type, callingAddinId); if (nt != null) @@ -348,7 +453,7 @@ namespace Mono.Addins foreach (string ns in nset.NodeSets) { ExtensionNodeSet regSet = (ExtensionNodeSet) nodeSets [ns]; if (regSet == null) { - AddinManager.ReportError ("Unknown node set: " + ns, callingAddinId, null, false); + ReportError ("Unknown node set: " + ns, callingAddinId, null, false); return null; } ExtensionNodeType nt = FindType (regSet, name, callingAddinId); @@ -358,17 +463,17 @@ namespace Mono.Addins return null; } - public void RegisterAutoTypeExtensionPoint (Type type, string path) + internal void RegisterAutoTypeExtensionPoint (Type type, string path) { autoExtensionTypes [type] = path; } - public void UnregisterAutoTypeExtensionPoint (Type type, string path) + internal void UnregisterAutoTypeExtensionPoint (Type type, string path) { autoExtensionTypes.Remove (type); } - public string GetAutoTypeExtensionPoint (Type type) + internal string GetAutoTypeExtensionPoint (Type type) { return autoExtensionTypes [type] as string; } @@ -390,7 +495,7 @@ namespace Mono.Addins if (AddinDatabase.RunningSetupProcess || asm is System.Reflection.Emit.AssemblyBuilder) return; string asmFile = new Uri (asm.CodeBase).LocalPath; - Addin ainfo = AddinManager.Registry.GetAddinForHostAssembly (asmFile); + Addin ainfo = Registry.GetAddinForHostAssembly (asmFile); if (ainfo != null && !IsAddinLoaded (ainfo.Id)) { AddinDescription adesc = null; try { @@ -402,14 +507,59 @@ namespace Mono.Addins // If the add-in has changed, update the add-in database. // We do it here because once loaded, add-in roots can't be // reloaded like regular add-ins. - AddinManager.Registry.Update (null); - ainfo = AddinManager.Registry.GetAddinForHostAssembly (asmFile); + Registry.Update (null); + ainfo = Registry.GetAddinForHostAssembly (asmFile); if (ainfo == null) return; } LoadAddin (null, ainfo.Id, false); } } + + public ExtensionContext CreateExtensionContext () + { + CheckInitialized (); + return CreateChildContext (); + } + + internal void CheckInitialized () + { + if (!initialized) + throw new InvalidOperationException ("Add-in engine not initialized."); + } + + internal void ReportError (string message, string addinId, Exception exception, bool fatal) + { + if (AddinLoadError != null) + AddinLoadError (null, new AddinErrorEventArgs (message, addinId, exception)); + else { + Console.WriteLine (message); + if (exception != null) + Console.WriteLine (exception); + } + } + + internal void ReportAddinLoad (string id) + { + if (AddinLoaded != null) { + try { + AddinLoaded (null, new AddinEventArgs (id)); + } catch { + // Ignore subscriber exceptions + } + } + } + + internal void ReportAddinUnload (string id) + { + if (AddinUnloaded != null) { + try { + AddinUnloaded (null, new AddinEventArgs (id)); + } catch { + // Ignore subscriber exceptions + } + } + } } } diff --git a/Mono.Addins/Mono.Addins/AddinManager.cs b/Mono.Addins/Mono.Addins/AddinManager.cs index 6707e8a..2377bc8 100644 --- a/Mono.Addins/Mono.Addins/AddinManager.cs +++ b/Mono.Addins/Mono.Addins/AddinManager.cs @@ -38,16 +38,7 @@ namespace Mono.Addins { public class AddinManager { - static AddinSessionService sessionService; - static AddinRegistry registry; - - static string startupDirectory; - static bool initialized; - static IAddinInstaller installer; - - public static event AddinErrorEventHandler AddinLoadError; - public static event AddinEventHandler AddinLoaded; - public static event AddinEventHandler AddinUnloaded; + static AddinEngine sessionService; private AddinManager () { @@ -55,94 +46,70 @@ namespace Mono.Addins public static void Initialize () { - Initialize (null); + // Code not shared with the other Initialize since I need to get the calling assembly + Assembly asm = Assembly.GetEntryAssembly (); + if (asm == null) asm = Assembly.GetCallingAssembly (); + AddinEngine.Initialize (null, asm); } public static void Initialize (string configDir) { - if (initialized) - return; - Assembly asm = Assembly.GetEntryAssembly (); if (asm == null) asm = Assembly.GetCallingAssembly (); - string asmFile = new Uri (asm.CodeBase).LocalPath; - - startupDirectory = Path.GetDirectoryName (asmFile); - - string customDir = Environment.GetEnvironmentVariable ("MONO_ADDINS_REGISTRY"); - if (customDir != null && customDir.Length > 0) - configDir = customDir; - - if (configDir == null || configDir.Length == 0) - registry = AddinRegistry.GetGlobalRegistry (startupDirectory); - else - registry = new AddinRegistry (configDir, startupDirectory); - - if (registry.CreateHostAddinsFile (asmFile) || registry.UnknownDomain) - registry.Update (new ConsoleProgressStatus (false)); - - initialized = true; - - SessionService.Initialize (); + AddinEngine.Initialize (configDir, asm); } public static void Shutdown () { - SessionService.Shutdown (); - registry.Dispose (); - registry = null; - startupDirectory = null; - initialized = false; + AddinEngine.Shutdown (); } public static void InitializeDefaultLocalizer (IAddinLocalizer localizer) { - CheckInitialized (); - SessionService.InitializeDefaultLocalizer (localizer); + AddinEngine.InitializeDefaultLocalizer (localizer); } internal static string StartupDirectory { - get { return startupDirectory; } + get { return AddinEngine.StartupDirectory; } } public static bool IsInitialized { - get { return initialized; } + get { return AddinEngine.IsInitialized; } } public static IAddinInstaller DefaultInstaller { - get { return installer; } - set { installer = value; } + get { return AddinEngine.DefaultInstaller; } + set { AddinEngine.DefaultInstaller = value; } } public static AddinLocalizer DefaultLocalizer { get { - CheckInitialized (); - return SessionService.DefaultLocalizer; + return AddinEngine.DefaultLocalizer; } } public static AddinLocalizer CurrentLocalizer { get { - CheckInitialized (); - RuntimeAddin addin = SessionService.GetAddinForAssembly (Assembly.GetCallingAssembly ()); + AddinEngine.CheckInitialized (); + RuntimeAddin addin = AddinEngine.GetAddinForAssembly (Assembly.GetCallingAssembly ()); if (addin != null) return addin.Localizer; else - return SessionService.DefaultLocalizer; + return AddinEngine.DefaultLocalizer; } } public static RuntimeAddin CurrentAddin { get { - CheckInitialized (); - return SessionService.GetAddinForAssembly (Assembly.GetCallingAssembly ()); + AddinEngine.CheckInitialized (); + return AddinEngine.GetAddinForAssembly (Assembly.GetCallingAssembly ()); } } - internal static AddinSessionService SessionService { + public static AddinEngine AddinEngine { get { if (sessionService == null) - sessionService = new AddinSessionService(); + sessionService = new AddinEngine(); return sessionService; } @@ -150,8 +117,7 @@ namespace Mono.Addins public static AddinRegistry Registry { get { - CheckInitialized (); - return registry; + return AddinEngine.Registry; } } @@ -162,207 +128,162 @@ namespace Mono.Addins // is not set, an exception will be thrown. public static void CheckInstalled (string message, params string[] addinIds) { - ArrayList notInstalled = new ArrayList (); - foreach (string id in addinIds) { - Addin addin = Registry.GetAddin (id, false); - if (addin != null) { - // The add-in is already installed - // If the add-in is disabled, enable it now - if (!addin.Enabled) - addin.Enabled = true; - } else { - notInstalled.Add (id); - } - } - if (notInstalled.Count == 0) - return; - if (installer == null) - throw new InvalidOperationException ("Add-in installer not set"); - - // Install the add-ins - installer.InstallAddins (Registry, message, (string[]) notInstalled.ToArray (typeof(string))); + AddinEngine.CheckInstalled (message, addinIds); } public static bool IsAddinLoaded (string id) { - CheckInitialized (); - return SessionService.IsAddinLoaded (id); + return AddinEngine.IsAddinLoaded (id); } public static void LoadAddin (IProgressStatus statusMonitor, string id) { - CheckInitialized (); - SessionService.LoadAddin (statusMonitor, id, true); + AddinEngine.LoadAddin (statusMonitor, id); } public static ExtensionContext CreateExtensionContext () { - CheckInitialized (); - return SessionService.DefaultContext.CreateChildContext (); + return AddinEngine.CreateExtensionContext (); } public static ExtensionNode GetExtensionNode (string path) { - CheckInitialized (); - return SessionService.DefaultContext.GetExtensionNode (path); + AddinEngine.CheckInitialized (); + return AddinEngine.GetExtensionNode (path); } public static ExtensionNode GetExtensionNode<T> (string path) where T:ExtensionNode { - CheckInitialized (); - return SessionService.DefaultContext.GetExtensionNode<T> (path); + AddinEngine.CheckInitialized (); + return AddinEngine.GetExtensionNode<T> (path); } public static ExtensionNodeList GetExtensionNodes (string path) { - CheckInitialized (); - return SessionService.DefaultContext.GetExtensionNodes (path); + AddinEngine.CheckInitialized (); + return AddinEngine.GetExtensionNodes (path); } public static ExtensionNodeList GetExtensionNodes (string path, Type type) { - CheckInitialized (); - return SessionService.DefaultContext.GetExtensionNodes (path, type); + AddinEngine.CheckInitialized (); + return AddinEngine.GetExtensionNodes (path, type); } public static ExtensionNodeList<T> GetExtensionNodes<T> (string path) where T:ExtensionNode { - CheckInitialized (); - return SessionService.DefaultContext.GetExtensionNodes<T> (path); + AddinEngine.CheckInitialized (); + return AddinEngine.GetExtensionNodes<T> (path); } public static ExtensionNodeList GetExtensionNodes (Type instanceType) { - CheckInitialized (); - return SessionService.DefaultContext.GetExtensionNodes (instanceType); + AddinEngine.CheckInitialized (); + return AddinEngine.GetExtensionNodes (instanceType); } public static ExtensionNodeList GetExtensionNodes (Type instanceType, Type expectedNodeType) { - CheckInitialized (); - return SessionService.DefaultContext.GetExtensionNodes (instanceType, expectedNodeType); + AddinEngine.CheckInitialized (); + return AddinEngine.GetExtensionNodes (instanceType, expectedNodeType); } public static ExtensionNodeList<T> GetExtensionNodes<T> (Type instanceType) where T: ExtensionNode { - CheckInitialized (); - return SessionService.DefaultContext.GetExtensionNodes<T> (instanceType); + AddinEngine.CheckInitialized (); + return AddinEngine.GetExtensionNodes<T> (instanceType); } public static object[] GetExtensionObjects (Type instanceType) { - CheckInitialized (); - return SessionService.DefaultContext.GetExtensionObjects (instanceType); + AddinEngine.CheckInitialized (); + return AddinEngine.GetExtensionObjects (instanceType); } public static T[] GetExtensionObjects<T> () { - CheckInitialized (); - return SessionService.DefaultContext.GetExtensionObjects<T> (); + AddinEngine.CheckInitialized (); + return AddinEngine.GetExtensionObjects<T> (); } public static object[] GetExtensionObjects (Type instanceType, bool reuseCachedInstance) { - CheckInitialized (); - return SessionService.DefaultContext.GetExtensionObjects (instanceType, reuseCachedInstance); + AddinEngine.CheckInitialized (); + return AddinEngine.GetExtensionObjects (instanceType, reuseCachedInstance); } public static T[] GetExtensionObjects<T> (bool reuseCachedInstance) { - CheckInitialized (); - return SessionService.DefaultContext.GetExtensionObjects<T> (reuseCachedInstance); + AddinEngine.CheckInitialized (); + return AddinEngine.GetExtensionObjects<T> (reuseCachedInstance); } public static object[] GetExtensionObjects (string path) { - CheckInitialized (); - return SessionService.DefaultContext.GetExtensionObjects (path); + AddinEngine.CheckInitialized (); + return AddinEngine.GetExtensionObjects (path); } public static object[] GetExtensionObjects (string path, bool reuseCachedInstance) { - CheckInitialized (); - return SessionService.DefaultContext.GetExtensionObjects (path, reuseCachedInstance); + AddinEngine.CheckInitialized (); + return AddinEngine.GetExtensionObjects (path, reuseCachedInstance); } public static object[] GetExtensionObjects (string path, Type arrayElementType) { - CheckInitialized (); - return SessionService.DefaultContext.GetExtensionObjects (path, arrayElementType); + AddinEngine.CheckInitialized (); + return AddinEngine.GetExtensionObjects (path, arrayElementType); } public static T[] GetExtensionObjects<T> (string path) { - CheckInitialized (); - return SessionService.DefaultContext.GetExtensionObjects<T> (path); + AddinEngine.CheckInitialized (); + return AddinEngine.GetExtensionObjects<T> (path); } public static object[] GetExtensionObjects (string path, Type arrayElementType, bool reuseCachedInstance) { - CheckInitialized (); - return SessionService.DefaultContext.GetExtensionObjects (path, arrayElementType, reuseCachedInstance); + AddinEngine.CheckInitialized (); + return AddinEngine.GetExtensionObjects (path, arrayElementType, reuseCachedInstance); } public static T[] GetExtensionObjects<T> (string path, bool reuseCachedInstance) { - CheckInitialized (); - return SessionService.DefaultContext.GetExtensionObjects<T> (path, reuseCachedInstance); + AddinEngine.CheckInitialized (); + return AddinEngine.GetExtensionObjects<T> (path, reuseCachedInstance); } public static event ExtensionEventHandler ExtensionChanged { - add { CheckInitialized(); SessionService.DefaultContext.ExtensionChanged += value; } - remove { CheckInitialized(); SessionService.DefaultContext.ExtensionChanged -= value; } + add { AddinEngine.CheckInitialized(); AddinEngine.ExtensionChanged += value; } + remove { AddinEngine.CheckInitialized(); AddinEngine.ExtensionChanged -= value; } } public static void AddExtensionNodeHandler (string path, ExtensionNodeEventHandler handler) { - CheckInitialized (); - SessionService.DefaultContext.AddExtensionNodeHandler (path, handler); + AddinEngine.CheckInitialized (); + AddinEngine.AddExtensionNodeHandler (path, handler); } public static void RemoveExtensionNodeHandler (string path, ExtensionNodeEventHandler handler) { - CheckInitialized (); - SessionService.DefaultContext.RemoveExtensionNodeHandler (path, handler); - } - - static void CheckInitialized () - { - if (!initialized) - throw new InvalidOperationException ("Add-in manager not initialized."); + AddinEngine.CheckInitialized (); + AddinEngine.RemoveExtensionNodeHandler (path, handler); } - internal static void ReportError (string message, string addinId, Exception exception, bool fatal) - { - if (AddinLoadError != null) - AddinLoadError (null, new AddinErrorEventArgs (message, addinId, exception)); - else { - Console.WriteLine (message); - if (exception != null) - Console.WriteLine (exception); - } + public static event AddinErrorEventHandler AddinLoadError { + add { AddinEngine.AddinLoadError += value; } + remove { AddinEngine.AddinLoadError -= value; } } - internal static void ReportAddinLoad (string id) - { - if (AddinLoaded != null) { - try { - AddinLoaded (null, new AddinEventArgs (id)); - } catch { - // Ignore subscriber exceptions - } - } + public static event AddinEventHandler AddinLoaded { + add { AddinEngine.AddinLoaded += value; } + remove { AddinEngine.AddinLoaded -= value; } } - internal static void ReportAddinUnload (string id) - { - if (AddinUnloaded != null) { - try { - AddinUnloaded (null, new AddinEventArgs (id)); - } catch { - // Ignore subscriber exceptions - } - } + public static event AddinEventHandler AddinUnloaded { + add { AddinEngine.AddinUnloaded += value; } + remove { AddinEngine.AddinUnloaded -= value; } } } diff --git a/Mono.Addins/Mono.Addins/AddinModuleAttribute.cs b/Mono.Addins/Mono.Addins/AddinModuleAttribute.cs new file mode 100644 index 0000000..377073d --- /dev/null +++ b/Mono.Addins/Mono.Addins/AddinModuleAttribute.cs @@ -0,0 +1,46 @@ +// +// AddinModuleAttribute.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; + +namespace Mono.Addins +{ + public class AddinModuleAttribute: Attribute + { + string assemblyFile; + + public AddinModuleAttribute (string assemblyFile) + { + this.assemblyFile = assemblyFile; + } + + public string AssemblyFile { + get { return this.assemblyFile ?? string.Empty; } + set { this.assemblyFile = value; } + } + } +} + diff --git a/Mono.Addins/Mono.Addins/AddinRegistry.cs b/Mono.Addins/Mono.Addins/AddinRegistry.cs index 81db9dc..c8d5afb 100644 --- a/Mono.Addins/Mono.Addins/AddinRegistry.cs +++ b/Mono.Addins/Mono.Addins/AddinRegistry.cs @@ -45,14 +45,18 @@ namespace Mono.Addins string currentDomain; string startupDirectory; - public AddinRegistry (string registryPath): this (registryPath, null) + public AddinRegistry (string registryPath): this (null, registryPath, null) { } - public AddinRegistry (string registryPath, string startupDirectory) + public AddinRegistry (string registryPath, string startupDirectory): this (null, registryPath, startupDirectory) + { + } + + internal AddinRegistry (AddinEngine engine, string registryPath, string startupDirectory) { basePath = Util.GetFullPath (Util.NormalizePath (registryPath)); - database = new AddinDatabase (this); + database = new AddinDatabase (engine, this); // Look for add-ins in the hosts directory and in the default // addins directory @@ -69,12 +73,12 @@ namespace Mono.Addins public static AddinRegistry GetGlobalRegistry () { - return GetGlobalRegistry (null); + return GetGlobalRegistry (null, null); } - internal static AddinRegistry GetGlobalRegistry (string startupDirectory) + internal static AddinRegistry GetGlobalRegistry (AddinEngine engine, string startupDirectory) { - AddinRegistry reg = new AddinRegistry (GlobalRegistryPath, startupDirectory); + AddinRegistry reg = new AddinRegistry (engine, GlobalRegistryPath, startupDirectory); string baseDir; if (Util.IsWindows) baseDir = Environment.GetFolderPath (Environment.SpecialFolder.CommonProgramFiles); @@ -227,6 +231,11 @@ namespace Mono.Addins currentDomain = database.GetFolderDomain (null, startupDirectory); } + public void Update () + { + Update (new ConsoleProgressStatus (false)); + } + public void Update (IProgressStatus monitor) { database.Update (monitor, currentDomain); diff --git a/Mono.Addins/Mono.Addins/ConditionType.cs b/Mono.Addins/Mono.Addins/ConditionType.cs index 596a576..ebf38a4 100644 --- a/Mono.Addins/Mono.Addins/ConditionType.cs +++ b/Mono.Addins/Mono.Addins/ConditionType.cs @@ -161,9 +161,11 @@ namespace Mono.Addins { ExtensionNodeDescription node; string typeId; + AddinEngine addinEngine; - internal Condition (ExtensionNodeDescription element, BaseCondition parent): base (parent) + internal Condition (AddinEngine addinEngine, ExtensionNodeDescription element, BaseCondition parent): base (parent) { + this.addinEngine = addinEngine; typeId = element.GetAttribute ("id"); node = element; } @@ -175,7 +177,7 @@ namespace Mono.Addins ConditionType type = ctx.GetCondition (typeId); if (type == null) { - AddinManager.ReportError ("Condition '" + typeId + "' not found in current extension context.", null, null, false); + addinEngine.ReportError ("Condition '" + typeId + "' not found in current extension context.", null, null, false); return false; } @@ -183,7 +185,7 @@ namespace Mono.Addins return type.Evaluate (node); } catch (Exception ex) { - AddinManager.ReportError ("Error while evaluating condition '" + typeId + "'", null, ex, false); + addinEngine.ReportError ("Error while evaluating condition '" + typeId + "'", null, ex, false); return false; } } diff --git a/Mono.Addins/Mono.Addins/ExtensionContext.cs b/Mono.Addins/Mono.Addins/ExtensionContext.cs index f0d2517..c0edbb2 100644 --- a/Mono.Addins/Mono.Addins/ExtensionContext.cs +++ b/Mono.Addins/Mono.Addins/ExtensionContext.cs @@ -55,12 +55,28 @@ namespace Mono.Addins parentContext.DisposeChildContext (this); } - internal ExtensionContext () + internal void Initialize (AddinEngine addinEngine) { - tree = new ExtensionTree (this); + fireEvents = false; + tree = new ExtensionTree (addinEngine, this); } - internal void ResetCachedData () + protected void Clear () + { + conditionTypes.Clear (); + conditionsToNodes.Clear (); + childContexts = null; + parentContext = null; + tree = null; + runTimeEnabledAddins = null; + runTimeDisabledAddins = null; + } + + internal AddinEngine AddinEngine { + get { return tree.AddinEngine; } + } + + internal virtual void ResetCachedData () { tree.ResetCachedData (); if (childContexts != null) { @@ -78,6 +94,7 @@ namespace Mono.Addins if (childContexts == null) childContexts = new ArrayList (); ExtensionContext ctx = new ExtensionContext (); + ctx.Initialize (AddinEngine); ctx.parentContext = this; WeakReference wref = new WeakReference (ctx); childContexts.Add (wref); @@ -236,7 +253,7 @@ namespace Mono.Addins public ExtensionNodeList GetExtensionNodes (Type instanceType, Type expectedNodeType) { - string path = AddinManager.SessionService.GetAutoTypeExtensionPoint (instanceType); + string path = AddinEngine.GetAutoTypeExtensionPoint (instanceType); if (path == null) return new ExtensionNodeList (null); return GetExtensionNodes (path, expectedNodeType); @@ -244,7 +261,7 @@ namespace Mono.Addins public ExtensionNodeList<T> GetExtensionNodes<T> (Type instanceType) where T: ExtensionNode { - string path = AddinManager.SessionService.GetAutoTypeExtensionPoint (instanceType); + string path = AddinEngine.GetAutoTypeExtensionPoint (instanceType); if (path == null) return new ExtensionNodeList<T> (null); return new ExtensionNodeList<T> (GetExtensionNodes (path, typeof (T)).list); @@ -263,7 +280,7 @@ namespace Mono.Addins foreach (ExtensionNode cnode in list) { if (!expectedNodeType.IsInstanceOfType (cnode)) { foundError = true; - AddinManager.ReportError ("Error while getting nodes for path '" + path + "'. Expected subclass of node type '" + expectedNodeType + "'. Found '" + cnode.GetType (), null, null, false); + AddinEngine.ReportError ("Error while getting nodes for path '" + path + "'. Expected subclass of node type '" + expectedNodeType + "'. Found '" + cnode.GetType (), null, null, false); } } if (foundError) { @@ -291,7 +308,7 @@ namespace Mono.Addins public object[] GetExtensionObjects (Type instanceType, bool reuseCachedInstance) { - string path = AddinManager.SessionService.GetAutoTypeExtensionPoint (instanceType); + string path = AddinEngine.GetAutoTypeExtensionPoint (instanceType); if (path == null) return (object[]) Array.CreateInstance (instanceType, 0); return GetExtensionObjects (path, instanceType, reuseCachedInstance); @@ -299,7 +316,7 @@ namespace Mono.Addins public T[] GetExtensionObjects<T> (bool reuseCachedInstance) { - string path = AddinManager.SessionService.GetAutoTypeExtensionPoint (typeof(T)); + string path = AddinEngine.GetAutoTypeExtensionPoint (typeof(T)); if (path == null) return new T[0]; return GetExtensionObjects<T> (path, reuseCachedInstance); @@ -442,9 +459,9 @@ namespace Mono.Addins try { fireEvents = true; - Addin addin = AddinManager.Registry.GetAddin (id); + Addin addin = AddinEngine.Registry.GetAddin (id); if (addin == null) { - AddinManager.ReportError ("Required add-in not found", id, null, false); + AddinEngine.ReportError ("Required add-in not found", id, null, false); return; } // Take note that this add-in has been enabled at run-time @@ -476,7 +493,7 @@ namespace Mono.Addins LoadModuleExtensionNodes (ext, data.AddinId, node.ExtensionNodeSet, loadedNodes); } else - AddinManager.ReportError ("Extension node not found or not extensible: " + ext.Path, id, null, false); + AddinEngine.ReportError ("Extension node not found or not extensible: " + ext.Path, id, null, false); } } } @@ -538,7 +555,7 @@ namespace Mono.Addins // The event is called for all extensions, even for those not loaded. This is for coherence, // although that something that it doesn't make much sense to do (subcribing the ExtensionChanged // event without first getting the list of nodes that may change). - Addin addin = AddinManager.Registry.GetAddin (id); + Addin addin = AddinEngine.Registry.GetAddin (id); if (addin != null) { ArrayList paths = new ArrayList (); foreach (ModuleDescription mod in addin.Description.AllModules) { @@ -632,7 +649,7 @@ namespace Mono.Addins bool added = false; for (int n=0; n<loadData.Count; n++) { ExtensionLoadData other = (ExtensionLoadData) loadData [n]; - if (AddinManager.Registry.AddinDependsOn (other.AddinId, ed.AddinId)) { + if (AddinEngine.Registry.AddinDependsOn (other.AddinId, ed.AddinId)) { loadData.Insert (n, ed); added = true; break; @@ -652,7 +669,7 @@ namespace Mono.Addins if (cnode != null && cnode.ExtensionNodeSet != null) LoadModuleExtensionNodes (ext, data.AddinId, cnode.ExtensionNodeSet, loadedNodes); else - AddinManager.ReportError ("Extension node not found or not extensible: " + ext.Path, data.AddinId, null, false); + AddinEngine.ReportError ("Extension node not found or not extensible: " + ext.Path, data.AddinId, null, false); } } // Call the OnAddinLoaded method on nodes, if the add-in is already loaded @@ -668,14 +685,14 @@ namespace Mono.Addins Addin pinfo = null; // Root add-ins are not returned by GetInstalledAddin. - RuntimeAddin addin = AddinManager.SessionService.GetAddin (id); + RuntimeAddin addin = AddinEngine.GetAddin (id); if (addin != null) pinfo = addin.Addin; else - pinfo = AddinManager.Registry.GetAddin (id); + pinfo = AddinEngine.Registry.GetAddin (id); if (pinfo == null) { - AddinManager.ReportError ("Required add-in not found", id, null, false); + AddinEngine.ReportError ("Required add-in not found", id, null, false); return null; } if (!pinfo.Enabled) @@ -719,7 +736,7 @@ namespace Mono.Addins ArrayList addedNodes = new ArrayList (); tree.LoadExtension (addinId, extension, addedNodes); - RuntimeAddin ad = AddinManager.SessionService.GetAddin (addinId); + RuntimeAddin ad = AddinEngine.GetAddin (addinId); if (ad != null) { foreach (TreeNode nod in addedNodes) { // Don't call OnAddinLoaded here. Do it when the entire extension point has been loaded. @@ -734,7 +751,7 @@ namespace Mono.Addins foreach (Dependency dep in module.Dependencies) { AddinDependency pdep = dep as AddinDependency; if (pdep != null) { - Addin pinfo = AddinManager.Registry.GetAddin (Addin.GetFullId (conf.Namespace, pdep.AddinId, pdep.Version)); + Addin pinfo = AddinEngine.Registry.GetAddin (Addin.GetFullId (conf.Namespace, pdep.AddinId, pdep.Version)); if (pinfo == null || !pinfo.Enabled) return false; } @@ -778,7 +795,7 @@ namespace Mono.Addins } else { // Create if not found - TreeNode newNode = new TreeNode (part); + TreeNode newNode = new TreeNode (AddinEngine, part); dstNode.AddChildNode (newNode); dstNode = newNode; diff --git a/Mono.Addins/Mono.Addins/ExtensionNode.cs b/Mono.Addins/Mono.Addins/ExtensionNode.cs index b299181..39b93a9 100644 --- a/Mono.Addins/Mono.Addins/ExtensionNode.cs +++ b/Mono.Addins/Mono.Addins/ExtensionNode.cs @@ -45,6 +45,7 @@ namespace Mono.Addins string addinId; ExtensionNodeType nodeType; ModuleDescription module; + AddinEngine addinEngine; event ExtensionNodeEventHandler extensionNodeChanged; public string Id { @@ -77,8 +78,9 @@ namespace Mono.Addins treeNode = node; } - internal void SetData (string plugid, ExtensionNodeType nodeType, ModuleDescription module) + internal void SetData (AddinEngine addinEngine, string plugid, ExtensionNodeType nodeType, ModuleDescription module) { + this.addinEngine = addinEngine; this.addinId = plugid; this.nodeType = nodeType; this.module = module; @@ -95,9 +97,9 @@ namespace Mono.Addins public RuntimeAddin Addin { get { if (addin == null && addinId != null) { - if (!AddinManager.SessionService.IsAddinLoaded (addinId)) - AddinManager.SessionService.LoadAddin (null, addinId, true); - addin = AddinManager.SessionService.GetAddin (addinId); + if (!addinEngine.IsAddinLoaded (addinId)) + addinEngine.LoadAddin (null, addinId, true); + addin = addinEngine.GetAddin (addinId); if (addin != null) addin = addin.GetModule (module); } @@ -114,7 +116,7 @@ namespace Mono.Addins try { value (this, new ExtensionNodeEventArgs (ExtensionChange.Add, node)); } catch (Exception ex) { - AddinManager.ReportError (null, node.Addin != null ? node.Addin.Id : null, ex, false); + addinEngine.ReportError (null, node.Addin != null ? node.Addin.Id : null, ex, false); } } } @@ -135,7 +137,7 @@ namespace Mono.Addins } } catch (Exception ex) { - AddinManager.ReportError (null, null, ex, false); + addinEngine.ReportError (null, null, ex, false); childNodes = ExtensionNodeList.Empty; return childNodes; } finally { @@ -152,7 +154,7 @@ namespace Mono.Addins if (cn.ExtensionNode != null && cn.IsEnabled) list.Add (cn.ExtensionNode); } catch (Exception ex) { - AddinManager.ReportError (null, null, ex, false); + addinEngine.ReportError (null, null, ex, false); } } if (list.Count > 0) @@ -201,7 +203,7 @@ namespace Mono.Addins for (int n=0; n<ChildNodes.Count; n++) { InstanceExtensionNode node = ChildNodes [n] as InstanceExtensionNode; if (node == null) { - AddinManager.ReportError ("Error while getting object for node in path '" + Path + "'. Extension node is not a subclass of InstanceExtensionNode.", null, null, false); + addinEngine.ReportError ("Error while getting object for node in path '" + Path + "'. Extension node is not a subclass of InstanceExtensionNode.", null, null, false); continue; } @@ -212,7 +214,7 @@ namespace Mono.Addins list.Add (node.CreateInstance (arrayElementType)); } catch (Exception ex) { - AddinManager.ReportError ("Error while getting object for node in path '" + Path + "'.", node.AddinId, ex, false); + addinEngine.ReportError ("Error while getting object for node in path '" + Path + "'.", node.AddinId, ex, false); } } return list.ToArray (arrayElementType); diff --git a/Mono.Addins/Mono.Addins/ExtensionPointAttribute.cs b/Mono.Addins/Mono.Addins/ExtensionPointAttribute.cs index 3e48ef0..215548f 100644 --- a/Mono.Addins/Mono.Addins/ExtensionPointAttribute.cs +++ b/Mono.Addins/Mono.Addins/ExtensionPointAttribute.cs @@ -107,12 +107,12 @@ namespace Mono.Addins set { name = value; } } - public Type CustomAttributeType { + public Type ExtensionAttributeType { get { return this.customAttributeType; } set { this.customAttributeType = value; customAttributeTypeName = value.FullName; } } - internal string CustomAttributeTypeName { + internal string ExtensionAttributeTypeName { get { return this.customAttributeTypeName; } set { this.customAttributeTypeName = value; } } diff --git a/Mono.Addins/Mono.Addins/ExtensionTree.cs b/Mono.Addins/Mono.Addins/ExtensionTree.cs index 43b505e..4bf0c34 100644 --- a/Mono.Addins/Mono.Addins/ExtensionTree.cs +++ b/Mono.Addins/Mono.Addins/ExtensionTree.cs @@ -42,7 +42,7 @@ namespace Mono.Addins internal const string AutoIdPrefix = "__nid_"; ExtensionContext context; - public ExtensionTree (ExtensionContext context): base ("") + public ExtensionTree (AddinEngine addinEngine, ExtensionContext context): base (addinEngine, "") { this.context = context; } @@ -56,7 +56,7 @@ namespace Mono.Addins { TreeNode tnode = GetNode (extension.Path); if (tnode == null) { - AddinManager.ReportError ("Can't load extensions for path '" + extension.Path + "'. Extension point not defined.", addin, null, false); + addinEngine.ReportError ("Can't load extensions for path '" + extension.Path + "'. Extension point not defined.", addin, null, false); return; } @@ -80,7 +80,7 @@ namespace Mono.Addins } if (elem.NodeName == "Condition") { - Condition cond = new Condition (elem, parentCondition); + Condition cond = new Condition (AddinEngine, elem, parentCondition); LoadExtensionElement (tnode, addin, elem.ChildNodes, module, ref curPos, cond, false, addedNodes); continue; } @@ -99,10 +99,10 @@ namespace Mono.Addins } // Find the type of the node in this extension - ExtensionNodeType ntype = AddinManager.SessionService.FindType (tnode.ExtensionNodeSet, elem.NodeName, addin); + ExtensionNodeType ntype = addinEngine.FindType (tnode.ExtensionNodeSet, elem.NodeName, addin); if (ntype == null) { - AddinManager.ReportError ("Node '" + elem.NodeName + "' not allowed in extension: " + tnode.GetPath (), addin, null, false); + addinEngine.ReportError ("Node '" + elem.NodeName + "' not allowed in extension: " + tnode.GetPath (), addin, null, false); continue; } @@ -110,7 +110,7 @@ namespace Mono.Addins if (id.Length == 0) id = AutoIdPrefix + (++internalId); - TreeNode cnode = new TreeNode (id); + TreeNode cnode = new TreeNode (addinEngine, id); ExtensionNode enode = ReadNode (cnode, addin, ntype, elem, module); if (enode == null) @@ -149,16 +149,16 @@ namespace Mono.Addins return new AndCondition ((BaseCondition[]) conds.ToArray (typeof(BaseCondition)), parentCondition); else { if (conds.Count != 1) { - AddinManager.ReportError ("Invalid complex condition element '" + elem.NodeName + "'. 'Not' condition can only have one parameter.", null, null, false); + addinEngine.ReportError ("Invalid complex condition element '" + elem.NodeName + "'. 'Not' condition can only have one parameter.", null, null, false); return new NullCondition (); } return new NotCondition ((BaseCondition) conds [0], parentCondition); } } if (elem.NodeName == "Condition") { - return new Condition (elem, parentCondition); + return new Condition (AddinEngine, elem, parentCondition); } - AddinManager.ReportError ("Invalid complex condition element '" + elem.NodeName + "'.", null, null, false); + addinEngine.ReportError ("Invalid complex condition element '" + elem.NodeName + "'.", null, null, false); return new NullCondition (); } @@ -173,31 +173,31 @@ namespace Mono.Addins ExtensionNode node; node = Activator.CreateInstance (ntype.Type) as ExtensionNode; if (node == null) { - AddinManager.ReportError ("Extension node type '" + ntype.Type + "' must be a subclass of ExtensionNode", addin, null, false); + addinEngine.ReportError ("Extension node type '" + ntype.Type + "' must be a subclass of ExtensionNode", addin, null, false); return null; } tnode.AttachExtensionNode (node); - node.SetData (addin, ntype, module); + node.SetData (addinEngine, addin, ntype, module); node.Read (elem); return node; } catch (Exception ex) { - AddinManager.ReportError ("Could not read extension node of type '" + ntype.Type + "' from extension path '" + tnode.GetPath() + "'", addin, ex, false); + addinEngine.ReportError ("Could not read extension node of type '" + ntype.Type + "' from extension path '" + tnode.GetPath() + "'", addin, ex, false); return null; } } bool InitializeNodeType (ExtensionNodeType ntype) { - RuntimeAddin p = AddinManager.SessionService.GetAddin (ntype.AddinId); + RuntimeAddin p = addinEngine.GetAddin (ntype.AddinId); if (p == null) { - if (!AddinManager.SessionService.IsAddinLoaded (ntype.AddinId)) { - if (!AddinManager.SessionService.LoadAddin (null, ntype.AddinId, false)) + if (!addinEngine.IsAddinLoaded (ntype.AddinId)) { + if (!addinEngine.LoadAddin (null, ntype.AddinId, false)) return false; - p = AddinManager.SessionService.GetAddin (ntype.AddinId); + p = addinEngine.GetAddin (ntype.AddinId); if (p == null) { - AddinManager.ReportError ("Add-in not found", ntype.AddinId, null, false); + addinEngine.ReportError ("Add-in not found", ntype.AddinId, null, false); return false; } } @@ -209,7 +209,7 @@ namespace Mono.Addins if (ntype.CustomAttributeTypeName.Length > 0) { Type attType = p.GetType (ntype.CustomAttributeTypeName, false); if (attType == null) { - AddinManager.ReportError ("Custom attribute type '" + ntype.CustomAttributeTypeName + "' not found.", ntype.AddinId, null, false); + addinEngine.ReportError ("Custom attribute type '" + ntype.CustomAttributeTypeName + "' not found.", ntype.AddinId, null, false); return false; } ntype.Type = typeof(TypeExtensionNode<>).MakeGenericType (attType); @@ -221,7 +221,7 @@ namespace Mono.Addins else { ntype.Type = p.GetType (ntype.TypeName, false); if (ntype.Type == null) { - AddinManager.ReportError ("Extension node type '" + ntype.TypeName + "' not found.", ntype.AddinId, null, false); + addinEngine.ReportError ("Extension node type '" + ntype.TypeName + "' not found.", ntype.AddinId, null, false); return false; } } diff --git a/Mono.Addins/Mono.Addins/ImportAddinAssemblyAttribute.cs b/Mono.Addins/Mono.Addins/ImportAddinAssemblyAttribute.cs new file mode 100644 index 0000000..257b194 --- /dev/null +++ b/Mono.Addins/Mono.Addins/ImportAddinAssemblyAttribute.cs @@ -0,0 +1,50 @@ +// +// ImportAddinAssemblyAttribute.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +namespace Mono.Addins +{ + public class ImportAddinAssemblyAttribute: Attribute + { + string filePath; + bool scan = true; + + public ImportAddinAssemblyAttribute (string filePath) + { + this.filePath = filePath; + } + + public string FilePath { + get { return filePath; } + set { filePath = value; } + } + + public bool Scan { + get { return this.scan; } + set { this.scan = value; } + } + } +} + diff --git a/Mono.Addins/Mono.Addins/AddinCategoryAttribute.cs b/Mono.Addins/Mono.Addins/ImportAddinFileAttribute.cs index adb36b8..79a3c19 100644 --- a/Mono.Addins/Mono.Addins/AddinCategoryAttribute.cs +++ b/Mono.Addins/Mono.Addins/ImportAddinFileAttribute.cs @@ -1,5 +1,5 @@ // -// AddinCategoryAttribute.cs +// ImportAddinFileAttribute.cs // // Author: // Lluis Sanchez Gual <lluis@novell.com> @@ -23,24 +23,21 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - using System; - namespace Mono.Addins { - [AttributeUsage (AttributeTargets.Assembly)] - public class AddinCategoryAttribute: Attribute + public class ImportAddinFileAttribute: Attribute { - string name; + string filePath; - public AddinCategoryAttribute (string name) + public ImportAddinFileAttribute (string filePath) { - this.name = name; + this.filePath = filePath; } - public string Name { - get { return this.name; } - set { this.name = value; } + public string FilePath { + get { return filePath; } + set { filePath = value; } } } } diff --git a/Mono.Addins/Mono.Addins/RuntimeAddin.cs b/Mono.Addins/Mono.Addins/RuntimeAddin.cs index c702f49..8babd42 100644 --- a/Mono.Addins/Mono.Addins/RuntimeAddin.cs +++ b/Mono.Addins/Mono.Addins/RuntimeAddin.cs @@ -55,13 +55,16 @@ namespace Mono.Addins ResourceManager[] resourceManagers; AddinLocalizer localizer; ModuleDescription module; + AddinEngine addinEngine; - internal RuntimeAddin () + internal RuntimeAddin (AddinEngine addinEngine) { + this.addinEngine = addinEngine; } - internal RuntimeAddin (RuntimeAddin parentAddin, ModuleDescription module) + internal RuntimeAddin (AddinEngine addinEngine, RuntimeAddin parentAddin, ModuleDescription module) { + this.addinEngine = addinEngine; this.parentAddin = parentAddin; this.module = module; id = parentAddin.id; @@ -304,7 +307,7 @@ namespace Mono.Addins if (localizer != null) return localizer; else - return AddinManager.DefaultLocalizer; + return addinEngine.DefaultLocalizer; } } @@ -317,7 +320,7 @@ namespace Mono.Addins if (module.RuntimeAddin != null) return module.RuntimeAddin; - RuntimeAddin addin = new RuntimeAddin (this, module); + RuntimeAddin addin = new RuntimeAddin (addinEngine, this, module); return addin; } @@ -364,11 +367,11 @@ namespace Mono.Addins foreach (Dependency dep in module.Dependencies) { AddinDependency pdep = dep as AddinDependency; if (pdep != null) { - RuntimeAddin adn = AddinManager.SessionService.GetAddin (Addin.GetFullId (ns, pdep.AddinId, pdep.Version)); + RuntimeAddin adn = addinEngine.GetAddin (Addin.GetFullId (ns, pdep.AddinId, pdep.Version)); if (adn != null) plugList.Add (adn); else - AddinManager.ReportError ("Add-in dependency not loaded: " + pdep.FullAddinId, module.ParentAddinDescription.AddinId, null, false); + addinEngine.ReportError ("Add-in dependency not loaded: " + pdep.FullAddinId, module.ParentAddinDescription.AddinId, null, false); } } return depAddins = (RuntimeAddin[]) plugList.ToArray (typeof(RuntimeAddin)); @@ -411,7 +414,7 @@ namespace Mono.Addins if (emap == null) return; foreach (ExtensionNodeSet rel in emap.ExtensionNodeSets) - AddinManager.SessionService.UnregisterNodeSet (rel); + addinEngine.UnregisterNodeSet (rel); } bool CheckAddinDependencies (ModuleDescription module, bool forceLoadAssemblies) @@ -420,10 +423,10 @@ namespace Mono.Addins AddinDependency pdep = dep as AddinDependency; if (pdep == null) continue; - if (!AddinManager.SessionService.IsAddinLoaded (pdep.FullAddinId)) + if (!addinEngine.IsAddinLoaded (pdep.FullAddinId)) return false; if (forceLoadAssemblies) - AddinManager.SessionService.GetAddin (pdep.FullAddinId).EnsureAssembliesLoaded (); + addinEngine.GetAddin (pdep.FullAddinId).EnsureAssembliesLoaded (); } return true; } @@ -444,7 +447,7 @@ namespace Mono.Addins LoadModule (module, asmList); assemblies = (Assembly[]) asmList.ToArray (typeof(Assembly)); - AddinManager.SessionService.RegisterAssemblies (this); + addinEngine.RegisterAssemblies (this); } } } diff --git a/Mono.Addins/Mono.Addins/TreeNode.cs b/Mono.Addins/Mono.Addins/TreeNode.cs index c738d8d..969ce00 100644 --- a/Mono.Addins/Mono.Addins/TreeNode.cs +++ b/Mono.Addins/Mono.Addins/TreeNode.cs @@ -45,16 +45,22 @@ namespace Mono.Addins ExtensionNodeSet nodeTypes; ExtensionPoint extensionPoint; BaseCondition condition; + protected AddinEngine addinEngine; - public TreeNode (string id) + public TreeNode (AddinEngine addinEngine, string id) { this.id = id; + this.addinEngine = addinEngine; // Root node if (id.Length == 0) childrenLoaded = true; } + public AddinEngine AddinEngine { + get { return addinEngine; } + } + internal void AttachExtensionNode (ExtensionNode enode) { this.extensionNode = enode; @@ -70,7 +76,7 @@ namespace Mono.Addins get { if (extensionNode == null && extensionPoint != null) { extensionNode = new ExtensionNode (); - extensionNode.SetData (extensionPoint.RootAddin, null, null); + extensionNode.SetData (addinEngine, extensionPoint.RootAddin, null, null); AttachExtensionNode (extensionNode); } return extensionNode; @@ -187,7 +193,7 @@ namespace Mono.Addins } if (buildPath) { - TreeNode newNode = new TreeNode (part); + TreeNode newNode = new TreeNode (addinEngine, part); curNode.AddChildNode (newNode); curNode = newNode; } else @@ -287,7 +293,7 @@ namespace Mono.Addins if (extensionPoint != null) { foreach (ExtensionNodeType nt in extensionPoint.NodeSet.NodeTypes) { if (nt.ObjectTypeName.Length > 0 && (nodeName.Length == 0 || nodeName == nt.Id)) { - RuntimeAddin addin = AddinManager.SessionService.GetAddin (extensionPoint.RootAddin); + RuntimeAddin addin = addinEngine.GetAddin (extensionPoint.RootAddin); Type ot = addin.GetType (nt.ObjectTypeName); if (ot != null) { if (ot.IsAssignableFrom (type)) { @@ -334,7 +340,7 @@ namespace Mono.Addins { if (extensionPoint != null) { string aid = Addin.GetIdName (extensionPoint.ParentAddinDescription.AddinId); - RuntimeAddin ad = AddinManager.SessionService.GetAddin (aid); + RuntimeAddin ad = addinEngine.GetAddin (aid); if (ad != null) extensionPoint = ad.Addin.Description.ExtensionPoints [GetPath ()]; } diff --git a/Mono.Addins/Mono.Addins/TypeExtensionPointAttribute.cs b/Mono.Addins/Mono.Addins/TypeExtensionPointAttribute.cs index 2b06753..d73640b 100644 --- a/Mono.Addins/Mono.Addins/TypeExtensionPointAttribute.cs +++ b/Mono.Addins/Mono.Addins/TypeExtensionPointAttribute.cs @@ -82,12 +82,12 @@ namespace Mono.Addins set { nodeTypeName = value; nodeType = null; } } - public Type CustomAttributeType { + public Type ExtensionAttributeType { get { return this.customAttributeType; } set { this.customAttributeType = value; customAttributeTypeName = value.FullName; } } - internal string CustomAttributeTypeName { + internal string ExtensionAttributeTypeName { get { return this.customAttributeTypeName; } set { this.customAttributeTypeName = value; } } |