public ExtensionNode ReadNode(TreeNode tnode, string addin, ExtensionNodeType ntype, ExtensionNodeDescription elem) { try { if (ntype.Type == null) { if (!InitializeNodeType(ntype)) { return(null); } } 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); return(null); } tnode.AttachExtensionNode(node); node.SetData(addin, ntype); 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); return(null); } }
BaseCondition ReadComplexCondition(ExtensionNodeDescription elem, BaseCondition parentCondition) { if (elem.NodeName == "Or" || elem.NodeName == "And") { ArrayList conds = new ArrayList(); foreach (ExtensionNodeDescription celem in elem.ChildNodes) { conds.Add(ReadComplexCondition(celem, null)); } if (elem.NodeName == "Or") { return(new OrCondition((BaseCondition[])conds.ToArray(typeof(BaseCondition)), parentCondition)); } else { return(new AndCondition((BaseCondition[])conds.ToArray(typeof(BaseCondition)), parentCondition)); } } if (elem.NodeName == "Condition") { return(new Condition(elem, parentCondition)); } AddinManager.ReportError("Invalid complex condition element '" + elem.NodeName + "'.", null, null, false); return(new NullCondition()); }
internal ExtensionNodeType FindType(ExtensionNodeSet nset, string name, string callingAddinId) { if (nset == null) { return(null); } foreach (ExtensionNodeType nt in nset.NodeTypes) { if (nt.Id == name) { return(nt); } } foreach (string ns in nset.NodeSets) { ExtensionNodeSet regSet = (ExtensionNodeSet)nodeSets [ns]; if (regSet == null) { AddinManager.ReportError("Unknown node set: " + ns, callingAddinId, null, false); return(null); } ExtensionNodeType nt = FindType(regSet, name, callingAddinId); if (nt != null) { return(nt); } } return(null); }
public object[] GetChildObjects(Type arrayElementType, bool reuseCachedInstance) { ArrayList list = new ArrayList(ChildNodes.Count); 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); continue; } try { if (reuseCachedInstance) { list.Add(node.GetInstance(arrayElementType)); } else { list.Add(node.CreateInstance(arrayElementType)); } } catch (Exception ex) { AddinManager.ReportError("Error while getting object for node in path '" + Path + "'.", null, ex, false); } } return((object[])list.ToArray(arrayElementType)); }
void LoadModule(ModuleDescription module, string ns, ArrayList plugList, ArrayList asmList) { // Load the assemblies foreach (string s in module.Assemblies) { Assembly asm = null; // don't load the assembly if it's already loaded string asmPath = Path.Combine(baseDirectory, s); foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) { // Sorry, you can't load addins from // dynamic assemblies as get_Location // throws a NotSupportedException if (a is System.Reflection.Emit.AssemblyBuilder) { continue; } if (a.Location == asmPath) { asm = a; break; } } if (asm == null) { asm = Assembly.LoadFrom(asmPath); } asmList.Add(asm); } // Collect dependent ids 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)); if (adn != null) { plugList.Add(adn); } else { AddinManager.ReportError("Add-in dependency not loaded: " + pdep.FullAddinId, module.ParentAddinDescription.AddinId, null, false); } } } }
bool InsertAddin(IProgressStatus statusMonitor, Addin iad) { try { RuntimeAddin p = new RuntimeAddin(); // Read the config file and load the add-in assemblies AddinDescription description = p.Load(iad); // Register the add-in loadedAddins [Addin.GetIdName(p.Id)] = p; if (!AddinDatabase.RunningSetupProcess) { // Load the extension points and other addin data foreach (ExtensionNodeSet rel in description.ExtensionNodeSets) { RegisterNodeSet(rel); } foreach (ConditionTypeDescription cond in description.ConditionTypes) { Type ctype = p.GetType(cond.TypeName, true); defaultContext.RegisterCondition(cond.Id, ctype); } } foreach (ExtensionPoint ep in description.ExtensionPoints) { InsertExtensionPoint(p, ep); } foreach (Assembly asm in p.Assemblies) { loadedAssemblies [asm] = p; } // Fire loaded event defaultContext.NotifyAddinLoaded(p); AddinManager.ReportAddinLoad(p.Id); return(true); } catch (Exception ex) { AddinManager.ReportError("Extension could not be loaded", iad.Id, ex, false); if (statusMonitor != null) { statusMonitor.ReportError("Extension '" + iad.Id + "' could not be loaded.", ex); } return(false); } }
public void LoadExtension(string addin, Extension extension, ArrayList addedNodes) { 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); return; } int curPos = tnode.ChildCount; LoadExtensionElement(tnode, addin, extension.ExtensionNodes, ref curPos, tnode.Condition, false, addedNodes); }
ExtensionLoadData GetAddinExtensions(string id, ExtensionPoint ep) { Addin pinfo = null; // Root add-ins are not returned by GetInstalledAddin. RuntimeAddin addin = AddinManager.SessionService.GetAddin(id); if (addin != null) { pinfo = addin.Addin; } else { pinfo = AddinManager.Registry.GetAddin(id); } if (pinfo == null) { AddinManager.ReportError("Required add-in not found", id, null, false); return(null); } if (!pinfo.Enabled) { return(null); } // Loads extensions defined in each module ExtensionLoadData data = null; AddinDescription conf = pinfo.Description; GetAddinExtensions(conf.MainModule, id, ep, ref data); foreach (ModuleDescription module in conf.OptionalModules) { if (CheckOptionalAddinDependencies(conf, module)) { GetAddinExtensions(module, id, ep, ref data); } } if (data != null) { data.Extensions.Sort(); } return(data); }
public ExtensionNodeList GetExtensionNodes(string path, Type expectedNodeType) { TreeNode node = GetNode(path); if (node == null || node.ExtensionNode == null) { return(ExtensionNodeList.Empty); } ExtensionNodeList list = node.ExtensionNode.ChildNodes; if (expectedNodeType != null) { bool foundError = false; 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); } } if (foundError) { // Create a new list excluding the elements that failed the test ArrayList newList = new ArrayList(); foreach (ExtensionNode cnode in list) { if (expectedNodeType.IsInstanceOfType(cnode)) { newList.Add(cnode); } } return(new ExtensionNodeList(newList)); } } return(list); }
public override bool Evaluate(ExtensionContext ctx) { if (!base.Evaluate(ctx)) { return(false); } ConditionType type = ctx.GetCondition(typeId); if (type == null) { AddinManager.ReportError("Condition '" + typeId + "' not found in current extension context.", null, null, false); return(false); } try { return(type.Evaluate(node)); } catch (Exception ex) { AddinManager.ReportError("Error while evaluating condition '" + typeId + "'", null, ex, false); return(false); } }
// Load the extension nodes at the specified path. If the path // contains extension nodes implemented in an add-in which is // not loaded, the add-in will be automatically loaded internal void LoadExtensions(string requestedExtensionPath) { TreeNode node = GetNode(requestedExtensionPath); if (node == null) { throw new InvalidOperationException("Extension point not defined: " + requestedExtensionPath); } ExtensionPoint ep = node.ExtensionPoint; if (ep != null) { // Collect extensions to be loaded from add-ins. Before loading the extensions, // they must be sorted, that's why loading is split in two steps (collecting + loading). ArrayList loadData = new ArrayList(); foreach (string addin in ep.Addins) { ExtensionLoadData ed = GetAddinExtensions(addin, ep); if (ed != null) { // Insert the addin data taking into account dependencies. // An add-in must be processed after all its dependencies. bool added = false; for (int n = 0; n < loadData.Count; n++) { ExtensionLoadData other = (ExtensionLoadData)loadData [n]; if (AddinManager.Registry.AddinDependsOn(other.AddinId, ed.AddinId)) { loadData.Insert(n, ed); added = true; break; } } if (!added) { loadData.Add(ed); } } } // Now load the extensions ArrayList loadedNodes = new ArrayList(); foreach (ExtensionLoadData data in loadData) { foreach (Extension ext in data.Extensions) { TreeNode cnode = GetNode(ext.Path); 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); } } } // Call the OnAddinLoaded method on nodes, if the add-in is already loaded foreach (TreeNode nod in loadedNodes) { nod.ExtensionNode.OnAddinLoaded(); } NotifyExtensionsChanged(new ExtensionEventArgs(requestedExtensionPath)); } }
internal void ActivateAddinExtensions(string id) { // Looks for loaded extension points which are extended by the provided // add-in, and adds the new nodes try { fireEvents = true; Addin addin = AddinManager.Registry.GetAddin(id); if (addin == null) { AddinManager.ReportError("Required add-in not found", id, null, false); return; } // Look for loaded extension points Hashtable eps = new Hashtable(); foreach (ModuleDescription mod in addin.Description.AllModules) { foreach (Extension ext in mod.Extensions) { ExtensionPoint ep = tree.FindExtensionPoint(ext.Path); if (ep != null && !eps.Contains(ep)) { eps.Add(ep, ep); } } } // Add the new nodes ArrayList loadedNodes = new ArrayList(); foreach (ExtensionPoint ep in eps.Keys) { ExtensionLoadData data = GetAddinExtensions(id, ep); if (data != null) { foreach (Extension ext in data.Extensions) { TreeNode node = GetNode(ext.Path); if (node != null && node.ExtensionNodeSet != null) { LoadModuleExtensionNodes(ext, data.AddinId, node.ExtensionNodeSet, loadedNodes); } else { AddinManager.ReportError("Extension node not found or not extensible: " + ext.Path, id, null, false); } } // Global extension change event. Other events are fired by LoadModuleExtensionNodes. NotifyExtensionsChanged(new ExtensionEventArgs(ep.Path)); } } // Call the OnAddinLoaded method on nodes, if the add-in is already loaded foreach (TreeNode nod in loadedNodes) { nod.ExtensionNode.OnAddinLoaded(); } } finally { fireEvents = false; } // Do the same in child contexts lock (conditionTypes) { if (childContexts != null) { foreach (WeakReference wref in childContexts) { ExtensionContext ctx = wref.Target as ExtensionContext; if (ctx != null) { ctx.ActivateAddinExtensions(id); } } } } }
bool InitializeNodeType(ExtensionNodeType ntype) { RuntimeAddin p = AddinManager.SessionService.GetAddin(ntype.AddinId); if (p == null) { if (!AddinManager.SessionService.IsAddinLoaded(ntype.AddinId)) { if (!AddinManager.SessionService.LoadAddin(null, ntype.AddinId, false)) { return(false); } p = AddinManager.SessionService.GetAddin(ntype.AddinId); if (p == null) { AddinManager.ReportError("Add-in not found", ntype.AddinId, null, false); return(false); } } } // If no type name is provided, use TypeExtensionNode by default if (ntype.TypeName == null || ntype.TypeName.Length == 0) { ntype.Type = typeof(TypeExtensionNode); return(true); } ntype.Type = p.GetType(ntype.TypeName, false); if (ntype.Type == null) { AddinManager.ReportError("Extension node type '" + ntype.TypeName + "' not found.", ntype.AddinId, null, false); return(false); } Hashtable fields = new Hashtable(); ArrayList reqFields = new ArrayList(); // Check if the type has NodeAttribute attributes applied to fields. foreach (FieldInfo field in ntype.Type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { NodeAttributeAttribute at = (NodeAttributeAttribute)Attribute.GetCustomAttribute(field, typeof(NodeAttributeAttribute), true); if (at != null) { string name; if (at.Name != null && at.Name.Length > 0) { name = at.Name; } else { name = field.Name; } if (at.Required) { reqFields.Add(name); } fields [name] = field; } } if (fields.Count > 0) { ntype.Fields = fields; if (reqFields.Count > 0) { ntype.RequiredFields = (string[])reqFields.ToArray(typeof(string)); } } return(true); }
bool InitializeNodeType(ExtensionNodeType ntype) { RuntimeAddin p = AddinManager.SessionService.GetAddin(ntype.AddinId); if (p == null) { if (!AddinManager.SessionService.IsAddinLoaded(ntype.AddinId)) { if (!AddinManager.SessionService.LoadAddin(null, ntype.AddinId, false)) { return(false); } p = AddinManager.SessionService.GetAddin(ntype.AddinId); if (p == null) { AddinManager.ReportError("Add-in not found", ntype.AddinId, null, false); return(false); } } } // If no type name is provided, use TypeExtensionNode by default if (ntype.TypeName == null || ntype.TypeName.Length == 0) { ntype.Type = typeof(TypeExtensionNode); return(true); } ntype.Type = p.GetType(ntype.TypeName, false); if (ntype.Type == null) { AddinManager.ReportError("Extension node type '" + ntype.TypeName + "' not found.", ntype.AddinId, null, false); return(false); } Hashtable fields = new Hashtable(); // Check if the type has NodeAttribute attributes applied to fields. Type type = ntype.Type; while (type != typeof(object) && type != null) { foreach (FieldInfo field in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { NodeAttributeAttribute at = (NodeAttributeAttribute)Attribute.GetCustomAttribute(field, typeof(NodeAttributeAttribute), true); if (at != null) { ExtensionNodeType.FieldData fdata = new ExtensionNodeType.FieldData(); fdata.Field = field; fdata.Required = at.Required; fdata.Localizable = at.Localizable; string name; if (at.Name != null && at.Name.Length > 0) { name = at.Name; } else { name = field.Name; } fields [name] = fdata; } } type = type.BaseType; } if (fields.Count > 0) { ntype.Fields = fields; } return(true); }
internal bool LoadAddin(IProgressStatus statusMonitor, string id, bool throwExceptions) { try { if (IsAddinLoaded(id)) { return(true); } if (!AddinManager.Registry.IsAddinEnabled(id)) { string msg = GettextCatalog.GetString("Disabled extensions can't be loaded."); AddinManager.ReportError(msg, id, null, false); if (throwExceptions) { throw new InvalidOperationException(msg); } return(false); } ArrayList addins = new ArrayList(); Stack depCheck = new Stack(); ResolveLoadDependencies(addins, depCheck, id, false); addins.Reverse(); if (statusMonitor != null) { statusMonitor.SetMessage("Loading Addins"); } for (int n = 0; n < addins.Count; n++) { if (statusMonitor != null) { statusMonitor.SetProgress((double)n / (double)addins.Count); } Addin iad = (Addin)addins [n]; if (IsAddinLoaded(iad.Id)) { continue; } if (statusMonitor != null) { statusMonitor.SetMessage(string.Format(GettextCatalog.GetString("Loading {0} extension"), iad.Id)); } if (!InsertAddin(statusMonitor, iad)) { return(false); } } return(true); } catch (Exception ex) { AddinManager.ReportError("Extension could not be loaded: " + ex.Message, id, ex, false); if (statusMonitor != null) { statusMonitor.ReportError("Extension '" + id + "' could not be loaded.", ex); } if (throwExceptions) { throw; } return(false); } }
void LoadExtensionElement(TreeNode tnode, string addin, ExtensionNodeDescriptionCollection extension, ref int curPos, BaseCondition parentCondition, bool inComplextCondition, ArrayList addedNodes) { foreach (ExtensionNodeDescription elem in extension) { if (inComplextCondition) { parentCondition = ReadComplexCondition(elem, parentCondition); inComplextCondition = false; continue; } if (elem.NodeName == "ComplexCondition") { LoadExtensionElement(tnode, addin, elem.ChildNodes, ref curPos, parentCondition, true, addedNodes); continue; } if (elem.NodeName == "Condition") { Condition cond = new Condition(elem, parentCondition); LoadExtensionElement(tnode, addin, elem.ChildNodes, ref curPos, cond, false, addedNodes); continue; } string after = elem.GetAttribute("insertafter"); if (after.Length > 0) { int i = tnode.Children.IndexOfNode(after); if (i != -1) { curPos = i + 1; } } string before = elem.GetAttribute("insertbefore"); if (before.Length > 0) { int i = tnode.Children.IndexOfNode(before); if (i != -1) { curPos = i; } } // Find the type of the node in this extension ExtensionNodeType ntype = AddinManager.SessionService.FindType(tnode.ExtensionNodeSet, elem.NodeName, addin); if (ntype == null) { AddinManager.ReportError("Node '" + elem.NodeName + "' not allowed in extension: " + tnode.GetPath(), addin, null, false); continue; } string id = elem.GetAttribute("id"); if (id.Length == 0) { id = AutoIdPrefix + (++internalId); } TreeNode cnode = new TreeNode(id); ExtensionNode enode = ReadNode(cnode, addin, ntype, elem); if (enode == null) { continue; } cnode.Condition = parentCondition; cnode.ExtensionNodeSet = ntype; tnode.InsertChildNode(curPos, cnode); addedNodes.Add(cnode); if (cnode.Condition != null) { Context.RegisterNodeCondition(cnode, cnode.Condition); } // Load children if (elem.ChildNodes.Count > 0) { int cp = 0; LoadExtensionElement(cnode, addin, elem.ChildNodes, ref cp, parentCondition, false, addedNodes); } curPos++; } if (Context.FireEvents) { tnode.NotifyChildrenChanged(); } }
internal void ActivateAddinExtensions(string id) { // Looks for loaded extension points which are extended by the provided // add-in, and adds the new nodes try { fireEvents = true; Addin addin = AddinManager.Registry.GetAddin(id); if (addin == null) { AddinManager.ReportError("Required add-in not found", id, null, false); return; } // Take note that this add-in has been enabled at run-time // Needed because loaded add-in descriptions may not include this add-in. RegisterRuntimeEnabledAddin(id); // Look for loaded extension points Hashtable eps = new Hashtable(); ArrayList newExtensions = new ArrayList(); foreach (ModuleDescription mod in addin.Description.AllModules) { foreach (Extension ext in mod.Extensions) { if (!newExtensions.Contains(ext.Path)) { newExtensions.Add(ext.Path); } ExtensionPoint ep = tree.FindLoadedExtensionPoint(ext.Path); if (ep != null && !eps.Contains(ep)) { eps.Add(ep, ep); } } } // Add the new nodes ArrayList loadedNodes = new ArrayList(); foreach (ExtensionPoint ep in eps.Keys) { ExtensionLoadData data = GetAddinExtensions(id, ep); if (data != null) { foreach (Extension ext in data.Extensions) { TreeNode node = GetNode(ext.Path); if (node != null && node.ExtensionNodeSet != null) { if (node.ChildrenLoaded) { LoadModuleExtensionNodes(ext, data.AddinId, node.ExtensionNodeSet, loadedNodes); } } else { AddinManager.ReportError("Extension node not found or not extensible: " + ext.Path, id, null, false); } } } } // Call the OnAddinLoaded method on nodes, if the add-in is already loaded foreach (TreeNode nod in loadedNodes) { nod.ExtensionNode.OnAddinLoaded(); } // Global extension change event. Other events are fired by LoadModuleExtensionNodes. // 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). foreach (string newExt in newExtensions) { NotifyExtensionsChanged(new ExtensionEventArgs(newExt)); } } finally { fireEvents = false; } // Do the same in child contexts lock (conditionTypes) { if (childContexts != null) { foreach (WeakReference wref in childContexts) { ExtensionContext ctx = wref.Target as ExtensionContext; if (ctx != null) { ctx.ActivateAddinExtensions(id); } } } } }