void AddChildExtensions (AddinDescription conf, ModuleDescription module, AddinUpdateData updateData, 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;
				relExtensionNodes++;
				string id = node.GetAttribute ("id");
				if (id.Length != 0)
					AddChildExtensions (conf, module, updateData, path + "/" + id, node.ChildNodes, node.NodeName == "Condition");
			}
		}
		void GenerateAddinExtensionMapsInternal (IProgressStatus monitor, ArrayList addinsToUpdate, ArrayList removedAddins)
		{
			AddinUpdateData updateData = new AddinUpdateData (this);
			
			// Clear cached data
			cachedAddinSetupInfos.Clear ();
			
			// Collect all information
			
			Hashtable addinHash = new Hashtable ();
			
			relExtensionPoints = 0;
			relExtensions = 0;
			relNodeSetTypes = 0;
			relExtensionNodes = 0;
		
			if (monitor.VerboseLog)
				monitor.Log ("Generating add-in extension maps");
			
			Hashtable changedAddins = null;
			ArrayList descriptionsToSave = new ArrayList ();
			ArrayList files = new ArrayList ();
			
			bool partialGeneration = addinsToUpdate != null;
			
			// Get the files to be updated
			
			if (partialGeneration) {
				changedAddins = new Hashtable ();
				foreach (string s in addinsToUpdate) {
					changedAddins [s] = s;
					string mp = GetDescriptionPath (s);
					if (fileDatabase.Exists (mp))
						files.Add (mp);
					else
						files.AddRange (fileDatabase.GetObjectSharedFiles (this.AddinCachePath, s, ".mroot"));
				}
				foreach (string s in removedAddins)
					changedAddins [s] = s;
			}
			else {
				files.AddRange (fileDatabase.GetDirectoryFiles (AddinCachePath, "*.maddin"));
				files.AddRange (fileDatabase.GetDirectoryFiles (AddinCachePath, "*.mroot"));
			}
			
			// 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);
				
				// Register extension points and node sets from root add-ins
				if (conf.IsRoot) {
					foreach (ExtensionPoint ep in conf.ExtensionPoints)
						updateData.RegisterAddinRootExtensionPoint (conf, ep);
					foreach (ExtensionNodeSet ns in conf.ExtensionNodeSets)
						updateData.RegisterAddinRootNodeSet (conf, ns);
				}
				else
					addinHash [conf.AddinId] = conf;
			}
			
			foreach (AddinDescription conf in addinHash.Values) {
				CollectExtensionData (conf, updateData);
			}
			
			updateData.ResolveExtensions (monitor, addinHash);
			
			// Update the extension points defined by this add-in			
			foreach (ExtensionPoint ep in updateData.GetUnresolvedExtensionPoints ()) {
				AddinDescription am = (AddinDescription) addinHash [ep.RootAddin];
				ExtensionPoint amep = am.ExtensionPoints [ep.Path];
				if (amep != null) {
					amep.MergeWith (am.AddinId, ep);
					amep.RootAddin = ep.RootAddin;
				}
			}

			// Now update the node sets
			foreach (ExtensionPoint ep in updateData.GetUnresolvedExtensionSets ()) {
				AddinDescription am = (AddinDescription) addinHash [ep.RootAddin];
				ExtensionNodeSet nset = am.ExtensionNodeSets [ep.Path];
				if (nset != null)
					nset.MergeWith (am.AddinId, ep.NodeSet);
			}
			
			// Save the maps
			foreach (AddinDescription conf in descriptionsToSave)
				conf.SaveBinary (fileDatabase);
			
			if (monitor.VerboseLog) {
				monitor.Log ("Addin relation map generated.");
				monitor.Log ("  Addins Updated: " + descriptionsToSave.Count);
				monitor.Log ("  Extension points: " + relExtensionPoints);
				monitor.Log ("  Extensions: " + relExtensions);
				monitor.Log ("  Extension nodes: " + relExtensionNodes);
				monitor.Log ("  Node sets: " + relNodeSetTypes);
			}
		}
		// Collects extension data in a hash table. The key is the path, the value is a list
		// of add-ins ids that extend that path
		
		void CollectExtensionData (AddinDescription conf, AddinUpdateData updateData)
		{
			foreach (ExtensionNodeSet nset in conf.ExtensionNodeSets) {
				try {
					updateData.RegisterNodeSet (conf, nset);
					relNodeSetTypes++;
				} catch (Exception ex) {
					throw new InvalidOperationException ("Error reading node set: " + nset.Id, ex);
				}
			}
			
			foreach (ExtensionPoint ep in conf.ExtensionPoints) {
				try {
					updateData.RegisterExtensionPoint (conf, ep);
					relExtensionPoints++;
				} catch (Exception ex) {
					throw new InvalidOperationException ("Error reading extension point: " + ep.Path, ex);
				}
			}
			
			foreach (ModuleDescription module in conf.AllModules) {
				foreach (Extension ext in module.Extensions) {
					relExtensions++;
					updateData.RegisterExtension (conf, module, ext);
					AddChildExtensions (conf, module, updateData, ext.Path, ext.ExtensionNodes, false);
				}
			}
		}
Exemplo n.º 4
0
        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);
                }
            }
        }
Exemplo n.º 5
0
        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);
            }
        }
Exemplo n.º 6
0
        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);
            }
        }
Exemplo n.º 7
0
 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);
     }
 }
Exemplo n.º 8
0
        // Collects extension data in a hash table. The key is the path, the value is a list
        // of add-ins ids that extend that path
        void CollectExtensionPointData(AddinDescription conf, AddinUpdateData updateData)
        {
            foreach (ExtensionNodeSet nset in conf.ExtensionNodeSets) {
                try {
                    updateData.RegisterNodeSet (conf, nset);
                    updateData.RelNodeSetTypes++;
                } catch (Exception ex) {
                    throw new InvalidOperationException ("Error reading node set: " + nset.Id, ex);
                }
            }

            foreach (ExtensionPoint ep in conf.ExtensionPoints) {
                try {
                    updateData.RegisterExtensionPoint (conf, ep);
                    updateData.RelExtensionPoints++;
                } catch (Exception ex) {
                    throw new InvalidOperationException ("Error reading extension point: " + ep.Path, ex);
                }
            }
        }
		void CollectExtensionData (AddinDescription conf, AddinUpdateData updateData)
		{
			foreach (ModuleDescription module in conf.AllModules) {
				foreach (Extension ext in module.Extensions) {
					updateData.RelExtensions++;
					updateData.RegisterExtension (conf, module, ext);
					AddChildExtensions (conf, module, updateData, 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);
			}
		}