From 82460570998db86d5201acd1523fda44c93cd3d3 Mon Sep 17 00:00:00 2001 From: Lluis Sanchez Date: Thu, 21 Nov 2013 18:51:45 +0100 Subject: Allow embedding .addin files into submodule assemblies --- Mono.Addins/Mono.Addins.Database/AddinScanner.cs | 82 ++++++++++++++++------ .../Mono.Addins.Description/AddinDescription.cs | 3 +- .../Mono.Addins.Description/ModuleDescription.cs | 6 ++ 3 files changed, 68 insertions(+), 23 deletions(-) diff --git a/Mono.Addins/Mono.Addins.Database/AddinScanner.cs b/Mono.Addins/Mono.Addins.Database/AddinScanner.cs index 21d6f4a..d323649 100644 --- a/Mono.Addins/Mono.Addins.Database/AddinScanner.cs +++ b/Mono.Addins/Mono.Addins.Database/AddinScanner.cs @@ -551,22 +551,8 @@ namespace Mono.Addins.Database // Get the config file from the resources, if there is one - foreach (string res in reflector.GetResourceNames (asm)) { - if (res.EndsWith (".addin") || res.EndsWith (".addin.xml")) { - 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 - monitor.ReportError ("Duplicate add-in definition found in assembly: " + filePath, null); - return false; - } - config = AddinDescription.Merge (config, ad); - } else - config = ad; - } - } - } + if (!ScanEmbeddedDescription (monitor, filePath, reflector, asm, out config)) + return false; if (config == null) { // In this case, only scan the assembly if it has the Addin attribute. @@ -593,6 +579,29 @@ namespace Mono.Addins.Database } } + static bool ScanEmbeddedDescription (IProgressStatus monitor, string filePath, IAssemblyReflector reflector, object asm, out AddinDescription config) + { + config = null; + foreach (string res in reflector.GetResourceNames (asm)) { + if (res.EndsWith (".addin") || res.EndsWith (".addin.xml")) { + 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 + monitor.ReportError ("Duplicate add-in definition found in assembly: " + filePath, null); + return false; + } + config = AddinDescription.Merge (config, ad); + } + else + config = ad; + } + } + } + return true; + } + bool ScanDescription (IProgressStatus monitor, IAssemblyReflector reflector, AddinDescription config, object rootAssembly, AddinScanResult scanResult) { // First of all scan the main module @@ -666,14 +675,14 @@ namespace Mono.Addins.Database if (!config.IsRoot) { foreach (ModuleDescription mod in config.OptionalModules) { try { - assemblies.Clear (); + var asmList = new List> (); for (int n=0; n (asmFile,asm)); scanResult.AddPathToIgnore (Path.GetFullPath (asmFile)); ScanAssemblyImports (reflector, mod, asm); } @@ -688,9 +697,9 @@ namespace Mono.Addins.Database scanResult.AddPathToIgnore (Path.GetFullPath (path)); } - foreach (object asm in assemblies) - ScanAssemblyContents (reflector, config, mod, asm, scanResult); - + foreach (var asm in asmList) + ScanSubmodule (monitor, mod, reflector, config, scanResult, asm.Item1, asm.Item2); + } catch (Exception ex) { ReportReflectionException (monitor, ex, config, scanResult); } @@ -701,6 +710,37 @@ namespace Mono.Addins.Database return true; } + bool ScanSubmodule (IProgressStatus monitor, ModuleDescription mod, IAssemblyReflector reflector, AddinDescription config, AddinScanResult scanResult, string assemblyName, object asm) + { + AddinDescription mconfig; + ScanEmbeddedDescription (monitor, assemblyName, reflector, asm, out mconfig); + if (mconfig != null) { + if (!mconfig.IsExtensionModel) { + monitor.ReportError ("Submodules can't define new add-ins: " + assemblyName, null); + return false; + } + if (mconfig.OptionalModules.Count != 0) { + monitor.ReportError ("Submodules can't define nested submodules: " + assemblyName, null); + return false; + } + if (mconfig.ConditionTypes.Count != 0) { + monitor.ReportError ("Submodules can't define condition types: " + assemblyName, null); + return false; + } + if (mconfig.ExtensionNodeSets.Count != 0) { + monitor.ReportError ("Submodules can't define extension node sets: " + assemblyName, null); + return false; + } + if (mconfig.ExtensionPoints.Count != 0) { + monitor.ReportError ("Submodules can't define extension points sets: " + assemblyName, null); + return false; + } + mod.MergeWith (mconfig.MainModule); + } + ScanAssemblyContents (reflector, config, mod, asm, scanResult); + return true; + } + void ReportReflectionException (IProgressStatus monitor, Exception ex, AddinDescription config, AddinScanResult scanResult) { scanResult.AddFileToWithFailure (config.AddinFile); diff --git a/Mono.Addins/Mono.Addins.Description/AddinDescription.cs b/Mono.Addins/Mono.Addins.Description/AddinDescription.cs index 3799751..00eaaf2 100644 --- a/Mono.Addins/Mono.Addins.Description/AddinDescription.cs +++ b/Mono.Addins/Mono.Addins.Description/AddinDescription.cs @@ -1193,8 +1193,7 @@ namespace Mono.Addins.Description desc1.MainModule.Assemblies.Add (s); foreach (string s in desc2.MainModule.DataFiles) desc1.MainModule.DataFiles.Add (s); - desc1.MainModule.Dependencies.AddRange (desc2.MainModule.Dependencies); - desc1.MainModule.Extensions.AddRange (desc2.MainModule.Extensions); + desc1.MainModule.MergeWith (desc2.MainModule); return desc1; } diff --git a/Mono.Addins/Mono.Addins.Description/ModuleDescription.cs b/Mono.Addins/Mono.Addins.Description/ModuleDescription.cs index f57a33c..adc04f0 100644 --- a/Mono.Addins/Mono.Addins.Description/ModuleDescription.cs +++ b/Mono.Addins/Mono.Addins.Description/ModuleDescription.cs @@ -66,6 +66,12 @@ namespace Mono.Addins.Description { } + internal void MergeWith (ModuleDescription module) + { + Dependencies.AddRange (module.Dependencies); + Extensions.AddRange (module.Extensions); + } + /// /// Checks if this module depends on the specified add-in. /// -- cgit v1.2.3