public void Save() { string xmlns = "http://www.buildingsmart-tech.org/ifcXML/IFC4/final"; if (this.m_views != null && this.m_views.Length == 1 && !String.IsNullOrEmpty(this.m_views[0].Code)) { DocModelView docView = this.m_views[0]; if (!String.IsNullOrEmpty(docView.XsdUri)) { xmlns = docView.XsdUri; } else if (!String.IsNullOrEmpty(docView.Code)) { xmlns = "http://www.buildingsmart-tech.org/ifcXML/MVD4/" + docView.Code; } } // build map of types Dictionary <string, DocObject> map = new Dictionary <string, DocObject>(); foreach (DocSection docSection in this.m_project.Sections) { foreach (DocSchema docSchema in docSection.Schemas) { foreach (DocEntity docEnt in docSchema.Entities) { if (!map.ContainsKey(docEnt.Name)) { map.Add(docEnt.Name, docEnt); } } foreach (DocType docType in docSchema.Types) { if (!map.ContainsKey(docType.Name)) { map.Add(docType.Name, docType); } } } } SortedList <string, DocDefined> mapDefined = new SortedList <string, DocDefined>(this); SortedList <string, DocEnumeration> mapEnum = new SortedList <string, DocEnumeration>(this); SortedList <string, DocSelect> mapSelect = new SortedList <string, DocSelect>(this); SortedList <string, DocEntity> mapEntity = new SortedList <string, DocEntity>(this); SortedList <string, DocFunction> mapFunction = new SortedList <string, DocFunction>(this); SortedList <string, DocGlobalRule> mapRule = new SortedList <string, DocGlobalRule>(this); SortedList <string, string> sort = new SortedList <string, string>(new FormatXSD(null)); foreach (DocSection docSection in this.m_project.Sections) { foreach (DocSchema docSchema in docSection.Schemas) { if (this.m_included == null || this.m_included.ContainsKey(docSchema)) { foreach (DocType docType in docSchema.Types) { if (this.m_included == null || this.m_included.ContainsKey(docType)) { if (docType is DocDefined) { if (!mapDefined.ContainsKey(docType.Name)) { mapDefined.Add(docType.Name, (DocDefined)docType); } } else if (docType is DocEnumeration) { mapEnum.Add(docType.Name, (DocEnumeration)docType); } else if (docType is DocSelect) { mapSelect.Add(docType.Name, (DocSelect)docType); } } } foreach (DocEntity docEnt in docSchema.Entities) { if (this.m_included == null || this.m_included.ContainsKey(docEnt)) { if (!mapEntity.ContainsKey(docEnt.Name)) { mapEntity.Add(docEnt.Name, docEnt); } // check for any attributes that are lists of value types requiring wrapper, e.g. IfcTextFontName foreach (DocAttribute docAttr in docEnt.Attributes) { DocObject docObjRef = null; if (docAttr.DefinedType != null && docAttr.GetAggregation() != DocAggregationEnum.NONE && map.TryGetValue(docAttr.DefinedType, out docObjRef) && docObjRef is DocDefined && docAttr.XsdFormat == DocXsdFormatEnum.Element && !(docAttr.XsdTagless == true) && !sort.ContainsKey(docAttr.DefinedType)) { sort.Add(docAttr.DefinedType, docAttr.DefinedType); } } } } foreach (DocFunction docFunc in docSchema.Functions) { if ((this.m_included == null || this.m_included.ContainsKey(docFunc)) && !mapFunction.ContainsKey(docFunc.Name)) { mapFunction.Add(docFunc.Name, docFunc); } } foreach (DocGlobalRule docRule in docSchema.GlobalRules) { if (this.m_included == null || this.m_included.ContainsKey(docRule)) { mapRule.Add(docRule.Name, docRule); } } } } } using (System.IO.StreamWriter writer = new System.IO.StreamWriter(this.m_filename)) { writer.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); writer.WriteLine("<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" " + "xmlns:ifc=\"" + xmlns + "\" " + "targetNamespace=\"" + xmlns + "\" " + "elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" >"); WriteResource(writer, "IfcDoc.xsd1.txt"); // Entities writer.WriteLine("\t<!-- element and complex type declarations (for ENTITY definitions) -->"); foreach (DocEntity docEntity in mapEntity.Values) { writer.Write(FormatEntity(docEntity, map, this.m_included)); } // Selects writer.WriteLine("\t<!-- group declarations (for SELECT data type definitions) -->"); foreach (DocSelect docSelect in mapSelect.Values) { writer.Write(FormatSelect(docSelect, map, this.m_included)); } // Enumerations writer.WriteLine("\t<!-- enumeration type declarations (for ENUMERATION data type definitions) -->"); foreach (DocEnumeration docEnum in mapEnum.Values) { writer.Write(FormatEnum(docEnum)); } // Defined Types writer.WriteLine("\t<!-- simple type declarations (for TYPE defined data type definitions) -->"); foreach (DocDefined docDefined in mapDefined.Values) { writer.Write(FormatDefinedSimple(docDefined)); } WriteResource(writer, "IfcDoc.xsd2.txt"); // sort selects alphabetically Queue <DocSelectItem> queue = new Queue <DocSelectItem>(); foreach (DocSelect docSelect in mapSelect.Values) { foreach (DocSelectItem docSelItem in docSelect.Selects) { queue.Enqueue(docSelItem); } } List <DocDefined> listWrapper = new List <DocDefined>(); // keep track of wrapped types while (queue.Count > 0) { DocSelectItem docItem = queue.Dequeue(); DocObject mapDef = null; if (map.TryGetValue(docItem.Name, out mapDef)) { if (mapDef is DocSelect) { // expand each DocSelect docSub = (DocSelect)mapDef; foreach (DocSelectItem dsi in docSub.Selects) { queue.Enqueue(dsi); } } else if (!sort.ContainsKey(docItem.Name)) { if (this.m_included == null || this.m_included.ContainsKey(mapDef)) { sort.Add(docItem.Name, docItem.Name); } } } } writer.WriteLine("\t<!-- base global wrapper declaration for atomic simple types (for embeded base schema definitions) -->"); foreach (string docItem in sort.Values) { DocObject mapDef = null; if (map.TryGetValue(docItem, out mapDef) && mapDef is DocType) { if (this.m_included == null || this.m_included.ContainsKey(mapDef)) { writer.Write(FormatTypeWrapper((DocType)mapDef, map)); } } } writer.WriteLine("</xs:schema>"); } }
public static string FormatSelect(DocSelect docSelect, Dictionary <string, DocObject> map, Dictionary <DocObject, bool> included) { StringBuilder sb = new StringBuilder(); sb.Append("\t<xs:group name=\""); sb.Append(docSelect.Name); sb.Append("\">"); sb.AppendLine(); sb.Append("\t\t<xs:choice>"); sb.AppendLine(); Queue <DocSelectItem> queue = new Queue <DocSelectItem>(); foreach (DocSelectItem docItem in docSelect.Selects) { queue.Enqueue(docItem); } // sort selects alphabetically SortedList <string, DocSelectItem> sort = new SortedList <string, DocSelectItem>(new FormatXSD(null)); while (queue.Count > 0) { DocSelectItem docItem = queue.Dequeue(); DocObject mapDef = null; if (map.TryGetValue(docItem.Name, out mapDef)) { if (mapDef is DocSelect) { // expand each DocSelect docSub = (DocSelect)mapDef; foreach (DocSelectItem dsi in docSub.Selects) { queue.Enqueue(dsi); } } else if ((included == null || included.ContainsKey(mapDef)) && !sort.ContainsKey(docItem.Name)) { //TODO: if abstract entity, then go through subtypes... sort.Add(docItem.Name, docItem); } } } // resolve selects into final elements // first entities, then wrappers // entities foreach (DocSelectItem docItem in sort.Values) { DocObject mapDef = null; if (map.TryGetValue(docItem.Name, out mapDef)) { if (included == null || included.ContainsKey(mapDef)) { sb.Append("\t\t\t<xs:element ref=\"ifc:"); sb.Append(docItem.Name); if (mapDef is DocDefined || mapDef is DocEnumeration) { sb.Append("-wrapper"); } sb.Append("\"/>"); sb.AppendLine(); } } } sb.Append("\t\t</xs:choice>"); sb.AppendLine(); sb.Append("\t</xs:group>"); sb.AppendLine(); return(sb.ToString()); }
public void Save() { SortedList <string, DocDefined> mapDefined = new SortedList <string, DocDefined>(this); SortedList <string, DocEnumeration> mapEnum = new SortedList <string, DocEnumeration>(this); SortedList <string, DocSelect> mapSelect = new SortedList <string, DocSelect>(this); SortedList <string, DocEntity> mapEntity = new SortedList <string, DocEntity>(this); SortedList <string, DocFunction> mapFunction = new SortedList <string, DocFunction>(this); SortedList <string, DocGlobalRule> mapRule = new SortedList <string, DocGlobalRule>(this); SortedList <string, DocObject> mapGeneral = new SortedList <string, DocObject>(); foreach (DocSection docSection in this.m_project.Sections) { foreach (DocSchema docSchema in docSection.Schemas) { if (this.m_included == null || this.m_included.ContainsKey(docSchema)) { foreach (DocType docType in docSchema.Types) { if (this.m_included == null || this.m_included.ContainsKey(docType)) { if (docType is DocDefined) { if (!mapDefined.ContainsKey(docType.Name)) { mapDefined.Add(docType.Name, (DocDefined)docType); } } else if (docType is DocEnumeration) { mapEnum.Add(docType.Name, (DocEnumeration)docType); } else if (docType is DocSelect) { mapSelect.Add(docType.Name, (DocSelect)docType); } if (!mapGeneral.ContainsKey(docType.Name)) { mapGeneral.Add(docType.Name, docType); } } } foreach (DocEntity docEnt in docSchema.Entities) { if (this.m_included == null || this.m_included.ContainsKey(docEnt)) { if (!mapEntity.ContainsKey(docEnt.Name)) { mapEntity.Add(docEnt.Name, docEnt); } if (!mapGeneral.ContainsKey(docEnt.Name)) { mapGeneral.Add(docEnt.Name, docEnt); } } } foreach (DocFunction docFunc in docSchema.Functions) { if ((this.m_included == null || this.m_included.ContainsKey(docFunc)) && !mapFunction.ContainsKey(docFunc.Name)) { mapFunction.Add(docFunc.Name, docFunc); } } foreach (DocGlobalRule docRule in docSchema.GlobalRules) { if (this.m_included == null || this.m_included.ContainsKey(docRule)) { mapRule.Add(docRule.Name, docRule); } } } } } string dirpath = System.IO.Path.GetDirectoryName(this.m_filename); if (!System.IO.Directory.Exists(dirpath)) { System.IO.Directory.CreateDirectory(dirpath); } using (System.IO.StreamWriter writer = new System.IO.StreamWriter(this.m_filename)) { if (writer.BaseStream.CanSeek) { writer.BaseStream.SetLength(0); } string schemaid = this.m_project.GetSchemaIdentifier(); string org = "buildingSMART International Limited"; writer.Write("" + "(*\r\n" + "Copyright by:\r\n" + org + ", 1996-" + DateTime.UtcNow.Year + "\r\n" + "\r\n" + "Any technical documentation made available by " + org + "\r\n" + "is the copyrighted work of " + org + " and is owned by the \r\n" + org + ". It may be photocopied, used in software development, \r\n" + "or translated into another computer language without prior written consent from \r\n" + org + " provided that full attribution is given. \r\n" + "Prior written consent is required if changes are made to the technical specification.\r\n" + "\r\n" + "This material is delivered to you as is and " + org + " makes \r\n" + "no warranty of any kind with regard to it, including, but not limited to, the implied \r\n" + "warranties as to its accuracy or fitness for a particular purpose. Any use of the \r\n" + "technical documentation or the information contained therein is at the risk of the user. \r\n" + "Documentation may include technical or other inaccuracies or typographical errors. \r\n" + org + " shall not be liable for errors contained therein or \r\n" + "for incidental consequential damages in connection with the furnishing, performance or use \r\n" + "of the material. The information contained in this document is subject to change without notice.\r\n" + "\r\n" + "Issue date:\r\n" + DateTime.Today.ToLongDateString() + "\r\n" + //"December 27, 2012\r\n" + "\r\n" + "*)\r\n" + "\r\n"); writer.WriteLine("SCHEMA " + schemaid.ToUpper() + ";"); writer.WriteLine(); // stripped optional applicable if MVD is used if (this.m_included != null) { writer.WriteLine("TYPE IfcStrippedOptional = BOOLEAN;"); writer.WriteLine("END_TYPE;"); writer.WriteLine(); } // defined types foreach (DocDefined docDef in mapDefined.Values) { writer.Write("TYPE "); writer.Write(docDef.Name); writer.Write(" = "); if (docDef.Aggregation != null) { WriteExpressAggregation(writer, docDef.Aggregation); } writer.Write(docDef.DefinedType); string length = ""; if (docDef.Length > 0) { length = "(" + docDef.Length.ToString() + ")"; } else if (docDef.Length < 0) { int len = -docDef.Length; length = "(" + len.ToString() + ") FIXED"; } writer.Write(length); writer.WriteLine(";"); if (docDef.WhereRules.Count > 0) { writer.WriteLine(" WHERE"); foreach (DocWhereRule where in docDef.WhereRules) { writer.Write("\t"); writer.Write(where.Name); writer.Write(" : "); writer.Write(MakeLongFormExpression(where.Expression, schemaid)); writer.WriteLine(";"); } } writer.WriteLine("END_TYPE;"); writer.WriteLine(); } // enumerations foreach (DocEnumeration docEnum in mapEnum.Values) { writer.Write("TYPE "); writer.Write(docEnum.Name); writer.Write(" = ENUMERATION OF"); writer.WriteLine(); for (int i = 0; i < docEnum.Constants.Count; i++) { DocConstant docConst = docEnum.Constants[i]; if (i == 0) { writer.Write("\t("); } else { writer.Write("\t,"); } writer.Write(docConst.Name); if (i == docEnum.Constants.Count - 1) { writer.WriteLine(");"); } else { writer.WriteLine(); } } writer.WriteLine("END_TYPE;"); writer.WriteLine(); } // selects foreach (DocSelect docSelect in mapSelect.Values) { writer.Write("TYPE "); writer.Write(docSelect.Name); writer.Write(" = SELECT"); writer.WriteLine(); SortedList <string, DocSelectItem> sortSelect = new SortedList <string, DocSelectItem>(this); foreach (DocSelectItem docSelectItem in docSelect.Selects) { if (!sortSelect.ContainsKey(docSelectItem.Name)) { sortSelect.Add(docSelectItem.Name, docSelectItem); } else { this.ToString(); } } int nSelect = 0; for (int i = 0; i < sortSelect.Keys.Count; i++) { DocSelectItem docConst = sortSelect.Values[i]; DocObject docRefEnt = null; if (mapGeneral.TryGetValue(docConst.Name, out docRefEnt)) { if (this.m_included == null || this.m_included.ContainsKey(docRefEnt)) { if (nSelect == 0) { writer.Write("\t("); } else { writer.WriteLine(); writer.Write("\t,"); } nSelect++; writer.Write(docConst.Name); } } } writer.WriteLine(");"); writer.WriteLine("END_TYPE;"); writer.WriteLine(); } // entities foreach (DocEntity docEntity in mapEntity.Values) { writer.Write("ENTITY "); writer.Write(docEntity.Name); if ((docEntity.IsAbstract())) { writer.WriteLine(); writer.Write(" ABSTRACT"); } // build up list of subtypes from other schemas SortedList <string, DocEntity> subtypes = new SortedList <string, DocEntity>(this); // sort to match Visual Express foreach (DocEntity eachent in mapEntity.Values) { if (eachent.BaseDefinition != null && eachent.BaseDefinition.Equals(docEntity.Name)) { subtypes.Add(eachent.Name, eachent); } } if (subtypes.Count > 0) { StringBuilder sb = new StringBuilder(); // Capture all subtypes, not just those within schema int countsub = 0; foreach (string ds in subtypes.Keys) { DocEntity refent = subtypes[ds]; if (this.m_included == null || this.m_included.ContainsKey(refent)) { countsub++; if (sb.Length != 0) { sb.Append("\r\n ,"); } sb.Append(ds); } } if (!docEntity.IsAbstract()) { writer.WriteLine(); } if (countsub > 1 || this.m_oneof) { writer.Write(" SUPERTYPE OF (ONEOF\r\n (" + sb.ToString() + "))"); } else if (countsub == 1) { writer.Write(" SUPERTYPE OF (" + sb.ToString() + ")"); } } if (docEntity.BaseDefinition != null) { writer.WriteLine(); writer.Write(" SUBTYPE OF ("); writer.Write(docEntity.BaseDefinition); writer.Write(")"); } writer.WriteLine(";"); // direct attributes bool hasinverse = false; bool hasderived = false; foreach (DocAttribute attr in docEntity.Attributes) { if (attr.Inverse == null && attr.Derived == null) { writer.Write("\t"); writer.Write(attr.Name); writer.Write(" : "); if (attr.IsOptional) { writer.Write("OPTIONAL "); } WriteExpressAggregation(writer, attr); if (this.m_included == null || this.m_included.ContainsKey(attr)) { writer.Write(attr.DefinedType); } else { writer.Write("IfcStrippedOptional"); } writer.WriteLine(";"); } else if (attr.Inverse != null && attr.Derived == null) { DocObject docref = null; if (mapGeneral.TryGetValue(attr.DefinedType, out docref)) { if (this.m_included == null || this.m_included.ContainsKey(docref)) { hasinverse = true; } } } else if (attr.Derived != null) { hasderived = true; } } // derived attributes if (hasderived) { writer.WriteLine(" DERIVE"); foreach (DocAttribute attr in docEntity.Attributes) { if (attr.Derived != null) { // determine the superclass having the attribute DocEntity found = null; DocEntity super = docEntity; while (super != null && found == null && super.BaseDefinition != null) { super = mapEntity[super.BaseDefinition] as DocEntity; if (super != null) { foreach (DocAttribute docattr in super.Attributes) { if (docattr.Name.Equals(attr.Name)) { // found class found = super; break; } } } } writer.Write("\t"); if (found != null) { // overridden attribute writer.Write("SELF\\"); writer.Write(found.Name); writer.Write("."); } writer.Write(attr.Name); writer.Write(" : "); WriteExpressAggregation(writer, attr); writer.Write(attr.DefinedType); writer.Write(" := "); writer.Write(attr.Derived); writer.WriteLine(";"); } } } // inverse attributes if (hasinverse) { writer.WriteLine(" INVERSE"); foreach (DocAttribute attr in docEntity.Attributes) { if (attr.Inverse != null && attr.Derived == null) { DocObject docref = null; if (mapGeneral.TryGetValue(attr.DefinedType, out docref)) { if (this.m_included == null || this.m_included.ContainsKey(docref)) { writer.Write("\t"); writer.Write(attr.Name); writer.Write(" : "); WriteExpressAggregation(writer, attr); writer.Write(attr.DefinedType); writer.Write(" FOR "); writer.Write(attr.Inverse); writer.WriteLine(";"); } } } } } // unique rules if (docEntity.UniqueRules.Count > 0) { writer.WriteLine(" UNIQUE"); foreach (DocUniqueRule where in docEntity.UniqueRules) { writer.Write("\t"); writer.Write(where.Name); writer.Write(" : "); foreach (DocUniqueRuleItem ruleitem in where.Items) { if (ruleitem != where.Items[0]) { writer.Write(", "); } writer.Write(ruleitem.Name); } writer.WriteLine(";"); } } // where rules if (docEntity.WhereRules.Count > 0) { writer.WriteLine(" WHERE"); foreach (DocWhereRule where in docEntity.WhereRules) { writer.Write("\t"); writer.Write(where.Name); writer.Write(" : "); writer.Write(MakeLongFormExpression(where.Expression, schemaid)); writer.WriteLine(";"); } } writer.WriteLine("END_ENTITY;"); writer.WriteLine(); } // functions foreach (DocFunction docFunction in mapFunction.Values) { writer.Write("FUNCTION "); writer.WriteLine(docFunction.Name); writer.WriteLine(MakeLongFormExpression(docFunction.Expression, schemaid)); writer.WriteLine("END_FUNCTION;"); writer.WriteLine(); } // rules foreach (DocGlobalRule docRule in mapRule.Values) { writer.Write("RULE "); writer.Write(docRule.Name); writer.WriteLine(" FOR"); writer.Write("\t("); writer.Write(docRule.ApplicableEntity); writer.WriteLine(");"); writer.WriteLine(docRule.Expression); // where writer.WriteLine(" WHERE"); foreach (DocWhereRule docWhere in docRule.WhereRules) { writer.Write(" "); writer.Write(docWhere.Name); writer.Write(" : "); writer.Write(MakeLongFormExpression(docWhere.Expression, schemaid)); writer.WriteLine(";"); } writer.WriteLine("END_RULE;"); writer.WriteLine(); } writer.WriteLine("END_SCHEMA;"); } }
public static void LoadAssembly(DocProject project, Assembly assem) { // look through classes of assembly foreach (Type t in assem.GetTypes()) { if (t.Namespace != null) { string[] namespaceparts = t.Namespace.Split('.'); string schema = namespaceparts[namespaceparts.Length - 1]; DocSection docSection = null; if (t.Namespace.EndsWith("Resource")) { docSection = project.Sections[7]; } else if (t.Namespace.EndsWith("Domain")) { docSection = project.Sections[6]; } else if (t.Namespace.Contains("Shared")) { docSection = project.Sections[5]; } else { docSection = project.Sections[4]; // kernel, extensions } // find schema DocSchema docSchema = null; foreach (DocSchema docEachSchema in docSection.Schemas) { if (docEachSchema.Name.Equals(schema)) { docSchema = docEachSchema; break; } } if (docSchema == null) { docSchema = new DocSchema(); docSchema.Name = schema; docSection.Schemas.Add(docSchema); docSection.SortSection(); } DocDefinition docDef = null; if (t.IsEnum) { DocEnumeration docEnum = new DocEnumeration(); docSchema.Types.Add(docEnum); docDef = docEnum; System.Reflection.FieldInfo[] fields = t.GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public); foreach (System.Reflection.FieldInfo field in fields) { DocConstant docConst = new DocConstant(); docEnum.Constants.Add(docConst); docConst.Name = field.Name; DescriptionAttribute[] attrs = (DescriptionAttribute[])field.GetCustomAttributes(typeof(DescriptionAttribute), false); if (attrs.Length == 1) { docConst.Documentation = attrs[0].Description; } } } else if (t.IsValueType) { PropertyInfo[] fields = t.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); if (fields.Length > 0) { Type typeField = fields[0].PropertyType; DocDefined docDefined = new DocDefined(); docSchema.Types.Add(docDefined); docDef = docDefined; docDefined.DefinedType = FormatCSC.GetExpressType(typeField); if (typeField.IsGenericType) { Type typeGeneric = typeField.GetGenericTypeDefinition(); typeField = typeField.GetGenericArguments()[0]; if (typeGeneric == typeof(ISet <>) || typeGeneric == typeof(HashSet <>)) { docDefined.Aggregation = new DocAttribute(); docDefined.Aggregation.AggregationType = (int)DocAggregationEnum.SET; } else if (typeGeneric == typeof(IList <>) || typeGeneric == typeof(List <>)) { docDefined.Aggregation = new DocAttribute(); docDefined.Aggregation.AggregationType = (int)DocAggregationEnum.LIST; } } MaxLengthAttribute mxa = (MaxLengthAttribute)fields[0].GetCustomAttribute(typeof(MaxLengthAttribute)); if (mxa != null) { docDefined.Length = mxa.Length; } } } else if (t.IsInterface) { DocSelect docSelect = new DocSelect(); docSchema.Types.Add(docSelect); docDef = docSelect; } else if (t.IsClass) { DocEntity docEntity = new DocEntity(); docSchema.Entities.Add(docEntity); docDef = docEntity; if (t.BaseType != null) { if (t.BaseType != typeof(object) && t.BaseType.Name != "SEntity") // back-compat for reflecting on IfcDoc types to generate Express { docEntity.BaseDefinition = t.BaseType.Name; } } docEntity.IsAbstract = t.IsAbstract; Dictionary <int, DocAttribute> attrsDirect = new Dictionary <int, DocAttribute>(); List <DocAttribute> attrsInverse = new List <DocAttribute>(); PropertyInfo[] fields = t.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | BindingFlags.DeclaredOnly); foreach (PropertyInfo field in fields) { DocAttribute docAttr = new DocAttribute(); docAttr.Name = field.Name; Type typeField = field.PropertyType; if (typeField.IsGenericType) { Type typeGeneric = typeField.GetGenericTypeDefinition(); typeField = typeField.GetGenericArguments()[0]; if (typeGeneric == typeof(Nullable <>)) { docAttr.IsOptional = true; } else if (typeGeneric == typeof(ISet <>) || typeGeneric == typeof(HashSet <>)) { docAttr.AggregationType = (int)DocAggregationEnum.SET; } else if (typeGeneric == typeof(IList <>) || typeGeneric == typeof(List <>)) { docAttr.AggregationType = (int)DocAggregationEnum.LIST; } } // primitives docAttr.DefinedType = FormatCSC.GetExpressType(typeField); MinLengthAttribute mla = (MinLengthAttribute)field.GetCustomAttribute(typeof(MinLengthAttribute)); if (mla != null) { docAttr.AggregationLower = mla.Length.ToString(); } MaxLengthAttribute mxa = (MaxLengthAttribute)field.GetCustomAttribute(typeof(MaxLengthAttribute)); if (mxa != null) { docAttr.AggregationUpper = mxa.Length.ToString(); } DescriptionAttribute da = (DescriptionAttribute)field.GetCustomAttribute(typeof(DescriptionAttribute)); if (da != null) { docAttr.Documentation = da.Description; } DataMemberAttribute dma = (DataMemberAttribute)field.GetCustomAttribute(typeof(DataMemberAttribute)); if (dma != null) { attrsDirect.Add(dma.Order, docAttr); RequiredAttribute rqa = (RequiredAttribute)field.GetCustomAttribute(typeof(RequiredAttribute)); if (rqa == null) { docAttr.IsOptional = true; } CustomValidationAttribute cva = (CustomValidationAttribute)field.GetCustomAttribute(typeof(CustomValidationAttribute)); if (cva != null) { docAttr.IsUnique = true; } } else { InversePropertyAttribute ipa = (InversePropertyAttribute)field.GetCustomAttribute(typeof(InversePropertyAttribute)); if (ipa != null) { docAttr.Inverse = ipa.Property; attrsInverse.Add(docAttr); } } // xml XmlIgnoreAttribute xia = (XmlIgnoreAttribute)field.GetCustomAttribute(typeof(XmlIgnoreAttribute)); if (xia != null) { docAttr.XsdFormat = DocXsdFormatEnum.Hidden; } else { XmlElementAttribute xea = (XmlElementAttribute)field.GetCustomAttribute(typeof(XmlElementAttribute)); if (xea != null) { if (!String.IsNullOrEmpty(xea.ElementName)) { docAttr.XsdFormat = DocXsdFormatEnum.Element; } else { docAttr.XsdFormat = DocXsdFormatEnum.Attribute; } } } } foreach (DocAttribute docAttr in attrsDirect.Values) { docEntity.Attributes.Add(docAttr); } foreach (DocAttribute docAttr in attrsInverse) { docEntity.Attributes.Add(docAttr); } // get derived attributes based on properties #if false PropertyInfo[] props = t.GetProperties(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public); foreach (PropertyInfo prop in props) { // if no backing field, then derived FieldInfo field = t.GetField("_" + prop.Name, BindingFlags.NonPublic | BindingFlags.Instance); if (field == null) { DocAttribute docDerived = new DocAttribute(); docDerived.Name = prop.Name; docEntity.Attributes.Add(docDerived); } } #endif } if (docDef != null) { docDef.Name = t.Name; docDef.Uuid = t.GUID; } docSchema.SortTypes(); docSchema.SortEntities(); } } // pass 2: hook up selects foreach (Type t in assem.GetTypes()) { Type[] typeInterfaces = t.GetInterfaces(); Type[] typeInherit = null; if (t.BaseType != null) { typeInherit = t.BaseType.GetInterfaces(); } if (typeInterfaces.Length > 0) { foreach (Type typeI in typeInterfaces) { if (typeInherit == null || !typeInherit.Contains <Type>(typeI)) { DocSelect docSelect = project.GetDefinition(typeI.Name) as DocSelect; if (docSelect != null) { DocSelectItem docItem = new DocSelectItem(); docItem.Name = t.Name; docSelect.Selects.Add(docItem); } } } } } }
/// <summary> /// Creates a documentation schema from a VEX schema /// </summary> /// <param name="schemata">The VEX schema to import</param> /// <param name="project">The documentation project where the imported schema is to be created</param> /// <returns>The imported documentation schema</returns> internal static DocSchema ImportVex(SCHEMATA schemata, DocProject docProject, bool updateDescriptions) { DocSchema docSchema = docProject.RegisterSchema(schemata.name); if (updateDescriptions && schemata.comment != null && schemata.comment.text != null) { docSchema.Documentation = schemata.comment.text.text; } docSchema.DiagramPagesHorz = schemata.settings.page.nhorizontalpages; docSchema.DiagramPagesVert = schemata.settings.page.nverticalpages; // remember current types for deletion if they no longer exist List<DocObject> existing = new List<DocObject>(); foreach (DocType doctype in docSchema.Types) { existing.Add(doctype); } foreach (DocEntity docentity in docSchema.Entities) { existing.Add(docentity); } foreach (DocFunction docfunction in docSchema.Functions) { existing.Add(docfunction); } foreach (DocGlobalRule docrule in docSchema.GlobalRules) { existing.Add(docrule); } docSchema.PageTargets.Clear(); docSchema.SchemaRefs.Clear(); docSchema.Comments.Clear(); // remember references for fixing up attributes afterwords Dictionary<object, DocDefinition> mapRefs = new Dictionary<object, DocDefinition>(); Dictionary<ATTRIBUTE_DEF, DocAttribute> mapAtts = new Dictionary<ATTRIBUTE_DEF, DocAttribute>(); //Dictionary<SELECT_DEF, DocSelectItem> mapSels = new Dictionary<SELECT_DEF, DocSelectItem>(); Dictionary<SELECT_DEF, DocLine> mapSL = new Dictionary<SELECT_DEF, DocLine>(); Dictionary<SUBTYPE_DEF, DocLine> mapSubs = new Dictionary<SUBTYPE_DEF, DocLine>(); Dictionary<PAGE_REF, DocPageTarget> mapPage = new Dictionary<PAGE_REF, DocPageTarget>(); // entities and types foreach (object obj in schemata.objects) { if (obj is ENTITIES) { ENTITIES ent = (ENTITIES)obj; // filter out orphaned entities having upper flags set if ((ent.flag & 0xFFFF0000) == 0 && (ent.interfaceto == null || ent.interfaceto.theschema == null)) { // create if doesn't exist string name = ent.name.text; string super = null; if (ent.supertypes.Count > 0 && ent.supertypes[0].the_supertype is ENTITIES) { ENTITIES superent = (ENTITIES)ent.supertypes[0].the_supertype; super = superent.name.text; } DocEntity docEntity = docSchema.RegisterEntity(name); if (existing.Contains(docEntity)) { existing.Remove(docEntity); } mapRefs.Add(obj, docEntity); // clear out existing if merging docEntity.BaseDefinition = null; foreach(DocSubtype docSub in docEntity.Subtypes) { docSub.Delete(); } docEntity.Subtypes.Clear(); foreach(DocUniqueRule docUniq in docEntity.UniqueRules) { docUniq.Delete(); } docEntity.UniqueRules.Clear(); foreach(DocLine docLine in docEntity.Tree) { docLine.Delete(); } docEntity.Tree.Clear(); if (updateDescriptions && ent.comment != null && ent.comment.text != null) { docEntity.Documentation = ent.comment.text.text; } if (ent.supertypes.Count > 0 && ent.supertypes[0].the_supertype is ENTITIES) { docEntity.BaseDefinition = ((ENTITIES)ent.supertypes[0].the_supertype).name.text; } docEntity.EntityFlags = ent.flag; if (ent.subtypes != null) { foreach (SUBTYPE_DEF sd in ent.subtypes) { // new (3.8): intermediate subtypes for diagrams DocLine docLine = new DocLine(); ImportVexLine(sd.layout, null, docLine.DiagramLine, null); docEntity.Tree.Add(docLine); OBJECT od = (OBJECT)sd.the_subtype; // tunnel through page ref if (od is PAGE_REF_TO) { od = ((PAGE_REF_TO)od).pageref; } if (od is TREE) { TREE tree = (TREE)od; foreach (OBJECT o in tree.list) { OBJECT os = o; OBJECT_LINE_LAYOUT linelayout = null; if (o is SUBTYPE_DEF) { SUBTYPE_DEF osd = (SUBTYPE_DEF)o; linelayout = osd.layout; os = ((SUBTYPE_DEF)o).the_subtype; } if (os is PAGE_REF_TO) { os = ((PAGE_REF_TO)os).pageref; } if (os is ENTITIES) { DocSubtype docSub = new DocSubtype(); docSub.DefinedType = ((ENTITIES)os).name.text; docEntity.Subtypes.Add(docSub); DocLine docSubline = new DocLine(); docLine.Tree.Add(docSubline); if (o is SUBTYPE_DEF) { mapSubs.Add((SUBTYPE_DEF)o, docSubline); } ImportVexLine(linelayout, null, docSubline.DiagramLine, null); } else { Debug.Assert(false); } } } else if (od is ENTITIES) { DocSubtype docInt = new DocSubtype(); docEntity.Subtypes.Add(docInt); docInt.DefinedType = ((ENTITIES)od).name.text; } else { Debug.Assert(false); } } } // determine EXPRESS-G page based on placement (required for generating hyperlinks) if (ent.layout != null) { ImportVexRectangle(docEntity, ent.layout.rectangle, schemata); } if (ent.attributes != null) { List<DocAttribute> existingattr = new List<DocAttribute>(); foreach (DocAttribute docAttr in docEntity.Attributes) { existingattr.Add(docAttr); } // attributes are replaced, not merged (template don't apply here) foreach (ATTRIBUTE_DEF attr in ent.attributes) { if (attr.name != null) { DocAttribute docAttr = docEntity.RegisterAttribute(attr.name.text); mapAtts.Add(attr, docAttr); if (existingattr.Contains(docAttr)) { existingattr.Remove(docAttr); } if (updateDescriptions && attr.comment != null && attr.comment.text != null) { docAttr.Documentation = attr.comment.text.text; } if (docAttr.DiagramLabel != null) { docAttr.DiagramLabel.Delete(); docAttr.DiagramLabel = null; } foreach(DocPoint docPoint in docAttr.DiagramLine) { docPoint.Delete(); } docAttr.DiagramLine.Clear(); if (attr.layout != null) { if (attr.layout.pline != null) { // intermediate lines if (attr.layout.pline.rpoint != null) { docAttr.DiagramLabel = new DocRectangle(); ImportVexLine(attr.layout, attr.name.layout, docAttr.DiagramLine, docAttr.DiagramLabel); } } } OBJECT def = attr.the_attribute; if (attr.the_attribute is PAGE_REF_TO) { PAGE_REF_TO pr = (PAGE_REF_TO)attr.the_attribute; def = pr.pageref; } if (def is DEFINED_TYPE) { DEFINED_TYPE dt = (DEFINED_TYPE)def; docAttr.DefinedType = dt.name.text; } else if (def is ENTITIES) { ENTITIES en = (ENTITIES)def; docAttr.DefinedType = en.name.text; } else if (def is ENUMERATIONS) { ENUMERATIONS en = (ENUMERATIONS)def; docAttr.DefinedType = en.name.text; } else if (def is SELECTS) { SELECTS en = (SELECTS)def; docAttr.DefinedType = en.name.text; } else if (def is PRIMITIVE_TYPE) { PRIMITIVE_TYPE en = (PRIMITIVE_TYPE)def; string length = ""; if (en.constraints > 0) { length = " (" + en.constraints.ToString() + ")"; } else if (en.constraints < 0) { int len = -en.constraints; length = " (" + len.ToString() + ") FIXED"; } docAttr.DefinedType = en.name.text + length; } else if (def is SCHEMA_REF) { SCHEMA_REF en = (SCHEMA_REF)def; docAttr.DefinedType = en.name.text; } else { Debug.Assert(false); } docAttr.AttributeFlags = attr.attributeflag; AGGREGATES vexAggregates = attr.aggregates; DocAttribute docAggregate = docAttr; while (vexAggregates != null) { // traverse nested aggregation (e.g. IfcStructuralLoadConfiguration) docAggregate.AggregationType = vexAggregates.aggrtype + 1; docAggregate.AggregationLower = vexAggregates.lower; docAggregate.AggregationUpper = vexAggregates.upper; docAggregate.AggregationFlag = vexAggregates.flag; vexAggregates = vexAggregates.next; if (vexAggregates != null) { // inner array (e.g. IfcStructuralLoadConfiguration) docAggregate.AggregationAttribute = new DocAttribute(); docAggregate = docAggregate.AggregationAttribute; } } docAttr.Derived = attr.is_derived; if (attr.user_redeclaration != null) { docAttr.Inverse = attr.user_redeclaration; } else if (attr.is_inverse is ATTRIBUTE_DEF) { ATTRIBUTE_DEF adef = (ATTRIBUTE_DEF)attr.is_inverse; docAttr.Inverse = adef.name.text; } else if (attr.is_inverse != null) { Debug.Assert(false); } } } foreach(DocAttribute docAttr in existingattr) { docEntity.Attributes.Remove(docAttr); docAttr.Delete(); } } // unique rules if (ent.uniquenes != null) { // rules are replaced, not merged (template don't apply here) //docEntity.UniqueRules = new List<DocUniqueRule>(); foreach (UNIQUE_RULE rule in ent.uniquenes) { DocUniqueRule docRule = new DocUniqueRule(); docEntity.UniqueRules.Add(docRule); docRule.Name = rule.name; docRule.Items = new List<DocUniqueRuleItem>(); foreach (ATTRIBUTE_DEF ruleitem in rule.for_attribute) { DocUniqueRuleItem item = new DocUniqueRuleItem(); item.Name = ruleitem.name.text; docRule.Items.Add(item); } } } // where rules if (ent.wheres != null) { List<DocWhereRule> existingattr = new List<DocWhereRule>(); foreach (DocWhereRule docWhere in docEntity.WhereRules) { existingattr.Add(docWhere); } foreach (WHERE_RULE where in ent.wheres) { DocWhereRule docWhere = docEntity.RegisterWhereRule(where.name); docWhere.Expression = where.rule_context; if(existingattr.Contains(docWhere)) { existingattr.Remove(docWhere); } if (updateDescriptions && where.comment != null && where.comment.text != null) { docWhere.Documentation = where.comment.text.text; } } foreach(DocWhereRule exist in existingattr) { exist.Delete(); docEntity.WhereRules.Remove(exist); } } } } else if (obj is ENUMERATIONS) { ENUMERATIONS ent = (ENUMERATIONS)obj; if (ent.interfaceto == null || ent.interfaceto.theschema == null) { if (schemata.name.Equals("IfcConstructionMgmtDomain", StringComparison.OrdinalIgnoreCase) && ent.name.text.Equals("IfcNullStyle", StringComparison.OrdinalIgnoreCase)) { // hack to workaround vex bug Debug.Assert(true); } else { DocEnumeration docEnumeration = docSchema.RegisterType<DocEnumeration>(ent.name.text); if (existing.Contains(docEnumeration)) { existing.Remove(docEnumeration); } mapRefs.Add(obj, docEnumeration); if (updateDescriptions && ent.comment != null && ent.comment.text != null) { docEnumeration.Documentation = ent.comment.text.text; } // determine EXPRESS-G page based on placement (required for generating hyperlinks) if (ent.typelayout != null && schemata.settings != null && schemata.settings.page != null) { ImportVexRectangle(docEnumeration, ent.typelayout.rectangle, schemata); } // enumeration values are replaced, not merged (template don't apply here) docEnumeration.Constants.Clear(); foreach (string s in ent.enums) { DocConstant docConstant = new DocConstant(); docEnumeration.Constants.Add(docConstant); docConstant.Name = s; } } } } else if (obj is DEFINED_TYPE) { DEFINED_TYPE ent = (DEFINED_TYPE)obj; if (ent.interfaceto == null || ent.interfaceto.theschema == null) { DocDefined docDefined = docSchema.RegisterType<DocDefined>(ent.name.text); if (existing.Contains(docDefined)) { existing.Remove(docDefined); } mapRefs.Add(obj, docDefined); if (updateDescriptions && ent.comment != null && ent.comment.text != null) { docDefined.Documentation = ent.comment.text.text; } if (ent.layout != null) { ImportVexRectangle(docDefined, ent.layout.rectangle, schemata); } if(ent.defined.object_line_layout != null) { foreach(DocPoint docPoint in docDefined.DiagramLine) { docPoint.Delete(); } docDefined.DiagramLine.Clear(); ImportVexLine(ent.defined.object_line_layout, null, docDefined.DiagramLine, null); } OBJECT os = (OBJECT)ent.defined.defined; if (os is PAGE_REF_TO) { os = ((PAGE_REF_TO)os).pageref; } if (os is PRIMITIVE_TYPE) { PRIMITIVE_TYPE pt = (PRIMITIVE_TYPE)os; docDefined.DefinedType = pt.name.text; if (pt.constraints != 0) { docDefined.Length = pt.constraints; } } else if (os is DEFINED_TYPE) { DEFINED_TYPE dt = (DEFINED_TYPE)os; docDefined.DefinedType = dt.name.text; } else if (os is ENTITIES) { ENTITIES et = (ENTITIES)os; docDefined.DefinedType = et.name.text; } else { Debug.Assert(false); } // aggregation AGGREGATES vexAggregates = ent.defined.aggregates; if (vexAggregates != null) { DocAttribute docAggregate = new DocAttribute(); docDefined.Aggregation = docAggregate; docAggregate.AggregationType = vexAggregates.aggrtype + 1; docAggregate.AggregationLower = vexAggregates.lower; docAggregate.AggregationUpper = vexAggregates.upper; docAggregate.AggregationFlag = vexAggregates.flag; } // where rules if (ent.whererules != null) { // rules are replaced, not merged (template don't apply here) foreach(DocWhereRule docWhere in docDefined.WhereRules) { docWhere.Delete(); } docDefined.WhereRules.Clear(); foreach (WHERE_RULE where in ent.whererules) { DocWhereRule docWhere = new DocWhereRule(); docDefined.WhereRules.Add(docWhere); docWhere.Name = where.name; docWhere.Expression = where.rule_context; if (where.comment != null && where.comment.text != null) { docWhere.Documentation = where.comment.text.text; } } } } } else if (obj is SELECTS) { SELECTS ent = (SELECTS)obj; if (ent.interfaceto == null || ent.interfaceto.theschema == null) { DocSelect docSelect = docSchema.RegisterType<DocSelect>(ent.name.text); if (existing.Contains(docSelect)) { existing.Remove(docSelect); } mapRefs.Add(obj, docSelect); if (updateDescriptions && ent.comment != null && ent.comment.text != null) { docSelect.Documentation = ent.comment.text.text; } // determine EXPRESS-G page based on placement (required for generating hyperlinks) if (ent.typelayout != null) { ImportVexRectangle(docSelect, ent.typelayout.rectangle, schemata); } docSelect.Selects.Clear(); docSelect.Tree.Clear(); foreach (SELECT_DEF sdef in ent.selects) { DocLine docLine = new DocLine(); docSelect.Tree.Add(docLine); ImportVexLine(sdef.layout, null, docLine.DiagramLine, null); mapSL.Add(sdef, docLine); if (sdef.def is TREE) { TREE tree = (TREE)sdef.def; foreach (OBJECT o in tree.list) { DocSelectItem dsi = new DocSelectItem(); docSelect.Selects.Add(dsi); OBJECT os = o; if (o is SELECT_DEF) { SELECT_DEF selectdef = (SELECT_DEF)o; DocLine docLineSub = new DocLine(); docLine.Tree.Add(docLineSub); ImportVexLine(selectdef.layout, null, docLineSub.DiagramLine, null); mapSL.Add(selectdef, docLineSub); os = ((SELECT_DEF)o).def; } else { Debug.Assert(false); } if (os is PAGE_REF_TO) { PAGE_REF_TO pr = (PAGE_REF_TO)os; os = pr.pageref; } if (os is DEFINITION) { dsi.Name = ((DEFINITION)os).name.text; } } } else { OBJECT os = (OBJECT)sdef.def; if (os is PAGE_REF_TO) { PAGE_REF_TO pr = (PAGE_REF_TO)os; os = pr.pageref; } DocSelectItem dsi = new DocSelectItem(); docSelect.Selects.Add(dsi); if (os is DEFINITION) { dsi.Name = ((DEFINITION)os).name.text; } } } } } else if (obj is GLOBAL_RULE) { GLOBAL_RULE func = (GLOBAL_RULE)obj; DocGlobalRule docFunction = docSchema.RegisterRule(func.name); if (existing.Contains(docFunction)) { existing.Remove(docFunction); } // clear out existing if merging docFunction.WhereRules.Clear(); if (updateDescriptions && func.comment != null && func.comment.text != null) { docFunction.Documentation = func.comment.text.text; } docFunction.Expression = func.rule_context; foreach (WHERE_RULE wr in func.where_rule) { DocWhereRule docW = new DocWhereRule(); docW.Name = wr.name; docW.Expression = wr.rule_context; if (wr.comment != null) { docW.Documentation = wr.comment.text.text; } docFunction.WhereRules.Add(docW); } if (func.for_entities.Count == 1) { docFunction.ApplicableEntity = func.for_entities[0].ToString(); } } else if (obj is USER_FUNCTION) { USER_FUNCTION func = (USER_FUNCTION)obj; DocFunction docFunction = docSchema.RegisterFunction(func.name); if (existing.Contains(docFunction)) { existing.Remove(docFunction); } if (updateDescriptions && func.comment != null && func.comment.text != null) { docFunction.Documentation = func.comment.text.text; } docFunction.Expression = func.rule_context; // NOTE: While the VEX schema can represent parameters and return values, Visual Express does not implement it! // Rather, parameter info is also included in the 'rule_context' if (func.return_value != null) { docFunction.ReturnValue = func.return_value.ToString(); } else { docFunction.ReturnValue = null; } docFunction.Parameters.Clear(); if (func.parameter_list != null) { foreach (PARAMETER par in func.parameter_list) { DocParameter docParameter = new DocParameter(); docParameter.Name = par.name; docParameter.DefinedType = par.parameter_type.ToString(); docFunction.Parameters.Add(docParameter); } } } else if (obj is PRIMITIVE_TYPE) { PRIMITIVE_TYPE prim = (PRIMITIVE_TYPE)obj; DocPrimitive docPrimitive = new DocPrimitive(); docPrimitive.Name = prim.name.text; if (prim.layout != null) { ImportVexRectangle(docPrimitive, prim.layout.rectangle, schemata); } docSchema.Primitives.Add(docPrimitive); mapRefs.Add(obj, docPrimitive); } else if (obj is COMMENT) { COMMENT comment = (COMMENT)obj; // only deal with comments that are part of EXPRESS-G layout -- ignore those referenced by definitions and old cruft left behind due to older versions of VisualE that were buggy if (comment.layout != null) { DocComment docComment = new DocComment(); docComment.Documentation = comment.text.text; ImportVexRectangle(docComment, comment.layout.rectangle, schemata); docSchema.Comments.Add(docComment); } } else if (obj is INTERFACE_SCHEMA) { INTERFACE_SCHEMA iface = (INTERFACE_SCHEMA)obj; DocSchemaRef docSchemaRef = new DocSchemaRef(); docSchema.SchemaRefs.Add(docSchemaRef); docSchemaRef.Name = iface.schema_name; foreach (object o in iface.item) { if (o is DEFINITION) { DocDefinitionRef docDefRef = new DocDefinitionRef(); docSchemaRef.Definitions.Add(docDefRef); mapRefs.Add(o, docDefRef); docDefRef.Name = ((DEFINITION)o).name.text; if (o is DEFINED_TYPE) { DEFINED_TYPE dt = (DEFINED_TYPE)o; if (dt.layout != null) { ImportVexRectangle(docDefRef, dt.layout.rectangle, schemata); } } else if (o is ENTITIES) { ENTITIES ents = (ENTITIES)o; if (ents.layout != null) // null for IfcPolyline reference in IfcGeometricModelResource { ImportVexRectangle(docDefRef, ents.layout.rectangle, schemata); } if (ents.subtypes != null) { foreach (SUBTYPE_DEF subdef in ents.subtypes) { OBJECT_LINE_LAYOUT linelayout = subdef.layout; DocLine docSub = new DocLine(); ImportVexLine(subdef.layout, null, docSub.DiagramLine, null); docDefRef.Tree.Add(docSub); if(subdef.the_subtype is TREE) { TREE tree = (TREE)subdef.the_subtype; foreach(object oo in tree.list) { if(oo is SUBTYPE_DEF) { SUBTYPE_DEF subsubdef = (SUBTYPE_DEF)oo; DocLine docSubSub = new DocLine(); docSub.Tree.Add(docSubSub); ImportVexLine(subsubdef.layout, null, docSubSub.DiagramLine, null); mapSubs.Add(subsubdef, docSubSub); } } } } } } else if (o is ENUMERATIONS) { ENUMERATIONS enums = (ENUMERATIONS)o; if (enums.typelayout != null) { ImportVexRectangle(docDefRef, enums.typelayout.rectangle, schemata); } } else if (o is SELECTS) { SELECTS sels = (SELECTS)o; if (sels.typelayout != null) { ImportVexRectangle(docDefRef, sels.typelayout.rectangle, schemata); } } else if(o is SCHEMA_REF) { SCHEMA_REF sref = (SCHEMA_REF)o; if(sref.layout != null) { ImportVexRectangle(docDefRef, sref.layout.rectangle, schemata); } } } else if (o is USER_FUNCTION) { DocDefinitionRef docDefRef = new DocDefinitionRef(); docSchemaRef.Definitions.Add(docDefRef); USER_FUNCTION uf = (USER_FUNCTION)o; docDefRef.Name = uf.name; } } } else if (obj is PAGE_REF) { PAGE_REF pageref = (PAGE_REF)obj; DocPageTarget docPageTarget = new DocPageTarget(); docSchema.PageTargets.Add(docPageTarget); docPageTarget.Name = pageref.text.text; docPageTarget.DiagramNumber = pageref.pagenr; ImportVexLine(pageref.pageline.layout, null, docPageTarget.DiagramLine, null); ImportVexRectangle(docPageTarget, pageref.layout.rectangle, schemata); foreach (PAGE_REF_TO pagerefto in pageref.pagerefto) { DocPageSource docPageSource = new DocPageSource(); docPageTarget.Sources.Add(docPageSource); docPageSource.DiagramNumber = pagerefto.pagenr; docPageSource.Name = pagerefto.text.text; ImportVexRectangle(docPageSource, pagerefto.layout.rectangle, schemata); mapRefs.Add(pagerefto, docPageSource); } mapPage.Add(pageref, docPageTarget); } } foreach (DocObject docobj in existing) { if (docobj is DocEntity) { docSchema.Entities.Remove((DocEntity)docobj); } else if (docobj is DocType) { docSchema.Types.Remove((DocType)docobj); } else if (docobj is DocFunction) { docSchema.Functions.Remove((DocFunction)docobj); } else if (docobj is DocGlobalRule) { docSchema.GlobalRules.Remove((DocGlobalRule)docobj); } docobj.Delete(); } // now fix up attributes foreach (ATTRIBUTE_DEF docAtt in mapAtts.Keys) { DocAttribute docAttr = mapAtts[docAtt]; docAttr.Definition = mapRefs[docAtt.the_attribute]; } foreach (PAGE_REF page in mapPage.Keys) { DocPageTarget docPage = mapPage[page]; docPage.Definition = mapRefs[page.pageline.pageref]; } foreach (SELECT_DEF sd in mapSL.Keys) { DocLine docLine = mapSL[sd]; if (mapRefs.ContainsKey(sd.def)) { docLine.Definition = mapRefs[sd.def]; } } foreach (SUBTYPE_DEF sd in mapSubs.Keys) { DocLine docLine = mapSubs[sd]; if (mapRefs.ContainsKey(sd.the_subtype)) { docLine.Definition = mapRefs[sd.the_subtype]; } } foreach(object o in mapRefs.Keys) { if (o is DEFINED_TYPE) { DEFINED_TYPE def = (DEFINED_TYPE)o; if (def.interfaceto == null || def.interfaceto.theschema == null) { // declared within DocDefined docDef = (DocDefined)mapRefs[o]; docDef.Definition = mapRefs[def.defined.defined]; } } } return docSchema; }
private void ctlExpressG_LinkOperation(object sender, EventArgs e) { if (this.ctlExpressG.Highlight is DocDefinition) { DocDefinition docDefinition = (DocDefinition)this.ctlExpressG.Highlight; if(e == null && docDefinition is DocEntity) { DocEntity docEntity = (DocEntity)docDefinition; // link subtype (either from entity or entity reference) docEntity.BaseDefinition = this.ctlExpressG.Selection.Name; DocLine docLine = new DocLine(); docLine.DiagramLine.Add(new DocPoint()); docLine.DiagramLine.Add(new DocPoint()); docLine.DiagramLine.Add(new DocPoint()); docLine.Definition = docDefinition; List<DocLine> tree = null; if (this.ctlExpressG.Selection is DocEntity) { DocEntity docSuper = (DocEntity)this.ctlExpressG.Selection; DocSubtype docSub = new DocSubtype(); docSub.DefinedType = docEntity.Name; docSuper.Subtypes.Add(docSub); tree = docSuper.Tree; } else if (this.ctlExpressG.Selection is DocDefinitionRef) { tree = ((DocDefinitionRef)this.ctlExpressG.Selection).Tree; } if(tree != null) { if (tree.Count > 0 && tree[0].Definition == null) { // existing tree structure tree[0].Tree.Add(docLine); } else { // no tree structure tree.Add(docLine); } } this.ctlExpressG.LayoutDefinition((DocDefinition)this.ctlExpressG.Selection); this.ctlExpressG.LayoutDefinition(docDefinition); this.ctlExpressG.Redraw(); } else if (this.ctlExpressG.Selection is DocEntity) { // create an attribute DocEntity docEntity = (DocEntity)this.ctlExpressG.Selection; DocAttribute docAttr = new DocAttribute(); docAttr.Name = "Attribute"; docAttr.Definition = docDefinition; docAttr.DefinedType = docAttr.Definition.Name; CtlExpressG.LayoutLine(docEntity, docAttr.Definition, docAttr.DiagramLine); docAttr.DiagramLabel = new DocRectangle(); docAttr.DiagramLabel.X = docAttr.DiagramLine[0].X; docAttr.DiagramLabel.Y = docAttr.DiagramLine[0].Y; docAttr.DiagramLabel.Width = 400.0; docAttr.DiagramLabel.Height = 100.0; docEntity.Attributes.Add(docAttr); TreeNode tnParent = this.treeView.SelectedNode; this.treeView.SelectedNode = this.LoadNode(tnParent, docAttr, docAttr.ToString(), false); toolStripMenuItemEditRename_Click(this, e); } else if (this.ctlExpressG.Selection is DocSelect) { // link select DocSelect docSelect = (DocSelect)this.ctlExpressG.Selection; // link definition DocSelectItem docItem = new DocSelectItem(); //docItem.Definition = docDefinition; docItem.Name = docDefinition.Name; //CtlExpressG.LayoutLine(docSelect, docItem.Definition, docItem.DiagramLine); docSelect.Selects.Add(docItem); // link lines DocLine docLine = new DocLine(); docLine.Definition = docDefinition; CtlExpressG.LayoutLine(docSelect, docDefinition, docLine.DiagramLine); docSelect.Tree.Add(docLine); TreeNode tnParent = this.treeView.SelectedNode; this.treeView.SelectedNode = this.LoadNode(tnParent, docItem, docItem.ToString(), false); } else if (this.ctlExpressG.Selection is DocDefined) { // link defined DocDefined docDefined = (DocDefined)this.ctlExpressG.Selection; docDefined.Definition = docDefinition; docDefined.DefinedType = docDefined.Definition.Name; CtlExpressG.LayoutLine(docDefined, docDefined.Definition, docDefined.DiagramLine); } } }
/// <summary> /// Loads all content from a folder hierarchy (overlaying anything already existing) /// </summary> /// <param name="project"></param> /// <param name="path"></param> public static void Load(DocProject project, string path) { // get all files within folder hierarchy string pathSchema = path + @"\schemas"; IEnumerable <string> en = System.IO.Directory.EnumerateFiles(pathSchema, "*.cs", System.IO.SearchOption.AllDirectories); List <string> list = new List <string>(); foreach (string s in en) { list.Add(s); } string[] files = list.ToArray(); Dictionary <string, string> options = new Dictionary <string, string> { { "CompilerVersion", "v4.0" } }; Microsoft.CSharp.CSharpCodeProvider prov = new Microsoft.CSharp.CSharpCodeProvider(options); System.CodeDom.Compiler.CompilerParameters parms = new System.CodeDom.Compiler.CompilerParameters(); parms.GenerateInMemory = true; parms.GenerateExecutable = false; parms.ReferencedAssemblies.Add("System.dll"); parms.ReferencedAssemblies.Add("System.Core.dll"); parms.ReferencedAssemblies.Add("System.ComponentModel.dll"); parms.ReferencedAssemblies.Add("System.ComponentModel.DataAnnotations.dll"); parms.ReferencedAssemblies.Add("System.Data.dll"); parms.ReferencedAssemblies.Add("System.Runtime.Serialization.dll"); parms.ReferencedAssemblies.Add("System.Xml.dll"); System.CodeDom.Compiler.CompilerResults results = prov.CompileAssemblyFromFile(parms, files); System.Reflection.Assembly assem = results.CompiledAssembly; // look through classes of assembly foreach (Type t in assem.GetTypes()) { string[] namespaceparts = t.Namespace.Split('.'); string schema = namespaceparts[namespaceparts.Length - 1]; DocSection docSection = null; if (t.Namespace.EndsWith("Resource")) { docSection = project.Sections[7]; } else if (t.Namespace.EndsWith("Domain")) { docSection = project.Sections[6]; } else if (t.Namespace.Contains("Shared")) { docSection = project.Sections[5]; } else { docSection = project.Sections[4]; // kernel, extensions } // find schema DocSchema docSchema = null; foreach (DocSchema docEachSchema in docSection.Schemas) { if (docEachSchema.Name.Equals(schema)) { docSchema = docEachSchema; break; } } if (docSchema == null) { docSchema = new DocSchema(); docSchema.Name = schema; docSection.Schemas.Add(docSchema); docSection.SortSchemas(); } DocDefinition docDef = null; if (t.IsEnum) { DocEnumeration docEnum = new DocEnumeration(); docSchema.Types.Add(docEnum); docDef = docEnum; System.Reflection.FieldInfo[] fields = t.GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public); foreach (System.Reflection.FieldInfo field in fields) { DocConstant docConst = new DocConstant(); docEnum.Constants.Add(docConst); docConst.Name = field.Name; DescriptionAttribute[] attrs = (DescriptionAttribute[])field.GetCustomAttributes(typeof(DescriptionAttribute), false); if (attrs.Length == 1) { docConst.Documentation = attrs[0].Description; } } } else if (t.IsValueType) { DocDefined docDefined = new DocDefined(); docSchema.Types.Add(docDefined); docDef = docDefined; PropertyInfo[] fields = t.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); docDefined.DefinedType = fields[0].PropertyType.Name; } else if (t.IsInterface) { DocSelect docSelect = new DocSelect(); docSchema.Types.Add(docSelect); docDef = docSelect; } else if (t.IsClass) { DocEntity docEntity = new DocEntity(); docSchema.Entities.Add(docEntity); docDef = docEntity; if (t.BaseType != typeof(object)) { docEntity.BaseDefinition = t.BaseType.Name; } if (!t.IsAbstract) { docEntity.EntityFlags = 0x20; } Dictionary <int, DocAttribute> attrsDirect = new Dictionary <int, DocAttribute>(); List <DocAttribute> attrsInverse = new List <DocAttribute>(); PropertyInfo[] fields = t.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | BindingFlags.DeclaredOnly); foreach (PropertyInfo field in fields) { DocAttribute docAttr = new DocAttribute(); docAttr.Name = field.Name.Substring(1); Type typeField = field.PropertyType; if (typeField.IsGenericType) { Type typeGeneric = typeField.GetGenericTypeDefinition(); typeField = typeField.GetGenericArguments()[0]; if (typeGeneric == typeof(Nullable <>)) { docAttr.IsOptional = true; } else if (typeGeneric == typeof(ISet <>)) { docAttr.AggregationType = (int)DocAggregationEnum.SET; } else if (typeGeneric == typeof(IList <>)) { docAttr.AggregationType = (int)DocAggregationEnum.LIST; } } docAttr.DefinedType = typeField.Name; MinLengthAttribute mla = (MinLengthAttribute)field.GetCustomAttribute(typeof(MinLengthAttribute)); if (mla != null) { docAttr.AggregationLower = mla.Length.ToString(); } MaxLengthAttribute mxa = (MaxLengthAttribute)field.GetCustomAttribute(typeof(MaxLengthAttribute)); if (mxa != null) { docAttr.AggregationUpper = mxa.Length.ToString(); } PropertyInfo propinfo = t.GetProperty(docAttr.Name); if (propinfo != null) { DescriptionAttribute da = (DescriptionAttribute)propinfo.GetCustomAttribute(typeof(DescriptionAttribute)); if (da != null) { docAttr.Documentation = da.Description; } } DataMemberAttribute dma = (DataMemberAttribute)field.GetCustomAttribute(typeof(DataMemberAttribute)); if (dma != null) { attrsDirect.Add(dma.Order, docAttr); RequiredAttribute rqa = (RequiredAttribute)field.GetCustomAttribute(typeof(RequiredAttribute)); if (rqa == null) { docAttr.IsOptional = true; } CustomValidationAttribute cva = (CustomValidationAttribute)field.GetCustomAttribute(typeof(CustomValidationAttribute)); if (cva != null) { docAttr.IsUnique = true; } } else { InversePropertyAttribute ipa = (InversePropertyAttribute)field.GetCustomAttribute(typeof(InversePropertyAttribute)); if (ipa != null) { docAttr.Inverse = ipa.Property; attrsInverse.Add(docAttr); } } // xml XmlIgnoreAttribute xia = (XmlIgnoreAttribute)field.GetCustomAttribute(typeof(XmlIgnoreAttribute)); if (xia != null) { docAttr.XsdFormat = DocXsdFormatEnum.Hidden; } else { XmlElementAttribute xea = (XmlElementAttribute)field.GetCustomAttribute(typeof(XmlElementAttribute)); if (xea != null) { if (!String.IsNullOrEmpty(xea.ElementName)) { docAttr.XsdFormat = DocXsdFormatEnum.Element; } else { docAttr.XsdFormat = DocXsdFormatEnum.Attribute; } } } } foreach (DocAttribute docAttr in attrsDirect.Values) { docEntity.Attributes.Add(docAttr); } foreach (DocAttribute docAttr in attrsInverse) { docEntity.Attributes.Add(docAttr); } // get derived attributes based on properties PropertyInfo[] props = t.GetProperties(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public); foreach (PropertyInfo prop in props) { // if no backing field, then derived FieldInfo field = t.GetField("_" + prop.Name, BindingFlags.NonPublic | BindingFlags.Instance); if (field == null) { DocAttribute docDerived = new DocAttribute(); docDerived.Name = prop.Name; docEntity.Attributes.Add(docDerived); } } } if (docDef != null) { docDef.Name = t.Name; docDef.Uuid = t.GUID; } docSchema.SortTypes(); docSchema.SortEntities(); } // pass 2: hook up selects foreach (Type t in assem.GetTypes()) { Type[] typeInterfaces = t.GetInterfaces(); if (typeInterfaces.Length > 0) { foreach (Type typeI in typeInterfaces) { DocSelect docSelect = project.GetDefinition(typeI.Name) as DocSelect; if (docSelect != null) { DocSelectItem docItem = new DocSelectItem(); docItem.Name = t.Name; docSelect.Selects.Add(docItem); } } } } // EXPRESS rules (eventually in C#, though .exp file snippets for now) en = System.IO.Directory.EnumerateFiles(pathSchema, "*.exp", System.IO.SearchOption.AllDirectories); foreach (string file in en) { string name = Path.GetFileNameWithoutExtension(file); string expr = null; using (StreamReader readExpr = new StreamReader(file, Encoding.UTF8)) { expr = readExpr.ReadToEnd(); } if (name.Contains('-')) { // where rule string[] parts = name.Split('-'); if (parts.Length == 2) { DocWhereRule docWhere = new DocWhereRule(); docWhere.Name = parts[1]; docWhere.Expression = expr; DocDefinition docDef = project.GetDefinition(parts[0]); if (docDef is DocEntity) { DocEntity docEnt = (DocEntity)docDef; docEnt.WhereRules.Add(docWhere); } else if (docDef is DocDefined) { DocDefined docEnt = (DocDefined)docDef; docEnt.WhereRules.Add(docWhere); } else if (docDef == null) { //... global rule... } } } else { // function string schema = Path.GetDirectoryName(file); schema = Path.GetDirectoryName(schema); schema = Path.GetFileName(schema); DocSchema docSchema = project.GetSchema(schema); if (docSchema != null) { DocFunction docFunction = new DocFunction(); docSchema.Functions.Add(docFunction); docFunction.Name = name; docFunction.Expression = expr; } } } // now, hook up html documentation en = System.IO.Directory.EnumerateFiles(pathSchema, "*.htm", System.IO.SearchOption.AllDirectories); foreach (string file in en) { string name = Path.GetFileNameWithoutExtension(file); DocObject docObj = null; if (name == "schema") { string schema = Path.GetDirectoryName(file); schema = Path.GetFileName(schema); docObj = project.GetSchema(schema); } else if (name.Contains('-')) { // where rule string[] parts = name.Split('-'); if (parts.Length == 2) { DocDefinition docDef = project.GetDefinition(parts[0]); if (docDef is DocEntity) { DocEntity docEnt = (DocEntity)docDef; foreach (DocWhereRule docWhereRule in docEnt.WhereRules) { if (docWhereRule.Name.Equals(parts[1])) { docObj = docWhereRule; break; } } } else if (docDef is DocDefined) { DocDefined docEnt = (DocDefined)docDef; foreach (DocWhereRule docWhereRule in docEnt.WhereRules) { if (docWhereRule.Name.Equals(parts[1])) { docObj = docWhereRule; break; } } } } } else { docObj = project.GetDefinition(name); if (docObj == null) { docObj = project.GetFunction(name); } } if (docObj != null) { using (StreamReader readHtml = new StreamReader(file, Encoding.UTF8)) { docObj.Documentation = readHtml.ReadToEnd(); } } } // load schema diagrams en = System.IO.Directory.EnumerateFiles(pathSchema, "*.svg", System.IO.SearchOption.AllDirectories); foreach (string file in en) { string schema = Path.GetDirectoryName(file); schema = Path.GetFileName(schema); DocSchema docSchema = project.GetSchema(schema); if (docSchema != null) { using (IfcDoc.Schema.SVG.SchemaSVG schemaSVG = new IfcDoc.Schema.SVG.SchemaSVG(file, docSchema, project)) { schemaSVG.Load(); } } } // psets, qsets //... // exchanges en = System.IO.Directory.EnumerateFiles(path, "*.mvdxml", System.IO.SearchOption.AllDirectories); foreach (string file in en) { IfcDoc.Schema.MVD.SchemaMVD.Load(project, file); } // examples string pathExamples = path + @"\examples"; if (Directory.Exists(pathExamples)) { en = System.IO.Directory.EnumerateFiles(pathExamples, "*.htm", SearchOption.TopDirectoryOnly); foreach (string file in en) { DocExample docExample = new DocExample(); docExample.Name = Path.GetFileNameWithoutExtension(file); project.Examples.Add(docExample); using (StreamReader reader = new StreamReader(file)) { docExample.Documentation = reader.ReadToEnd(); } string dirpath = file.Substring(0, file.Length - 4); if (Directory.Exists(dirpath)) { IEnumerable <string> suben = System.IO.Directory.EnumerateFiles(dirpath, "*.ifc", SearchOption.TopDirectoryOnly); foreach (string ex in suben) { DocExample docEx = new DocExample(); docEx.Name = Path.GetFileNameWithoutExtension(ex); docExample.Examples.Add(docEx); // read the content of the file using (FileStream fs = new FileStream(ex, FileMode.Open, FileAccess.Read)) { docEx.File = new byte[fs.Length]; fs.Read(docEx.File, 0, docEx.File.Length); } // read documentation string exdoc = ex.Substring(0, ex.Length - 4) + ".htm"; if (File.Exists(exdoc)) { using (StreamReader reader = new StreamReader(exdoc)) { docEx.Documentation = reader.ReadToEnd(); } } } } } } // localization en = System.IO.Directory.EnumerateFiles(path, "*.txt", System.IO.SearchOption.AllDirectories); foreach (string file in en) { using (FormatCSV format = new FormatCSV(file)) { try { format.Instance = project; format.Load(); } catch { } } } }