diff options
Diffstat (limited to 'Mono.Addins/Mono.Addins.Database')
4 files changed, 127 insertions, 59 deletions
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); |