void PopulateNodeTypes(Gtk.Menu menu, TreeIter it) { ExtensionNodeTypeCollection types = GetAllowedChildTypes(it); Extension ext = (Extension)store.GetValue(it, ColExtension); ExtensionNodeDescription node = (ExtensionNodeDescription)store.GetValue(it, ColNode); if (types != null && types.Count > 0) { if (menu.Children.Length > 0) { menu.Insert(new Gtk.SeparatorMenuItem(), -1); } foreach (ExtensionNodeType nt in types) { Gtk.ImageMenuItem mi = new Gtk.ImageMenuItem(AddinManager.CurrentLocalizer.GetString("Add node '{0}'", nt.NodeName)); menu.Insert(mi, -1); ExtensionNodeType ntc = nt; mi.Activated += delegate { CreateNode(it, ext, node, ntc); }; } } }
public NodeEditorWidget(DotNetProject project, AddinRegistry reg, ExtensionNodeType ntype, AddinDescription parentAddinDescription, string parentPath, ExtensionNodeDescription node) { this.node = node; this.project = project; tips = new Tooltips(); Spacing = 0; // Header Label label = new Label(); label.Wrap = true; label.WidthRequest = 480; string txt = "<b>" + node.NodeName + "</b>"; if (ntype.Description.Length > 0) { txt += "\n" + GLib.Markup.EscapeText(ntype.Description); } label.Markup = txt; label.Xalign = 0f; PackStart(label, false, false, 6); PackStart(new HSeparator(), false, false, 0); // Attributes grid = new PropertyGrid(); grid.CurrentObject = new NodeWrapper(project, reg, ntype, parentAddinDescription, parentPath, node); PackStart(grid, true, true, 0); ShowAll(); grid.ShowHelp = true; grid.ShowToolbar = false; }
public void AddNodeBefore(object data) { DotNetProject p = (DotNetProject)CurrentNode.GetParentDataItem(typeof(Project), false); AddinData adata = p.GetAddinData(); Extension en = GetExtension(); ExtensionNodeType ntype = (ExtensionNodeType)data; ExtensionNodeDescription newNode = new ExtensionNodeDescription(ntype.NodeName); en.ExtensionNodes.Add(newNode); CurrentNode.Expanded = true; adata.SaveAddinManifest(); adata.NotifyChanged(false); DispatchService.GuiDispatch(delegate { ITreeNavigator nav = Tree.GetNodeAtObject(new ExtensionNodeInfo(newNode, false)); if (nav != null) { nav.Selected = true; } }); }
void PrintExtensionPoint(AddinDescription desc, ExtensionPoint ep) { Console.WriteLine(); Console.WriteLine("* Extension Point: " + ep.Path); if (ep.Description.Length > 0) { Console.WriteLine(ep.Description); } ArrayList list = new ArrayList(); Hashtable visited = new Hashtable(); Console.WriteLine(); Console.WriteLine(" Extension nodes:"); GetNodes(desc, ep.NodeSet, list, new Hashtable()); foreach (ExtensionNodeType nt in list) { Console.WriteLine(" - " + nt.Id + ": " + nt.Description); } Console.WriteLine(); Console.WriteLine(" Node description:"); string sind = " "; for (int n = 0; n < list.Count; n++) { ExtensionNodeType nt = (ExtensionNodeType)list [n]; if (visited.Contains(nt.Id + " " + nt.TypeName)) { continue; } visited.Add(nt.Id + " " + nt.TypeName, nt); Console.WriteLine(); Console.WriteLine(sind + "- " + nt.Id + ": " + nt.Description); string nsind = sind + " "; if (nt.Attributes.Count > 0) { Console.WriteLine(nsind + "Attributes:"); foreach (NodeTypeAttribute att in nt.Attributes) { string req = att.Required ? " (required)" : ""; Console.WriteLine(nsind + " " + att.Name + " (" + att.Type + "): " + att.Description + req); } } if (nt.NodeTypes.Count > 0 || nt.NodeSets.Count > 0) { Console.WriteLine(nsind + "Child nodes:"); ArrayList newList = new ArrayList(); GetNodes(desc, nt, newList, new Hashtable()); list.AddRange(newList); foreach (ExtensionNodeType cnt in newList) { Console.WriteLine(" " + cnt.Id + ": " + cnt.Description); } } } Console.WriteLine(); }
void ScanNodeType(AddinDescription config, ExtensionNodeType nt, ArrayList assemblies, Hashtable internalNodeSets) { if (nt.TypeName.Length == 0) { nt.TypeName = "Mono.Addins.TypeExtensionNode"; } Type ntype = FindAddinType(nt.TypeName, assemblies); if (ntype == null) { return; } // Add type information declared with attributes in the code ExtensionNodeAttribute nodeAtt = (ExtensionNodeAttribute)Attribute.GetCustomAttribute(ntype, typeof(ExtensionNodeAttribute), true); if (nodeAtt != null) { if (nt.Id.Length == 0 && nodeAtt.NodeName.Length > 0) { nt.Id = nodeAtt.NodeName; } if (nt.Description.Length == 0 && nodeAtt.Description.Length > 0) { nt.Description = nodeAtt.Description; } } else { // Use the node type name as default name if (nt.Id.Length == 0) { nt.Id = ntype.Name; } } // Add information about attributes object[] fieldAtts = ntype.GetCustomAttributes(typeof(NodeAttributeAttribute), true); foreach (NodeAttributeAttribute fatt in fieldAtts) { NodeTypeAttribute natt = new NodeTypeAttribute(); natt.Name = fatt.Name; natt.Required = fatt.Required; if (fatt.Type != null) { natt.Type = fatt.Type.FullName; } if (fatt.Description.Length > 0) { natt.Description = fatt.Description; } nt.Attributes.Add(natt); } // Check if the type has NodeAttribute attributes applied to fields. foreach (FieldInfo field in ntype.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { NodeAttributeAttribute fatt = (NodeAttributeAttribute)Attribute.GetCustomAttribute(field, typeof(NodeAttributeAttribute)); if (fatt != null) { NodeTypeAttribute natt = new NodeTypeAttribute(); if (fatt.Name.Length > 0) { natt.Name = fatt.Name; } else { natt.Name = field.Name; } if (fatt.Description.Length > 0) { natt.Description = fatt.Description; } natt.Type = field.FieldType.FullName; natt.Required = fatt.Required; nt.Attributes.Add(natt); } } // Check if the extension type allows children by looking for [ExtensionNodeChild] attributes. // First of all, look in the internalNodeSets hashtable, which is being used as cache string childSet = (string)internalNodeSets [nt.TypeName]; if (childSet == null) { object[] ats = ntype.GetCustomAttributes(typeof(ExtensionNodeChildAttribute), true); if (ats.Length > 0) { // Create a new node set for this type. It is necessary to create a new node set // instead of just adding child ExtensionNodeType objects to the this node type // because child types references can be recursive. ExtensionNodeSet internalSet = new ExtensionNodeSet(); internalSet.Id = ntype.Name + "_" + Guid.NewGuid().ToString(); foreach (ExtensionNodeChildAttribute at in ats) { ExtensionNodeType internalType = new ExtensionNodeType(); internalType.Id = at.NodeName; internalType.TypeName = at.ExtensionNodeType.FullName; internalSet.NodeTypes.Add(internalType); } config.ExtensionNodeSets.Add(internalSet); nt.NodeSets.Add(internalSet.Id); // Register the new set in a hashtable, to allow recursive references to the // same internal set. internalNodeSets [nt.TypeName] = internalSet.Id; internalNodeSets [ntype.AssemblyQualifiedName] = internalSet.Id; ScanNodeSet(config, internalSet, assemblies, internalNodeSets); } } else { if (childSet.Length == 0) { // The extension type does not declare children. return; } // The extension type can have children. The allowed children are // defined in this extension set. nt.NodeSets.Add(childSet); return; } ScanNodeSet(config, nt, assemblies, internalNodeSets); }
void ScanAssemblyContents(AddinDescription config, Assembly asm, ArrayList hostExtensionClasses, AddinScanResult scanResult) { // Get dependencies object[] deps = asm.GetCustomAttributes(typeof(AddinDependencyAttribute), false); foreach (AddinDependencyAttribute dep in deps) { AddinDependency adep = new AddinDependency(); adep.AddinId = dep.Id; adep.Version = dep.Version; config.MainModule.Dependencies.Add(adep); } // Get extension points object[] extPoints = asm.GetCustomAttributes(typeof(ExtensionPointAttribute), false); foreach (ExtensionPointAttribute ext in extPoints) { ExtensionPoint ep = config.AddExtensionPoint(ext.Path); ep.Description = ext.Description; ep.Name = ext.Name; ep.AddExtensionNode(ext.NodeName, ext.NodeType.FullName); } foreach (Type t in asm.GetTypes()) { if (Attribute.IsDefined(t, typeof(ExtensionAttribute))) { foreach (ExtensionAttribute eatt in t.GetCustomAttributes(typeof(ExtensionAttribute), false)) { string path; string nodeName; if (eatt.Path.Length == 0) { if (config.IsRoot) { // The extension point must be one of the defined by the assembly // Look for it later, when the assembly has been fully scanned. hostExtensionClasses.Add(t); continue; } else { path = GetBaseTypeNameList(t); if (path == "$") { // The type does not implement any interface and has no superclass. // Will be reported later as an error. path = "$" + t.FullName; } nodeName = "Type"; } } else { path = eatt.Path; nodeName = eatt.NodeName; } ExtensionNodeDescription elem = config.MainModule.AddExtensionNode(path, nodeName); if (eatt.Id.Length > 0) { elem.SetAttribute("id", eatt.Id); elem.SetAttribute("type", t.FullName); } else { elem.SetAttribute("id", t.FullName); } if (eatt.InsertAfter.Length > 0) { elem.SetAttribute("insertafter", eatt.InsertAfter); } if (eatt.InsertBefore.Length > 0) { elem.SetAttribute("insertbefore", eatt.InsertAfter); } } } else if (Attribute.IsDefined(t, typeof(TypeExtensionPointAttribute))) { foreach (TypeExtensionPointAttribute epa in t.GetCustomAttributes(typeof(TypeExtensionPointAttribute), false)) { ExtensionPoint ep; ExtensionNodeType nt = new ExtensionNodeType(); if (epa.Path.Length > 0) { ep = config.AddExtensionPoint(epa.Path); } else { ep = config.AddExtensionPoint(GetDefaultTypeExtensionPath(config, t)); nt.ObjectTypeName = t.FullName; } nt.Id = epa.NodeName; nt.TypeName = epa.NodeType.FullName; ep.NodeSet.NodeTypes.Add(nt); ep.Description = epa.Description; ep.Name = epa.Name; ep.RootAddin = config.AddinId; ep.SetExtensionsAddinId(config.AddinId); } } } }
internal void SetData(string plugid, ExtensionNodeType nodeType) { this.addinId = plugid; this.nodeType = nodeType; }
public ExtensionNodeElement(AddinProject proj, ExtensionPoint extensionPoint, ExtensionNodeType info) : base(info.NodeName, info.Description) { this.proj = proj; this.extensionPoint = extensionPoint; this.info = info; }
void LoadExtensionElement(TreeNode tnode, string addin, ExtensionNodeDescriptionCollection extension, ModuleDescription module, ref int curPos, BaseCondition parentCondition, bool inComplextCondition, List <TreeNode> addedNodes) { foreach (ExtensionNodeDescription elem in extension) { if (inComplextCondition) { parentCondition = ReadComplexCondition(elem, parentCondition); inComplextCondition = false; continue; } if (elem.NodeName == "ComplexCondition") { LoadExtensionElement(tnode, addin, elem.ChildNodes, module, ref curPos, parentCondition, true, addedNodes); continue; } if (elem.NodeName == "Condition") { Condition cond = new Condition(AddinEngine, elem, parentCondition); LoadExtensionElement(tnode, addin, elem.ChildNodes, module, ref curPos, cond, false, addedNodes); continue; } var pnode = tnode; ExtensionPoint extensionPoint = null; while (pnode != null && (extensionPoint = pnode.ExtensionPoint) == null) { pnode = pnode.Parent; } string after = elem.GetAttribute("insertafter"); if (after.Length == 0 && extensionPoint != null && curPos == -1) { after = extensionPoint.DefaultInsertAfter; } 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 && extensionPoint != null && curPos == -1) { before = extensionPoint.DefaultInsertBefore; } if (before.Length > 0) { int i = tnode.Children.IndexOfNode(before); if (i != -1) { curPos = i; } } // If node position is not explicitly set, add the node at the end if (curPos == -1) { curPos = tnode.Children.Count; } // Find the type of the node in this extension ExtensionNodeType ntype = addinEngine.FindType(tnode.ExtensionNodeSet, elem.NodeName, addin); if (ntype == null) { addinEngine.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(addinEngine, id); ExtensionNode enode = ReadNode(cnode, addin, ntype, elem, module); 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, module, ref cp, parentCondition, false, addedNodes); } curPos++; } if (Context.FireEvents) { tnode.NotifyChildrenChanged(); } }
bool InitializeNodeType(ExtensionNodeType ntype) { RuntimeAddin p = addinEngine.GetAddin(ntype.AddinId); if (p == null) { if (!addinEngine.IsAddinLoaded(ntype.AddinId)) { if (!addinEngine.LoadAddin(null, ntype.AddinId, false)) { return(false); } p = addinEngine.GetAddin(ntype.AddinId); if (p == null) { addinEngine.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.TypeName == typeof(TypeExtensionNode).FullName) { // If it has a custom attribute, use the generic version of TypeExtensionNode if (ntype.ExtensionAttributeTypeName.Length > 0) { Type attType = p.GetType(ntype.ExtensionAttributeTypeName, false); if (attType == null) { addinEngine.ReportError("Custom attribute type '" + ntype.ExtensionAttributeTypeName + "' not found.", ntype.AddinId, null, false); return(false); } if (ntype.ObjectTypeName.Length > 0 || ntype.TypeName == typeof(TypeExtensionNode).FullName) { ntype.Type = typeof(TypeExtensionNode <>).MakeGenericType(attType); } else { ntype.Type = typeof(ExtensionNode <>).MakeGenericType(attType); } } else { ntype.Type = typeof(TypeExtensionNode); return(true); } } else { ntype.Type = p.GetType(ntype.TypeName, false); if (ntype.Type == null) { addinEngine.ReportError("Extension node type '" + ntype.TypeName + "' not found.", ntype.AddinId, null, false); return(false); } } // Check if the type has NodeAttribute attributes applied to fields. ExtensionNodeType.FieldData boundAttributeType = null; Dictionary <string, ExtensionNodeType.FieldData> fields = GetMembersMap(ntype.Type, out boundAttributeType); ntype.CustomAttributeMember = boundAttributeType; if (fields.Count > 0) { ntype.Fields = fields; } // If the node type is bound to a custom attribute and there is a member bound to that attribute, // get the member map for the attribute. if (boundAttributeType != null) { if (ntype.ExtensionAttributeTypeName.Length == 0) { throw new InvalidOperationException("Extension node not bound to a custom attribute."); } if (ntype.ExtensionAttributeTypeName != boundAttributeType.MemberType.FullName) { throw new InvalidOperationException("Incorrect custom attribute type declaration in " + ntype.Type + ". Expected '" + ntype.ExtensionAttributeTypeName + "' found '" + boundAttributeType.MemberType.FullName + "'"); } fields = GetMembersMap(boundAttributeType.MemberType, out boundAttributeType); if (fields.Count > 0) { ntype.CustomAttributeFields = fields; } } return(true); }
void PrintAddinXml(XmlWriter tw, AddinDescription desc) { tw.WriteStartElement("Addin"); tw.WriteAttributeString("name", desc.Name); tw.WriteAttributeString("addinId", desc.LocalId); tw.WriteAttributeString("fullId", desc.AddinId); tw.WriteAttributeString("id", "addin_" + uniqueId); uniqueId++; if (desc.Namespace.Length > 0) { tw.WriteAttributeString("namespace", desc.Namespace); } tw.WriteAttributeString("isroot", desc.IsRoot.ToString()); tw.WriteAttributeString("version", desc.Version); if (desc.CompatVersion.Length > 0) { tw.WriteAttributeString("compatVersion", desc.CompatVersion); } if (desc.Author.Length > 0) { tw.WriteAttributeString("author", desc.Author); } if (desc.Category.Length > 0) { tw.WriteAttributeString("category", desc.Category); } if (desc.Copyright.Length > 0) { tw.WriteAttributeString("copyright", desc.Copyright); } if (desc.Url.Length > 0) { tw.WriteAttributeString("url", desc.Url); } if (desc.Description.Length > 0) { tw.WriteElementString("Description", desc.Description); } if (desc.ExtensionPoints.Count > 0) { ArrayList list = new ArrayList(); Hashtable visited = new Hashtable(); foreach (ExtensionPoint ep in desc.ExtensionPoints) { tw.WriteStartElement("ExtensionPoint"); tw.WriteAttributeString("path", ep.Path); if (ep.Name.Length > 0) { tw.WriteAttributeString("name", ep.Name); } else { tw.WriteAttributeString("name", ep.Path); } if (ep.Description.Length > 0) { tw.WriteElementString("Description", ep.Description); } PrintExtensionNodeSetXml(tw, desc, ep.NodeSet, list, visited); tw.WriteEndElement(); } for (int n = 0; n < list.Count; n++) { ExtensionNodeType nt = (ExtensionNodeType)list [n]; tw.WriteStartElement("ExtensionNodeType"); tw.WriteAttributeString("name", nt.Id); tw.WriteAttributeString("id", visited [nt.Id + " " + nt.TypeName].ToString()); if (nt.Description.Length > 0) { tw.WriteElementString("Description", nt.Description); } if (nt.Attributes.Count > 0) { tw.WriteStartElement("Attributes"); foreach (NodeTypeAttribute att in nt.Attributes) { tw.WriteStartElement("Attribute"); tw.WriteAttributeString("name", att.Name); tw.WriteAttributeString("type", att.Type); tw.WriteAttributeString("required", att.Required.ToString()); tw.WriteAttributeString("localizable", att.Localizable.ToString()); if (att.Description.Length > 0) { tw.WriteElementString("Description", att.Description); } tw.WriteEndElement(); } tw.WriteEndElement(); } if (nt.NodeTypes.Count > 0 || nt.NodeSets.Count > 0) { tw.WriteStartElement("ChildNodes"); PrintExtensionNodeSetXml(tw, desc, nt, list, visited); tw.WriteEndElement(); } tw.WriteEndElement(); } } tw.WriteEndElement(); }
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(); } }
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); }
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); }