void CollectExtensionData(IProgressStatus monitor, AddinIndex addinHash, AddinDescription conf, AddinUpdateData updateData) { IEnumerable<string> missingDeps = addinHash.GetMissingDependencies (conf, conf.MainModule); if (missingDeps.Any ()) { string w = "The add-in '" + conf.AddinId + "' could not be updated because some of its dependencies are missing or not compatible:"; w += BuildMissingAddinsList (addinHash, conf, missingDeps); monitor.ReportWarning (w); return; } CollectModuleExtensionData (conf, conf.MainModule, updateData, addinHash); foreach (ModuleDescription module in conf.OptionalModules) { missingDeps = addinHash.GetMissingDependencies (conf, module); if (missingDeps.Any ()) { if (monitor.LogLevel > 1) { string w = "An optional module of the add-in '" + conf.AddinId + "' could not be updated because some of its dependencies are missing or not compatible:"; w += BuildMissingAddinsList (addinHash, conf, missingDeps); } } else CollectModuleExtensionData (conf, module, updateData, addinHash); } }
string BuildMissingAddinsList(AddinIndex addinHash, AddinDescription conf, IEnumerable<string> missingDeps) { string w = ""; foreach (string dep in missingDeps) { var found = addinHash.GetSimilarExistingAddin (conf, dep); if (found == null) w += "\n missing: " + dep; else w += "\n required: " + dep + ", found: " + found.AddinId; } return w; }
void AddChildExtensions(AddinDescription conf, ModuleDescription module, AddinUpdateData updateData, AddinIndex index, string path, ExtensionNodeDescriptionCollection nodes, bool conditionChildren) { // Don't register conditions as extension nodes. if (!conditionChildren) updateData.RegisterExtension (conf, module, path); foreach (ExtensionNodeDescription node in nodes) { if (node.NodeName == "ComplexCondition") continue; updateData.RelExtensionNodes++; string id = node.GetAttribute ("id"); if (id.Length != 0) { bool isCondition = node.NodeName == "Condition"; if (isCondition) { // Find the add-in that provides the implementation for this condition. // Store that id in the condition. The add-in engine will ensure the add-in // is loaded when it tries to evaluate this condition. var condAsm = index.FindCondition (conf, module, id); if (condAsm != null) node.SetAttribute (Condition.SourceAddinAttribute, condAsm); } AddChildExtensions (conf, module, updateData, index, path + "/" + id, node.ChildNodes, isCondition); } } }
void GenerateAddinExtensionMapsInternal(IProgressStatus monitor, string domain, List<string> addinsToUpdate, List<string> addinsToUpdateRelations, List<string> removedAddins) { AddinUpdateData updateData = new AddinUpdateData (this, monitor); // Clear cached data cachedAddinSetupInfos.Clear (); // Collect all information AddinIndex addinHash = new AddinIndex (); if (monitor.LogLevel > 1) monitor.Log ("Generating add-in extension maps"); Hashtable changedAddins = null; ArrayList descriptionsToSave = new ArrayList (); ArrayList files = new ArrayList (); bool partialGeneration = addinsToUpdate != null; string[] domains = GetDomains ().Where (d => d == domain || d == GlobalDomain).ToArray (); // Get the files to be updated if (partialGeneration) { changedAddins = new Hashtable (); if (monitor.LogLevel > 2) monitor.Log ("Doing a partial registry update.\nAdd-ins to be updated:"); // Get the files and ids of all add-ins that have to be updated // Include removed add-ins: if there are several instances of the same add-in, removing one of // them will make other instances to show up. If there is a single instance, its files are // already removed. foreach (string sa in addinsToUpdate.Union (removedAddins)) { changedAddins [sa] = sa; if (monitor.LogLevel > 2) monitor.Log (" - " + sa); foreach (string file in GetAddinFiles (sa, domains)) { if (!files.Contains (file)) { files.Add (file); string an = Path.GetFileNameWithoutExtension (file); changedAddins [an] = an; if (monitor.LogLevel > 2 && an != sa) monitor.Log (" - " + an); } } } if (monitor.LogLevel > 2) monitor.Log ("Add-ins whose relations have to be updated:"); // Get the files and ids of all add-ins whose relations have to be updated foreach (string sa in addinsToUpdateRelations) { foreach (string file in GetAddinFiles (sa, domains)) { if (!files.Contains (file)) { if (monitor.LogLevel > 2) { string an = Path.GetFileNameWithoutExtension (file); monitor.Log (" - " + an); } files.Add (file); } } } } else { foreach (var dom in domains) files.AddRange (fileDatabase.GetDirectoryFiles (Path.Combine (AddinCachePath, dom), "*.maddin")); } // Load the descriptions. foreach (string file in files) { AddinDescription conf; if (!ReadAddinDescription (monitor, file, out conf)) { SafeDelete (monitor, file); continue; } // If the original file does not exist, the description can be deleted if (!fs.FileExists (conf.AddinFile)) { SafeDelete (monitor, file); continue; } // Remove old data from the description. Remove the data of the add-ins that // have changed. This data will be re-added later. conf.UnmergeExternalData (changedAddins); descriptionsToSave.Add (conf); addinHash.Add (conf); } // Sort the add-ins, to make sure add-ins are processed before // all their dependencies var sorted = addinHash.GetSortedAddins (); // Register extension points and node sets foreach (AddinDescription conf in sorted) CollectExtensionPointData (conf, updateData); if (monitor.LogLevel > 2) monitor.Log ("Registering new extensions:"); // Register extensions foreach (AddinDescription conf in sorted) { if (changedAddins == null || changedAddins.ContainsKey (conf.AddinId)) { if (monitor.LogLevel > 2) monitor.Log ("- " + conf.AddinId + " (" + conf.Domain + ")"); CollectExtensionData (monitor, addinHash, conf, updateData); } } // Save the maps foreach (AddinDescription conf in descriptionsToSave) { ConsolidateExtensions (conf); conf.SaveBinary (fileDatabase); } if (monitor.LogLevel > 1) { monitor.Log ("Addin relation map generated."); monitor.Log (" Addins Updated: " + descriptionsToSave.Count); monitor.Log (" Extension points: " + updateData.RelExtensionPoints); monitor.Log (" Extensions: " + updateData.RelExtensions); monitor.Log (" Extension nodes: " + updateData.RelExtensionNodes); monitor.Log (" Node sets: " + updateData.RelNodeSetTypes); } }
void CollectModuleExtensionData(AddinDescription conf, ModuleDescription module, AddinUpdateData updateData, AddinIndex index) { foreach (Extension ext in module.Extensions) { updateData.RelExtensions++; updateData.RegisterExtension (conf, module, ext); AddChildExtensions (conf, module, updateData, index, ext.Path, ext.ExtensionNodes, false); } }
void GenerateAddinExtensionMapsInternal (IProgressStatus monitor, ArrayList addinsToUpdate, ArrayList removedAddins) { AddinUpdateData updateData = new AddinUpdateData (this, monitor); // Clear cached data cachedAddinSetupInfos.Clear (); // Collect all information AddinIndex addinHash = new AddinIndex (); if (monitor.LogLevel > 1) monitor.Log ("Generating add-in extension maps"); Hashtable changedAddins = null; ArrayList descriptionsToSave = new ArrayList (); ArrayList files = new ArrayList (); bool partialGeneration = addinsToUpdate != null; string[] domains = GetDomains (); // Get the files to be updated if (partialGeneration) { changedAddins = new Hashtable (); foreach (string sa in addinsToUpdate) { changedAddins [sa] = sa; // Look for all versions of the add-in, because this id may be the id of a reference, // and the exact reference version may not be installed. string s = sa; int i = s.LastIndexOf (','); if (i != -1) s = s.Substring (0, i); s += ",*"; // Look for the add-in in any of the existing folders foreach (string domain in domains) { string mp = GetDescriptionPath (domain, s); string dir = Path.GetDirectoryName (mp); string pat = Path.GetFileName (mp); foreach (string fmp in fileDatabase.GetDirectoryFiles (dir, pat)) { if (files.Contains (fmp)) continue; files.Add (fmp); string an = Path.GetFileNameWithoutExtension (fmp); changedAddins [an] = an; } } } foreach (string s in removedAddins) changedAddins [s] = s; } else { foreach (string dom in domains) files.AddRange (fileDatabase.GetDirectoryFiles (Path.Combine (AddinCachePath, dom), "*.maddin")); } // Load the descriptions. foreach (string file in files) { AddinDescription conf; if (!ReadAddinDescription (monitor, file, out conf)) { SafeDelete (monitor, file); continue; } // If the original file does not exist, the description can be deleted if (!File.Exists (conf.AddinFile)) { SafeDelete (monitor, file); continue; } // Remove old data from the description. If changedAddins==null, removes all data. // Otherwise, removes data only from the addins in the table. conf.UnmergeExternalData (changedAddins); descriptionsToSave.Add (conf); addinHash.Add (conf); } // Sort the add-ins, to make sure add-ins are processed before // all their dependencies ArrayList sorted = addinHash.GetSortedAddins (); // Register extension points and node sets foreach (AddinDescription conf in sorted) CollectExtensionPointData (conf, updateData); // Register extensions foreach (AddinDescription conf in sorted) CollectExtensionData (conf, updateData); // Save the maps foreach (AddinDescription conf in descriptionsToSave) conf.SaveBinary (fileDatabase); if (monitor.LogLevel > 1) { monitor.Log ("Addin relation map generated."); monitor.Log (" Addins Updated: " + descriptionsToSave.Count); monitor.Log (" Extension points: " + updateData.RelExtensionPoints); monitor.Log (" Extensions: " + updateData.RelExtensions); monitor.Log (" Extension nodes: " + updateData.RelExtensionNodes); monitor.Log (" Node sets: " + updateData.RelNodeSetTypes); } }