/// <summary> /// Creates or returns emitted type, or NULL if no such type. /// </summary> /// <param name="map"></param> /// <param name="typename"></param> /// <returns></returns> public Type RegisterType(string strtype) { // this implementation maps direct and inverse attributes to fields for brevity; a production implementation would use properties as well if (strtype == null) { return(typeof(SEntity)); } Type type = null; // resolve standard types switch (strtype) { case "INTEGER": type = typeof(long); break; case "REAL": case "NUMBER": type = typeof(double); break; case "BOOLEAN": case "LOGICAL": type = typeof(bool); break; case "STRING": type = typeof(string); break; case "BINARY": case "BINARY (32)": type = typeof(byte[]); break; } if (type != null) { return(type); } // check for existing mapped type if (this.m_types.TryGetValue(strtype, out type)) { return(type); } // look up DocObject docType = null; if (!this.m_definitions.TryGetValue(strtype, out docType)) { return(null); } string schema = this.m_namespaces[docType.Name]; // not yet exist: create it TypeAttributes attr = TypeAttributes.Public; if (docType is DocEntity) { attr |= TypeAttributes.Class; DocEntity docEntity = (DocEntity)docType; if (docEntity.IsAbstract()) { attr |= TypeAttributes.Abstract; } Type typebase = RegisterType(docEntity.BaseDefinition); // calling base class may result in this class getting defined (IFC2x3 schema with IfcBuildingElement), so check again if (this.m_types.TryGetValue(strtype, out type)) { return(type); } TypeBuilder tb = this.m_module.DefineType(schema + "." + docType.Name, attr, typebase); // add typebuilder to map temporarily in case referenced by an attribute within same class or base class this.m_types.Add(strtype, tb); // custom attributes (required for JSON serialization) ConstructorInfo conContract = (typeof(DataContractAttribute).GetConstructor(new Type[] { })); PropertyInfo propContractReference = typeof(DataContractAttribute).GetProperty("IsReference"); CustomAttributeBuilder cbContract = new CustomAttributeBuilder(conContract, new object[] { }, new PropertyInfo[] { propContractReference }, new object[] { false }); // consider setting IsReference to true if/when serializers like JSON support such referencing tb.SetCustomAttribute(cbContract); // interfaces implemented by type (SELECTS) foreach (DocDefinition docdef in this.m_definitions.Values) { if (docdef is DocSelect) { DocSelect docsel = (DocSelect)docdef; foreach (DocSelectItem dsi in docsel.Selects) { if (strtype.Equals(dsi.Name)) { // register Type typeinterface = this.RegisterType(docdef.Name); tb.AddInterfaceImplementation(typeinterface); } } } } Dictionary <string, FieldInfo> mapField = new Dictionary <string, FieldInfo>(); this.m_fields.Add(tb, mapField); ConstructorInfo conMember = typeof(DataMemberAttribute).GetConstructor(new Type[] { /*typeof(int)*/ }); ConstructorInfo conLookup = typeof(DataLookupAttribute).GetConstructor(new Type[] { typeof(string) }); PropertyInfo propMemberOrder = typeof(DataMemberAttribute).GetProperty("Order"); int order = 0; foreach (DocAttribute docAttribute in docEntity.Attributes) { // exclude derived attributes if (String.IsNullOrEmpty(docAttribute.Derived)) { Type typefield = RegisterType(docAttribute.DefinedType); if (typefield == null) { typefield = typeof(object); // excluded from scope } if (docAttribute.AggregationType != 0) { if (docAttribute.AggregationAttribute != null) { // nested collection, e.g. IfcCartesianPointList3D typefield = typeof(List <>).MakeGenericType(new Type[] { typefield }); } typefield = typeof(List <>).MakeGenericType(new Type[] { typefield }); } else if (typefield.IsValueType && docAttribute.IsOptional) { typefield = typeof(Nullable <>).MakeGenericType(new Type[] { typefield }); } FieldBuilder fb = tb.DefineField(docAttribute.Name, typefield, FieldAttributes.Public); // public for now mapField.Add(docAttribute.Name, fb); if (String.IsNullOrEmpty(docAttribute.Inverse)) { // direct attributes are fields marked for serialization //CustomAttributeBuilder cb = new CustomAttributeBuilder(conMember, new object[] { order }); CustomAttributeBuilder cb = new CustomAttributeBuilder(conMember, new object[] {}, new PropertyInfo[] { propMemberOrder }, new object[] { order }); fb.SetCustomAttribute(cb); order++; } else { // inverse attributes are fields marked for lookup CustomAttributeBuilder cb = new CustomAttributeBuilder(conLookup, new object[] { docAttribute.Inverse }); fb.SetCustomAttribute(cb); } } } // remove from typebuilder this.m_types.Remove(strtype); type = tb; // avoid circular conditions -- generate type afterwords } else if (docType is DocSelect) { attr |= TypeAttributes.Interface | TypeAttributes.Abstract; TypeBuilder tb = this.m_module.DefineType(schema + "." + docType.Name, attr); // interfaces implemented by type (SELECTS) foreach (DocDefinition docdef in this.m_definitions.Values) { if (docdef is DocSelect) { DocSelect docsel = (DocSelect)docdef; foreach (DocSelectItem dsi in docsel.Selects) { if (strtype.Equals(dsi.Name)) { // register Type typeinterface = this.RegisterType(docdef.Name); tb.AddInterfaceImplementation(typeinterface); } } } } type = tb.CreateType(); } else if (docType is DocEnumeration) { DocEnumeration docEnum = (DocEnumeration)docType; EnumBuilder eb = this.m_module.DefineEnum(schema + "." + docType.Name, TypeAttributes.Public, typeof(int)); for (int i = 0; i < docEnum.Constants.Count; i++) { DocConstant docConst = docEnum.Constants[i]; eb.DefineLiteral(docConst.Name, (int)i); } type = eb.CreateType(); } else if (docType is DocDefined) { DocDefined docDef = (DocDefined)docType; attr |= TypeAttributes.Sealed; if (docDef.DefinedType == docDef.Name) { return(null); } TypeBuilder tb = this.m_module.DefineType(schema + "." + docType.Name, attr, typeof(ValueType)); // interfaces implemented by type (SELECTS) foreach (DocDefinition docdef in this.m_definitions.Values) { if (docdef is DocSelect) { DocSelect docsel = (DocSelect)docdef; foreach (DocSelectItem dsi in docsel.Selects) { if (strtype.Equals(dsi.Name)) { // register Type typeinterface = RegisterType(docdef.Name); tb.AddInterfaceImplementation(typeinterface); } } } } Type typeliteral = RegisterType(docDef.DefinedType); if (typeliteral != null) { if (docDef.Aggregation != null && docDef.Aggregation.AggregationType != 0) { typeliteral = typeof(List <>).MakeGenericType(new Type[] { typeliteral }); } else { FieldInfo fieldval = typeliteral.GetField("Value"); while (fieldval != null) { typeliteral = fieldval.FieldType; fieldval = typeliteral.GetField("Value"); } } FieldBuilder fieldValue = tb.DefineField("Value", typeliteral, FieldAttributes.Public); type = tb.CreateType(); Dictionary <string, FieldInfo> mapField = new Dictionary <string, FieldInfo>(); mapField.Add("Value", fieldValue); this.m_fields.Add(type, mapField); } } this.m_types.Add(strtype, type); return(type); }
public static string FormatEntity(DocEntity docEntity, Dictionary <string, DocObject> map, Dictionary <DocObject, bool> included) { string basetype = docEntity.BaseDefinition; if (String.IsNullOrEmpty(basetype)) { basetype = "Entity"; } StringBuilder sb = new StringBuilder(); // if any derived attributes, then must use intermediate type bool hasderivedattributes = false; foreach (DocAttribute docAttr in docEntity.Attributes) { if (docAttr.Derived != null && docAttr.Inverse == null) { // determine the superclass having the attribute DocEntity found = null; DocEntity super = docEntity; while (super != null && found == null && super.BaseDefinition != null) { super = map[super.BaseDefinition] as DocEntity; if (super != null) { foreach (DocAttribute docattrSuper in super.Attributes) { if (docattrSuper.Name.Equals(docAttr.Name)) { // found class found = super; break; } } } } if (found != null) { hasderivedattributes = true; } break; } } if (hasderivedattributes) { sb.Append("\t<xs:complexType name=\""); sb.Append(docEntity.Name); sb.Append("-temp\" abstract=\"true\">"); sb.AppendLine(); sb.Append("\t\t<xs:complexContent>"); sb.AppendLine(); sb.Append("\t\t\t<xs:restriction base=\"ifc:"); sb.Append(docEntity.BaseDefinition); sb.Append("\">"); sb.AppendLine(); // restate non-derived attributes at superclass, if any List <DocAttribute> listRestate = new List <DocAttribute>(); DocEntity docSuper = map[docEntity.BaseDefinition] as DocEntity; foreach (DocAttribute docAttrSuper in docSuper.Attributes) { // check if attribute not derived by us bool derived = false; foreach (DocAttribute docAttrThis in docEntity.Attributes) { if (docAttrSuper.Name.Equals(docAttrThis.Name)) { derived = true; break; } } if (!derived) { DocObject mapDef = null; if ((docAttrSuper.Inverse == null /* || docAttrSuper.XsdFormat == DocXsdFormatEnum.Element || docAttrSuper.XsdFormat == DocXsdFormatEnum.Attribute*/) && docAttrSuper.Derived == null && (map.TryGetValue(docAttrSuper.DefinedType, out mapDef) || docAttrSuper.DefinedType.StartsWith("BINARY"))) { if (mapDef is DocEntity || mapDef is DocSelect) { listRestate.Add(docAttrSuper); } } } } if (listRestate.Count > 0) { sb.AppendLine("\t\t\t\t<xs:sequence>"); foreach (DocAttribute docAttr in listRestate) { string formatAttr = FormatAttribute(docEntity, docAttr, map); sb.Append(formatAttr); } sb.Append("\t\t\t\t</xs:sequence>"); } else { sb.Append("\t\t\t\t<xs:sequence/>"); } sb.AppendLine(); sb.Append("\t\t\t</xs:restriction>"); sb.AppendLine(); sb.Append("\t\t</xs:complexContent>"); sb.AppendLine(); sb.Append("\t</xs:complexType>"); sb.AppendLine(); } sb.Append("\t<xs:element"); sb.Append(" name=\""); sb.Append(docEntity.Name); sb.Append("\" type=\"ifc:"); sb.Append(docEntity.Name); sb.Append("\""); if (docEntity.IsAbstract()) { sb.Append(" abstract=\"true\""); } sb.Append(" substitutionGroup=\"ifc:"); sb.Append(basetype); sb.Append("\" nillable=\"true\""); sb.Append("/>"); sb.AppendLine(); sb.Append("\t<xs:complexType name=\""); sb.Append(docEntity.Name); sb.Append("\""); if (docEntity.IsAbstract()) { sb.Append(" abstract=\"true\""); } sb.Append(">"); sb.AppendLine(); sb.Append("\t\t<xs:complexContent>"); sb.AppendLine(); sb.Append("\t\t\t<xs:extension base=\"ifc:"); if (hasderivedattributes) { sb.Append(docEntity.Name); sb.Append("-temp"); } else { sb.Append(basetype); } sb.Append("\""); bool hascontent = false; // attributes for entities bool hassequence = false; foreach (DocAttribute docAttr in docEntity.Attributes) { if (included == null || included.ContainsKey(docAttr)) { if (docAttr.XsdFormat != DocXsdFormatEnum.Hidden && !(docAttr.XsdTagless == true) && docAttr.DefinedType != null) { DocObject mapDef = null; map.TryGetValue(docAttr.DefinedType, out mapDef); if ((docAttr.Inverse == null || docAttr.XsdFormat == DocXsdFormatEnum.Element || docAttr.XsdFormat == DocXsdFormatEnum.Attribute) && docAttr.Derived == null) { if (mapDef is DocEntity || mapDef is DocSelect || docAttr.XsdFormat == DocXsdFormatEnum.Element || docAttr.DefinedType.StartsWith("BINARY")) { if (!hascontent) { sb.Append(">"); sb.AppendLine(); hascontent = true; } if (!hassequence) { sb.AppendLine("\t\t\t\t<xs:sequence>"); hassequence = true; } string formatAttr = FormatAttribute(docEntity, docAttr, map); sb.Append(formatAttr); } } } } } if (hassequence) { sb.AppendLine("\t\t\t\t</xs:sequence>"); } // then attributes for value types foreach (DocAttribute docAttr in docEntity.Attributes) { if (included == null || included.ContainsKey(docAttr)) { if (docAttr.XsdFormat != DocXsdFormatEnum.Hidden && docAttr.DefinedType != null)// && docAttr.XsdFormat != DocXsdFormatEnum.Element*/) { DocObject mapDef = null; if ((docAttr.Inverse == null || docAttr.XsdFormat == DocXsdFormatEnum.Attribute) && docAttr.Derived == null && (docAttr.XsdFormat != DocXsdFormatEnum.Element || docAttr.XsdTagless == true)) { if ((map.TryGetValue(docAttr.DefinedType, out mapDef) == false && !docAttr.DefinedType.StartsWith("BINARY")) || (mapDef is DocDefined || mapDef is DocEnumeration || docAttr.XsdTagless == true /* || docAttr.XsdFormat == DocXsdFormatEnum.Attribute*/)) { if (mapDef == null || (included == null || included.ContainsKey(mapDef))) { if (!hascontent) { sb.Append(">"); sb.AppendLine(); hascontent = true; } // encode value types as attributes sb.Append("\t\t\t\t<xs:attribute"); sb.Append(" name=\""); sb.Append(docAttr.Name); sb.Append("\""); if (docAttr.AggregationType == 0) { sb.Append(" type=\""); if (mapDef is DocDefined && ((DocDefined)mapDef).Aggregation != null) { sb.Append("ifc:List-" + docAttr.DefinedType); } else { sb.Append(ToXsdType(docAttr.DefinedType)); } sb.Append("\""); if (true) // all attributes optional in XSD? docAttr.IsOptional()) { sb.Append(" use=\"optional\""); } sb.Append("/>"); } else { if (true) // all attributes optional in XSD? docAttr.IsOptional()) { sb.Append(" use=\"optional\""); } sb.Append(">"); sb.AppendLine(); sb.AppendLine("\t\t\t\t\t<xs:simpleType>"); sb.AppendLine("\t\t\t\t\t\t<xs:restriction>"); sb.AppendLine("\t\t\t\t\t\t\t<xs:simpleType>"); sb.Append("\t\t\t\t\t\t\t\t<xs:list itemType=\""); sb.Append(ToXsdType(docAttr.DefinedType)); sb.Append("\"/>"); sb.AppendLine(); sb.AppendLine("\t\t\t\t\t\t\t</xs:simpleType>"); if (docAttr.Name.Equals("OffsetValues")) { sb.ToString(); } int iLower = docAttr.GetAggregationNestingLower(); int iUpper = docAttr.GetAggregationNestingUpper(); // minimum if (docAttr.GetAggregation() == DocAggregationEnum.ARRAY) { iLower = iUpper; } if (iLower != -1 && iLower != 1) { sb.Append("\t\t\t\t\t\t\t<xs:minLength value=\""); sb.Append(iLower); sb.Append("\"/>"); sb.AppendLine(); } if (iUpper != 0) { sb.Append("\t\t\t\t\t\t\t<xs:maxLength value=\""); sb.Append(iUpper); sb.Append("\"/>"); sb.AppendLine(); } sb.AppendLine("\t\t\t\t\t\t</xs:restriction>"); sb.AppendLine("\t\t\t\t\t</xs:simpleType>"); sb.Append("\t\t\t\t</xs:attribute>"); } sb.AppendLine(); } } } } } } if (hascontent) { sb.Append("\t\t\t</xs:extension>"); sb.AppendLine(); } else { sb.Append("/>"); sb.AppendLine(); } sb.Append("\t\t</xs:complexContent>"); sb.AppendLine(); sb.Append("\t</xs:complexType>"); sb.AppendLine(); return(sb.ToString()); }
public string FormatEntity(DocEntity docEntity, Dictionary <string, DocObject> map, Dictionary <DocObject, bool> included) { StringBuilder sb = new StringBuilder(); string basedef = docEntity.BaseDefinition; if (String.IsNullOrEmpty(basedef)) { basedef = "IfcBase"; } sb.Append("public partial "); if (docEntity.IsAbstract()) { sb.Append("abstract "); } sb.AppendLine("class " + docEntity.Name + " : " + basedef); sb.AppendLine("{"); // fields int order = 0; foreach (DocAttribute docAttribute in docEntity.Attributes) { bool inscope = false; if (included != null) { included.TryGetValue(docAttribute, out inscope); } else { inscope = true; } if (docAttribute.Inverse == null) { sb.Append("\t[DataMember(Order=" + order + ")] "); order++; } else if (inscope) { sb.Append("\t[DataLookup(\"" + docAttribute.Inverse + "\")] "); } if (docAttribute.Inverse == null || inscope) { DocObject docRef = null; if (docAttribute.DefinedType != null) { map.TryGetValue(docAttribute.DefinedType, out docRef); } string optional = ""; if (docAttribute.IsOptional && (docRef == null || docRef is DocDefined)) { optional = "?"; } switch (docAttribute.GetAggregation()) { case DocAggregationEnum.SET: sb.AppendLine("ISet<" + docAttribute.DefinedType + "> _" + docAttribute.Name + ";"); break; case DocAggregationEnum.LIST: sb.AppendLine("IList<" + docAttribute.DefinedType + "> _" + docAttribute.Name + ";"); break; default: sb.AppendLine(docAttribute.DefinedType + optional + " _" + docAttribute.Name + ";"); break; } } } #if false // make an option... // constructor sb.AppendLine(); sb.AppendLine("\tpublic " + docEntity.Name + "()"); sb.AppendLine("\t{"); //... values... sb.AppendLine("\t}"); #endif // properties #if false // make an option... foreach (DocAttribute docAttribute in docEntity.Attributes) { sb.AppendLine(); switch (docAttribute.GetAggregation()) { case DocAggregationEnum.SET: sb.AppendLine("\tpublic ICollection<" + docAttribute.DefinedType + "> " + docAttribute.Name); break; case DocAggregationEnum.LIST: sb.AppendLine("\tpublic IList<" + docAttribute.DefinedType + "> " + docAttribute.Name); break; default: sb.AppendLine("\tpublic " + docAttribute.DefinedType + " " + docAttribute.Name); break; } sb.AppendLine("\t\t{"); sb.AppendLine("\t\tget"); sb.AppendLine("\t\t{"); sb.AppendLine("\t\t\treturn this._" + docAttribute.Name + ";"); sb.AppendLine("\t\t}"); if (docAttribute.GetAggregation() == DocAggregationEnum.NONE) { sb.AppendLine("\t\tset"); sb.AppendLine("\t\t{"); sb.AppendLine("\t\t\tthis.OnBeforePropertyChange(\"" + docAttribute.Name + "\");"); sb.AppendLine("\t\t\tthis._" + docAttribute.Name + " = value;"); sb.AppendLine("\t\t\tthis.OnAfterPropertyChange(\"" + docAttribute.Name + "\");"); sb.AppendLine("\t\t}"); } sb.AppendLine("\t}"); } #endif #if false // make an option... // serialization writer.WriteLine(); writer.WriteLine("\t\tprivate void GetObjectData(SerializationInfo info, StreamingContext context)"); writer.WriteLine("\t\t{"); foreach (DocAttribute docAttribute in docEntity.Attributes) { if (docAttribute.Inverse == null && docAttribute.Derived == null) { writer.WriteLine("\t\t\tinfo.AddValue(\"" + docAttribute.Name + "\", this._" + docAttribute.Name + ");"); } } writer.WriteLine("\t\t}"); writer.WriteLine(); writer.WriteLine("\t\tprivate void SetObjectData(SerializationInfo info, StreamingContext context)"); writer.WriteLine("\t\t{"); foreach (DocAttribute docAttribute in docEntity.Attributes) { if (docAttribute.Inverse == null && docAttribute.Derived == null) { string method = "GetValue"; writer.WriteLine("\t\t\tthis._" + docAttribute.Name + " = info." + method + "(\"" + docAttribute.Name + "\");"); } } writer.WriteLine("\t\t}"); #endif sb.AppendLine("}"); return(sb.ToString()); }
public string FormatEntityFull(DocEntity docEntity, Dictionary<string, DocObject> map, Dictionary<DocObject, bool> included, bool fullListing) { // entity StringBuilder sb = new StringBuilder(); // object properties StringBuilder sbProps = new StringBuilder(); // lists StringBuilder sbLists = new StringBuilder(); sb.AppendLine("ifc:" + docEntity.Name); // superclass if (docEntity.BaseDefinition != null) { DocEntity super = map[docEntity.BaseDefinition] as DocEntity; if (super != null) { sb.AppendLine("\trdfs:subClassOf \tifc:" + super.Name + " ;"); // disjoint if (subTypesOfEntity.ContainsKey(super.Name)) { string tmp = ""; foreach (string subtype in subTypesOfEntity[super.Name]) { if (subtype != docEntity.Name) { if (tmp.Length > 0) tmp += ", "; tmp += ToOwlClass(subtype) + " "; } } if (tmp.Length > 0) sb.AppendLine("\towl:disjointWith " + tmp + ";"); } } } // abstract class if (docEntity.IsAbstract()) { sb.AppendLine("\trdfs:subClassOf "); sb.AppendLine("\t\t[ "); sb.AppendLine("\t\t\trdf:type owl:Class ;"); sb.Append("\t\t\towl:unionOf ( "); if (subTypesOfEntity.ContainsKey(docEntity.Name)) { foreach (string subtype in subTypesOfEntity[docEntity.Name]) { sb.Append(ToOwlClass(subtype) + " "); } } sb.Append(")"); sb.AppendLine(); sb.AppendLine("\t\t] ;"); } // attributes -> create properties and restrictions foreach (DocAttribute docAttr in docEntity.Attributes) { // check if Attr must be skipped (1) - not included attribute if (included != null) if (!included.ContainsKey(docAttr)) continue; string propname = ""; string propfullname = ""; string invpropname = ""; string invpropfullname = ""; string targetString = docAttr.DefinedType; DocEntity targetEntity = null; if (map.ContainsKey(targetString)) { targetEntity = map[targetString] as DocEntity; } // check if Attr must be skipped (2) - DERIVE attribute if (docAttr.Derived != null) continue; // check if Attr must be skipped (3) - not manageable INVERSE attribute invpropname = docAttr.Inverse; if (invpropname != null) { // check if there are problems with inverse and in this case skip the attribute! // 1) the inverse is an inverse of two or more properties // 2) a list/array is involved as range in the property or its inverse // 1) var key = new Tuple<string, string>(docAttr.Inverse, targetString); if (attribInverses.ContainsKey(key)) if (attribInverses[key] > 1) continue; // 2.a) if (docAttr.GetAggregation() == DocAggregationEnum.LIST || docAttr.GetAggregation() == DocAggregationEnum.ARRAY) continue; // 2.b) if (targetEntity != null) { bool toBeSkipped = false; foreach (DocAttribute docAttrInv in targetEntity.Attributes) { if (docAttrInv.Name == invpropname) if (docAttrInv.GetAggregation() == DocAggregationEnum.LIST || docAttrInv.GetAggregation() == DocAggregationEnum.ARRAY) { toBeSkipped = true; break; } } if (toBeSkipped) continue; } } // set actual target string actualTargetString = ToOwlClass(targetString); if (docAttr.GetAggregation() == DocAggregationEnum.LIST || docAttr.GetAggregation() == DocAggregationEnum.ARRAY) { string newlistdef = createListClass(actualTargetString); actualTargetString = actualTargetString + "_List"; if (newlistdef.Length > 0) sbLists.Append(newlistdef); DocAttribute docAggregate = docAttr.AggregationAttribute; while (docAggregate != null) { newlistdef = createListClass(actualTargetString); actualTargetString = actualTargetString + "_List"; if (newlistdef.Length > 0) sbLists.Append(newlistdef); docAggregate = docAggregate.AggregationAttribute; } } // create property propname = docAttr.Name; propfullname = propname + "_" + docEntity.Name; if (propfullname.Length > 0) propfullname = char.ToLower(propfullname[0]) + propfullname.Substring(1); propfullname = "ifc:" + propfullname; sbProps.AppendLine(propfullname); sbProps.Append("\trdf:type \towl:ObjectProperty "); // functional if (docAttr.GetAggregation() == DocAggregationEnum.NONE || docAttr.GetAggregation() == DocAggregationEnum.LIST || docAttr.GetAggregation() == DocAggregationEnum.ARRAY || (docAttr.GetAggregation() == DocAggregationEnum.SET && docAttr.GetAggregationNestingUpper() == 1)) { sbProps.Append(", owl:FunctionalProperty "); } sbProps.Append(";"); sbProps.AppendLine(); // inverse if (invpropname != null && targetEntity != null) { invpropfullname = invpropname + "_" + targetEntity.Name; if (invpropfullname.Length > 0) invpropfullname = char.ToLower(invpropfullname[0]) + invpropfullname.Substring(1); invpropfullname = "ifc:" + invpropfullname; sbProps.AppendLine("\towl:inverseOf \t" + invpropfullname + " ;"); } // domain sbProps.AppendLine("\trdfs:domain " + ToOwlClass(docEntity.Name) + " ;"); // range sbProps.AppendLine("\trdfs:range " + actualTargetString + " ;"); // label sbProps.AppendLine("\trdfs:label \"" + propname + "\" ."); sbProps.AppendLine(); // create restrictions { // only sb.AppendLine("\trdfs:subClassOf "); sb.AppendLine("\t\t[ "); sb.AppendLine("\t\t\trdf:type owl:Restriction ;"); sb.AppendLine("\t\t\towl:allValuesFrom " + actualTargetString + " ;"); sb.AppendLine("\t\t\towl:onProperty " + propfullname); sb.AppendLine("\t\t] ;"); if (docAttr.GetAggregation() == DocAggregationEnum.NONE || docAttr.GetAggregation() == DocAggregationEnum.LIST || docAttr.GetAggregation() == DocAggregationEnum.ARRAY) { sb.AppendLine("\t" + "rdfs:subClassOf "); sb.AppendLine("\t\t" + "["); sb.AppendLine("\t\t\t" + "rdf:type owl:Restriction ;"); if (docAttr.IsOptional) sb.AppendLine("\t\t\t" + "owl:maxQualifiedCardinality \"" + 1 + "\"^^xsd:nonNegativeInteger ;"); else sb.AppendLine("\t\t\t" + "owl:qualifiedCardinality \"" + 1 + "\"^^xsd:nonNegativeInteger ;"); sb.AppendLine("\t\t\towl:onProperty " + propfullname + " ;"); sb.AppendLine("\t\t\t" + "owl:onClass " + actualTargetString); sb.AppendLine("\t\t] ;"); } if (docAttr.GetAggregation() == DocAggregationEnum.SET) { int mincard = 0; if (docAttr.AggregationLower != null) mincard = Int32.Parse(docAttr.AggregationLower); int maxcard = 0; if (String.IsNullOrEmpty(docAttr.AggregationUpper) || !Int32.TryParse(docAttr.AggregationUpper, out maxcard)) maxcard = 0; if (docAttr.IsOptional) mincard = 0; if (mincard == maxcard && mincard > 0) { sb.AppendLine("\t" + "rdfs:subClassOf "); sb.AppendLine("\t\t" + "["); sb.AppendLine("\t\t\t" + "rdf:type owl:Restriction ;"); sb.AppendLine("\t\t\t" + "owl:qualifiedCardinality \"" + mincard + "\"^^xsd:nonNegativeInteger ;"); sb.AppendLine("\t\t\towl:onProperty " + propfullname + " ;"); sb.AppendLine("\t\t\t" + "owl:onClass " + actualTargetString); sb.AppendLine("\t\t] ;"); } else { if (mincard > 0) { sb.AppendLine("\t" + "rdfs:subClassOf "); sb.AppendLine("\t\t" + "["); sb.AppendLine("\t\t\t" + "rdf:type owl:Restriction ;"); sb.AppendLine("\t\t\t" + "owl:minQualifiedCardinality \"" + mincard + "\"^^xsd:nonNegativeInteger ;"); sb.AppendLine("\t\t\towl:onProperty " + propfullname + " ;"); sb.AppendLine("\t\t\t" + "owl:onClass " + actualTargetString); sb.AppendLine("\t\t] ;"); } if (maxcard > 0) { sb.AppendLine("\t" + "rdfs:subClassOf "); sb.AppendLine("\t\t" + "["); sb.AppendLine("\t\t\t" + "rdf:type owl:Restriction ;"); sb.AppendLine("\t\t\t" + "owl:maxQualifiedCardinality \"" + maxcard + "\"^^xsd:nonNegativeInteger ;"); sb.AppendLine("\t\t\towl:onProperty " + propfullname + " ;"); sb.AppendLine("\t\t\t" + "owl:onClass " + actualTargetString); sb.AppendLine("\t\t] ;"); } } } if (docAttr.GetAggregation() == DocAggregationEnum.LIST || docAttr.GetAggregation() == DocAggregationEnum.ARRAY) { int mincard = 0; if (docAttr.AggregationLower != null) mincard = Int32.Parse(docAttr.AggregationLower); int maxcard = 0; if (String.IsNullOrEmpty(docAttr.AggregationUpper) || !Int32.TryParse(docAttr.AggregationUpper, out maxcard)) maxcard = 0; if (docAttr.GetAggregation() == DocAggregationEnum.ARRAY) { mincard = maxcard - mincard + 1; maxcard = mincard; } if (mincard >= 1) { string cards = ""; cards += WriteMinCardRestr(actualTargetString, propfullname, mincard, true); cards += " ;"; sb.AppendLine(cards); } if (maxcard > 1) { string cards = ""; string emptyListTgt = actualTargetString.Substring(0, actualTargetString.Length - 4) + "EmptyList"; cards += WriteMaxCardRestr(emptyListTgt, propfullname, maxcard, true); cards += " ;"; sb.AppendLine(cards); } } } } sb.AppendLine("\trdf:type \towl:Class ."); sb.AppendLine(); if (fullListing) { sb.Append(sbProps.ToString()); sb.Append(sbLists.ToString()); } return sb.ToString(); }
/// <summary> /// Draws entity and subtypes recursively to image /// </summary> /// <param name="g">Graphics where to draw; if null, then just return rectangle</param> /// <param name="pt">Point where to draw</param> /// <param name="docEntity">Entity to draw</param> /// <returns>Bounding rectangle of what was drawn.</returns> private static Rectangle DrawHierarchy(Graphics g, Point pt, DocEntity docEntity, DocEntity docTarget, DocProject docProject, Dictionary<DocObject, bool> included, Font font, Dictionary<Rectangle, DocEntity> map) { if (docEntity == null) return Rectangle.Empty; Rectangle rc = new Rectangle(pt.X, pt.Y, CX, CY); Point ptSub = new Point(pt.X + CY, pt.Y + CY + CY); SortedList<string, DocEntity> subtypes = new SortedList<string, DocEntity>(); // sort to match Visual Express foreach(DocSection docSection in docProject.Sections) { foreach (DocSchema docSchema in docSection.Schemas) { foreach(DocEntity docEnt in docSchema.Entities) { if (included == null || included.ContainsKey(docEnt)) { if (docEnt.BaseDefinition != null && docEnt.BaseDefinition.Equals(docEntity.Name)) { subtypes.Add(docEnt.Name, docEnt); } } } } } foreach(string s in subtypes.Keys) { DocEntity docEnt = subtypes[s];//docProject.GetDefinition(docSub.DefinedType) as DocEntity; if(docEnt != null) { bool vert = (docEnt.Status != "H");//hack Rectangle rcSub = DrawHierarchy(g, ptSub, docEnt, docTarget, docProject, included, font, map); if (g != null) { g.DrawLine(Pens.Black, rcSub.X - CY, pt.Y + CY, rcSub.X - CY, rcSub.Y + CY / 2); g.DrawLine(Pens.Black, rcSub.X - CY, rcSub.Y + CY / 2, rcSub.X, rcSub.Y + CY / 2); } if (vert) { ptSub.Y += rcSub.Height + CY; } else { ptSub.Y = pt.Y + CY + CY; ptSub.X += rcSub.Width + CY + CY + CY + CY + CY; } if (rc.Height < (rcSub.Y + rcSub.Height) - rc.Y) { rc.Height = (rcSub.Y + rcSub.Height) - rc.Y; } if (rc.Width < (rcSub.X + rcSub.Width) - rc.X + CY) { rc.Width = (rcSub.X + rcSub.Width) - rc.X + CY; } } } if (g != null) { Brush brush = Brushes.Black; if(docEntity.IsAbstract()) { brush = Brushes.Gray; } if(docEntity == docTarget) { brush = Brushes.Blue; } g.FillRectangle(brush, pt.X, pt.Y, rc.Width - CY, CY); g.DrawString(docEntity.Name, font, Brushes.White, pt); g.DrawRectangle(Pens.Black, pt.X, pt.Y, rc.Width - CY, CY); } if(map != null && docEntity != docTarget) { Rectangle rcKey = new Rectangle(pt.X, pt.Y, rc.Width - CY, CY); if (!map.ContainsKey(rcKey)) { map.Add(rcKey, docEntity); } } return rc; }
/// <summary> /// Draws entity and recurses. /// </summary> /// <param name="g">Graphics device.</param> /// <param name="lane">Horizontal lane for which to draw the entity.</param> /// <param name="lanes">List of lanes left-to-right.</param> /// <param name="docEntity">The entity to draw.</param> /// <param name="docView">The model view for which to draw the entity.</param> /// <param name="docTemplate">The template to draw.</param> /// <param name="docRule">Optional rule for recursing.</param> /// <param name="map">Map of definitions.</param> /// <param name="layout">Optional layout to receive rectangles for building image map</param> /// <param name="docProject">Required project.</param> /// <param name="instance">Optional instance where included or missing attributes are highlighted.</param> private static void DrawEntity( Graphics g, int lane, List<int> lanes, DocEntity docEntity, DocModelView docView, DocTemplateDefinition docTemplate, DocModelRuleEntity docRule, Dictionary<string, DocObject> map, Dictionary<Rectangle, DocModelRule> layout, DocProject docProject, DocSchema docSchema, object instance) { List<DocAttribute> listAttr = new List<DocAttribute>(); BuildAttributeList(docEntity, listAttr, map); while(lanes.Count < lane + 1) { int miny = 0; if (lanes.Count > lane) { miny = lanes[lane]; } lanes.Add(miny); } int x = lane * CX + FormatPNG.Border; int y = lanes[lane] + FormatPNG.Border; if (g != null) { Brush brush = Brushes.Black; if (instance != null) { brush = Brushes.Red; if (instance is System.Collections.IList) { string typename = instance.GetType().Name; // keep going until matching instance System.Collections.IList list = (System.Collections.IList)instance; foreach (object member in list) { string membertypename = member.GetType().Name; DocEntity docType = docProject.GetDefinition(membertypename) as DocEntity; while (docType != null) { if (docType == docEntity) { brush = Brushes.Lime; instance = member; break; } docType = docProject.GetDefinition(docType.BaseDefinition) as DocEntity; } if (brush != Brushes.Red) break; } } else { string typename = instance.GetType().Name; DocEntity docType = docProject.GetDefinition(typename) as DocEntity; while (docType != null) { if (docType == docEntity) { brush = Brushes.Lime; break; } docType = docProject.GetDefinition(docType.BaseDefinition) as DocEntity; } } } else if (docEntity.IsAbstract()) { brush = Brushes.Gray; } else { brush = Brushes.Black; } g.FillRectangle(brush, x, y, CX - DX, CY); g.DrawRectangle(Pens.Black, x, y, CX - DX, CY); using (Font font = new Font(FontFamily.GenericSansSerif, 8.0f, FontStyle.Bold)) { g.DrawString(docEntity.Name, font, Brushes.White, x, y); } if (docRule != null && docRule.Identification == "Value") { // mark rule serving as default value g.FillEllipse(Brushes.Green, new Rectangle(x + CX - DX - CY, y, CY, CY)); } g.DrawRectangle(Pens.Black, x, y + CY, CX - DX, CY * listAttr.Count); using (Font font = new Font(FontFamily.GenericSansSerif, 8.0f, FontStyle.Regular)) { for (int iAttr = 0; iAttr < listAttr.Count; iAttr++) { DocAttribute docAttr = listAttr[iAttr]; string display = docAttr.GetAggregationExpression(); brush = Brushes.Black; if (docAttr.Inverse != null) { brush = Brushes.Gray; } if(String.IsNullOrEmpty(display)) { if(docAttr.IsOptional) { display = "[0:1]"; } else { display = "[1:1]"; } } g.DrawString(docAttr.Name, font, brush, x, y + CY * (iAttr + 1)); using (StringFormat fmt = new StringFormat()) { fmt.Alignment = StringAlignment.Far; g.DrawString(display, font, brush, new RectangleF(x, y + CY * (iAttr + 1), CX - DX, CY), fmt); } } } } // record rectangle if (layout != null) { layout.Add(new Rectangle(x, y, CX - DX, CY + CY * listAttr.Count), docRule); } SortedList<int, List<DocModelRuleAttribute>> mapAttribute = new SortedList<int, List<DocModelRuleAttribute>>(); Dictionary<DocModelRuleAttribute, DocTemplateDefinition> mapTemplate = new Dictionary<DocModelRuleAttribute,DocTemplateDefinition>(); if (docRule != null && docRule.Rules != null) { // map inner rules // sort foreach (DocModelRule rule in docRule.Rules) { if (rule is DocModelRuleAttribute) { DocModelRuleAttribute ruleAttribute = (DocModelRuleAttribute)rule; for (int i = 0; i < listAttr.Count; i++) { if (listAttr[i].Name.Equals(ruleAttribute.Name)) { // found it if (!mapAttribute.ContainsKey(i)) { mapAttribute.Add(i, new List<DocModelRuleAttribute>()); } mapAttribute[i].Add(ruleAttribute); break; } } } } } else if (docTemplate != null) { if (docTemplate.Rules != null) { foreach (DocModelRuleAttribute ruleAttribute in docTemplate.Rules) { for (int i = 0; i < listAttr.Count; i++) { if (listAttr[i].Name != null && listAttr[i].Name.Equals(ruleAttribute.Name)) { // found it //iAttr = i; if (!mapAttribute.ContainsKey(i)) { mapAttribute.Add(i, new List<DocModelRuleAttribute>()); } mapAttribute[i].Add(ruleAttribute); break; } } } } } else { // map each use definition at top-level // build list of inherited views List<DocModelView> listViews = new List<DocModelView>(); DocModelView docBaseView = docView; while (docBaseView != null) { listViews.Add(docBaseView); if (!String.IsNullOrEmpty(docBaseView.BaseView)) { Guid guidBase = Guid.Parse(docBaseView.BaseView); if (guidBase != docBaseView.Uuid) { docBaseView = docProject.GetView(guidBase); } else { docBaseView = null; } } else { docBaseView = null; } } // build from inherited entities too List<DocTemplateDefinition> listTemplates = new List<DocTemplateDefinition>(); // keep track of templates so we don't repeat at supertypes List<DocTemplateDefinition> listSuppress = new List<DocTemplateDefinition>(); // list of templates that are suppressed DocEntity docEntitySuper = docEntity; while(docEntitySuper != null) { foreach (DocModelView docEachView in docProject.ModelViews) { if (docView == null || listViews.Contains(docEachView)) { foreach (DocConceptRoot docRoot in docEachView.ConceptRoots) { if (docRoot.ApplicableEntity == docEntitySuper) { foreach (DocTemplateUsage docUsage in docRoot.Concepts) { if (docUsage.Definition != null && docUsage.Definition.Rules != null && !listTemplates.Contains(docUsage.Definition) && !listSuppress.Contains(docUsage.Definition)) { if (docUsage.Suppress) { listSuppress.Add(docUsage.Definition); } else { listTemplates.Add(docUsage.Definition); foreach (DocModelRuleAttribute ruleAttribute in docUsage.Definition.Rules) { for (int i = 0; i < listAttr.Count; i++) { if (listAttr[i].Name.Equals(ruleAttribute.Name)) { // found it if (!mapAttribute.ContainsKey(i)) { mapAttribute.Add(i, new List<DocModelRuleAttribute>()); } mapAttribute[i].Add(ruleAttribute); if (!mapTemplate.ContainsKey(ruleAttribute)) { mapTemplate.Add(ruleAttribute, docUsage.Definition); } break; } } } } } } } } } } DocObject docTest = null; if (docEntitySuper.BaseDefinition != null && map.TryGetValue(docEntitySuper.BaseDefinition, out docTest)) { docEntitySuper = docTest as DocEntity; } else { docEntitySuper = null; } } } int offset = -mapAttribute.Values.Count / 2; DocTemplateDefinition lastTemplate = null; foreach (List<DocModelRuleAttribute> listSort in mapAttribute.Values) { if (docRule == null && docTemplate == null) { // offset all lanes int maxlane = 0; for (int i = 1; i < lanes.Count; i++) { if (lanes[i] > maxlane) { maxlane = lanes[i]; } } for (int i = 1; i < lanes.Count; i++) { lanes[i] = maxlane; } } foreach (DocModelRuleAttribute ruleAttributeSort in listSort) { // indicate each template DocTemplateDefinition eachTemplate = null; if (mapTemplate.TryGetValue(ruleAttributeSort, out eachTemplate)) { // offset for use definition int minlan = 0; for (int i = 1; i < lanes.Count; i++) { if (eachTemplate != lastTemplate) { lanes[i] += CY * 2; } if (lanes[i] > minlan) { minlan = lanes[i]; } } // verify this... for (int i = 1; i < lanes.Count; i++) { if (lanes[i] < minlan) { lanes[i] = minlan; } } if (g != null && eachTemplate != lastTemplate) { using (Font font = new Font(FontFamily.GenericSansSerif, 8.0f, FontStyle.Italic)) { g.DrawString(eachTemplate.Name, font, Brushes.Gray, CX + FormatPNG.Border, lanes[1] - CY * 2 + FormatPNG.Border); } int lineY = lanes[1] - CY * 2 + FormatPNG.Border; g.DrawLine(Pens.Gray, CX + FormatPNG.Border, lineY, 1920, lineY); } lastTemplate = eachTemplate; } DrawAttribute(g, lane, lanes, docEntity, docView, ruleAttributeSort, map, offset, layout, docProject, docSchema, instance as SEntity); } offset++; } // increment lane offset int minlane = y + CY * (listAttr.Count + 2); if (lanes[lane] < minlane) { lanes[lane] = minlane; } }
/// <summary> /// Creates or returns emitted type, or NULL if no such type. /// </summary> /// <param name="map"></param> /// <param name="typename"></param> /// <returns></returns> public Type RegisterType(string strtype) { // this implementation maps direct and inverse attributes to fields for brevity; a production implementation would use properties as well if (strtype == null) { return(typeof(object)); } Type type = null; // resolve standard types switch (strtype) { case "INTEGER": type = typeof(long); break; case "REAL": case "NUMBER": type = typeof(double); break; case "BOOLEAN": case "LOGICAL": type = typeof(bool); break; case "STRING": type = typeof(string); break; case "BINARY": case "BINARY (32)": type = typeof(byte[]); break; } if (type != null) { return(type); } // check for existing mapped type if (this.m_types.TryGetValue(strtype, out type)) { return(type); } // look up DocObject docType = null; if (!this.m_definitions.TryGetValue(strtype, out docType)) { return(null); } string schema = this.m_namespaces[docType.Name]; // not yet exist: create it TypeAttributes attr = TypeAttributes.Public; if (docType is DocEntity) { attr |= TypeAttributes.Class; DocEntity docEntity = (DocEntity)docType; if (docEntity.IsAbstract()) { attr |= TypeAttributes.Abstract; } Type typebase = RegisterType(docEntity.BaseDefinition); // calling base class may result in this class getting defined (IFC2x3 schema with IfcBuildingElement), so check again if (this.m_types.TryGetValue(strtype, out type)) { return(type); } TypeBuilder tb = this.m_module.DefineType("BuildingSmart.IFC4X1." + schema + "." + docType.Name, attr, typebase); // add typebuilder to map temporarily in case referenced by an attribute within same class or base class this.m_types.Add(strtype, tb); // custom attributes (required for JSON serialization) ConstructorInfo conContract = (typeof(DataContractAttribute).GetConstructor(new Type[] { })); PropertyInfo propContractReference = typeof(DataContractAttribute).GetProperty("IsReference"); CustomAttributeBuilder cbContract = new CustomAttributeBuilder(conContract, new object[] { }, new PropertyInfo[] { propContractReference }, new object[] { false }); // consider setting IsReference to true if/when serializers like JSON support such referencing tb.SetCustomAttribute(cbContract); string displayname = docType.Name; if (displayname != null) { ConstructorInfo conReq = typeof(DisplayNameAttribute).GetConstructor(new Type[] { typeof(string) }); CustomAttributeBuilder cabReq = new CustomAttributeBuilder(conReq, new object[] { displayname }); tb.SetCustomAttribute(cabReq); } string description = docType.Documentation; if (description != null) { ConstructorInfo conReq = typeof(DescriptionAttribute).GetConstructor(new Type[] { typeof(string) }); CustomAttributeBuilder cabReq = new CustomAttributeBuilder(conReq, new object[] { description }); tb.SetCustomAttribute(cabReq); } // interfaces implemented by type (SELECTS) foreach (DocDefinition docdef in this.m_definitions.Values) { if (docdef is DocSelect) { DocSelect docsel = (DocSelect)docdef; foreach (DocSelectItem dsi in docsel.Selects) { if (strtype.Equals(dsi.Name)) { // register Type typeinterface = this.RegisterType(docdef.Name); tb.AddInterfaceImplementation(typeinterface); } } } } Dictionary <string, FieldInfo> mapField = new Dictionary <string, FieldInfo>(); this.m_fields.Add(tb, mapField); ConstructorInfo conMember = typeof(DataMemberAttribute).GetConstructor(new Type[] { /*typeof(int)*/ }); ConstructorInfo conInverse = typeof(InversePropertyAttribute).GetConstructor(new Type[] { typeof(string) }); PropertyInfo propMemberOrder = typeof(DataMemberAttribute).GetProperty("Order"); int order = 0; foreach (DocAttribute docAttribute in docEntity.Attributes) { DocObject docRef = null; if (docAttribute.DefinedType != null) { this.m_definitions.TryGetValue(docAttribute.DefinedType, out docRef); } // exclude derived attributes if (String.IsNullOrEmpty(docAttribute.Derived)) { Type typefield = RegisterType(docAttribute.DefinedType); if (typefield == null) { typefield = typeof(object); // excluded from scope } if (docAttribute.AggregationType != 0) { if (docAttribute.AggregationAttribute != null) { // list of list switch (docAttribute.AggregationAttribute.GetAggregation()) { case DocAggregationEnum.SET: typefield = typeof(ISet <>).MakeGenericType(new Type[] { typefield }); break; case DocAggregationEnum.LIST: default: typefield = typeof(IList <>).MakeGenericType(new Type[] { typefield }); break; } } switch (docAttribute.GetAggregation()) { case DocAggregationEnum.SET: typefield = typeof(ISet <>).MakeGenericType(new Type[] { typefield }); break; case DocAggregationEnum.LIST: default: typefield = typeof(IList <>).MakeGenericType(new Type[] { typefield }); break; } } else if (typefield.IsValueType && docAttribute.IsOptional) { typefield = typeof(Nullable <>).MakeGenericType(new Type[] { typefield }); } FieldBuilder fb = tb.DefineField("_" + docAttribute.Name, typefield, FieldAttributes.Private); mapField.Add(docAttribute.Name, fb); PropertyBuilder pb = RegisterProperty(docAttribute.Name, typefield, tb, fb); if (String.IsNullOrEmpty(docAttribute.Inverse)) { // direct attributes are fields marked for serialization CustomAttributeBuilder cb = new CustomAttributeBuilder(conMember, new object[] {}, new PropertyInfo[] { propMemberOrder }, new object[] { order }); pb.SetCustomAttribute(cb); order++; // mark if required if (!docAttribute.IsOptional) { ConstructorInfo conReq = typeof(RequiredAttribute).GetConstructor(new Type[] { }); CustomAttributeBuilder cabReq = new CustomAttributeBuilder(conReq, new object[] { }); pb.SetCustomAttribute(cabReq); } } else { // inverse attributes are fields marked for lookup CustomAttributeBuilder cb = new CustomAttributeBuilder(conInverse, new object[] { docAttribute.Inverse }); pb.SetCustomAttribute(cb); } // XML ConstructorInfo conXSD; CustomAttributeBuilder cabXSD; if (docAttribute.AggregationAttribute == null && (docRef is DocDefined || docRef is DocEnumeration)) { conXSD = typeof(XmlAttributeAttribute).GetConstructor(new Type[] { }); cabXSD = new CustomAttributeBuilder(conXSD, new object[] { }); pb.SetCustomAttribute(cabXSD); } else { switch (docAttribute.XsdFormat) { case DocXsdFormatEnum.Element: conXSD = typeof(XmlElementAttribute).GetConstructor(new Type[] { typeof(string) }); cabXSD = new CustomAttributeBuilder(conXSD, new object[] { docAttribute.DefinedType }); pb.SetCustomAttribute(cabXSD); break; case DocXsdFormatEnum.Attribute: conXSD = typeof(XmlElementAttribute).GetConstructor(new Type[] { }); cabXSD = new CustomAttributeBuilder(conXSD, new object[] { }); pb.SetCustomAttribute(cabXSD); break; case DocXsdFormatEnum.Hidden: conXSD = typeof(XmlIgnoreAttribute).GetConstructor(new Type[] { }); cabXSD = new CustomAttributeBuilder(conXSD, new object[] { }); pb.SetCustomAttribute(cabXSD); break; } } // documentation string fielddisplayname = docAttribute.Name; if (displayname != null) { ConstructorInfo conReq = typeof(DisplayNameAttribute).GetConstructor(new Type[] { typeof(string) }); CustomAttributeBuilder cabReq = new CustomAttributeBuilder(conReq, new object[] { fielddisplayname }); pb.SetCustomAttribute(cabReq); } string fielddescription = docAttribute.Documentation; if (description != null) { ConstructorInfo conReq = typeof(DescriptionAttribute).GetConstructor(new Type[] { typeof(string) }); CustomAttributeBuilder cabReq = new CustomAttributeBuilder(conReq, new object[] { fielddescription }); pb.SetCustomAttribute(cabReq); } } } // remove from typebuilder this.m_types.Remove(strtype); type = tb; // avoid circular conditions -- generate type afterwords } else if (docType is DocSelect) { attr |= TypeAttributes.Interface | TypeAttributes.Abstract; TypeBuilder tb = this.m_module.DefineType(schema + "." + docType.Name, attr); // interfaces implemented by type (SELECTS) foreach (DocDefinition docdef in this.m_definitions.Values) { if (docdef is DocSelect) { DocSelect docsel = (DocSelect)docdef; foreach (DocSelectItem dsi in docsel.Selects) { if (strtype.Equals(dsi.Name)) { // register Type typeinterface = this.RegisterType(docdef.Name); tb.AddInterfaceImplementation(typeinterface); } } } } type = tb.CreateType(); } else if (docType is DocEnumeration) { DocEnumeration docEnum = (DocEnumeration)docType; EnumBuilder eb = this.m_module.DefineEnum(schema + "." + docType.Name, TypeAttributes.Public, typeof(int)); for (int i = 0; i < docEnum.Constants.Count; i++) { DocConstant docConst = docEnum.Constants[i]; FieldBuilder fb = eb.DefineLiteral(docConst.Name, (int)i); foreach (DocLocalization docLocal in docEnum.Localization) { CustomAttributeBuilder cab = docLocal.ToCustomAttributeBuilder(); if (cab != null) { fb.SetCustomAttribute(cab); } } } type = eb.CreateType(); } else if (docType is DocDefined) { DocDefined docDef = (DocDefined)docType; attr |= TypeAttributes.Sealed; if (docDef.DefinedType == docDef.Name) { return(null); } TypeBuilder tb = this.m_module.DefineType(schema + "." + docType.Name, attr, typeof(ValueType)); // interfaces implemented by type (SELECTS) foreach (DocDefinition docdef in this.m_definitions.Values) { if (docdef is DocSelect) { DocSelect docsel = (DocSelect)docdef; foreach (DocSelectItem dsi in docsel.Selects) { if (strtype.Equals(dsi.Name)) { // register Type typeinterface = RegisterType(docdef.Name); tb.AddInterfaceImplementation(typeinterface); } } } } Type typeliteral = RegisterType(docDef.DefinedType); if (typeliteral != null) { if (docDef.Aggregation != null && docDef.Aggregation.AggregationType != 0) { switch (docDef.Aggregation.GetAggregation()) { case DocAggregationEnum.SET: typeliteral = typeof(ISet <>).MakeGenericType(new Type[] { typeliteral }); break; case DocAggregationEnum.LIST: default: typeliteral = typeof(IList <>).MakeGenericType(new Type[] { typeliteral }); break; } } else { #if false // now use direct type -- don't recurse FieldInfo fieldval = typeliteral.GetField("Value"); while (fieldval != null) { typeliteral = fieldval.FieldType; fieldval = typeliteral.GetField("Value"); } #endif } FieldBuilder fieldValue = tb.DefineField("Value", typeliteral, FieldAttributes.Public); RegisterProperty("Value", typeliteral, tb, fieldValue); type = tb.CreateType(); Dictionary <string, FieldInfo> mapField = new Dictionary <string, FieldInfo>(); mapField.Add("Value", fieldValue); this.m_fields.Add(type, mapField); } } this.m_types.Add(strtype, type); return(type); }
public string FormatEntityFull(DocEntity docEntity, Dictionary <string, DocObject> map, Dictionary <DocObject, bool> included, bool fullListing) { // entity StringBuilder sb = new StringBuilder(); // object properties StringBuilder sbProps = new StringBuilder(); // lists StringBuilder sbLists = new StringBuilder(); sb.AppendLine("ifc:" + docEntity.Name); // superclass if (docEntity.BaseDefinition != null) { DocEntity super = map[docEntity.BaseDefinition] as DocEntity; if (super != null) { sb.AppendLine("\trdfs:subClassOf \tifc:" + super.Name + " ;"); // disjoint if (subTypesOfEntity.ContainsKey(super.Name)) { string tmp = ""; foreach (string subtype in subTypesOfEntity[super.Name]) { if (subtype != docEntity.Name) { if (tmp.Length > 0) { tmp += ", "; } tmp += ToOwlClass(subtype) + " "; } } if (tmp.Length > 0) { sb.AppendLine("\towl:disjointWith " + tmp + ";"); } } } } // abstract class if (docEntity.IsAbstract()) { sb.AppendLine("\trdfs:subClassOf "); sb.AppendLine("\t\t[ "); sb.AppendLine("\t\t\trdf:type owl:Class ;"); sb.Append("\t\t\towl:unionOf ( "); if (subTypesOfEntity.ContainsKey(docEntity.Name)) { foreach (string subtype in subTypesOfEntity[docEntity.Name]) { sb.Append(ToOwlClass(subtype) + " "); } } sb.Append(")"); sb.AppendLine(); sb.AppendLine("\t\t] ;"); } // attributes -> create properties and restrictions foreach (DocAttribute docAttr in docEntity.Attributes) { // check if Attr must be skipped (1) - not included attribute if (included != null) { if (!included.ContainsKey(docAttr)) { continue; } } string propname = ""; string propfullname = ""; string invpropname = ""; string invpropfullname = ""; string targetString = docAttr.DefinedType; DocEntity targetEntity = null; if (map.ContainsKey(targetString)) { targetEntity = map[targetString] as DocEntity; } // check if Attr must be skipped (2) - DERIVE attribute if (docAttr.Derived != null) { continue; } // check if Attr must be skipped (3) - not manageable INVERSE attribute invpropname = docAttr.Inverse; if (invpropname != null) { // check if there are problems with inverse and in this case skip the attribute! // 1) the inverse is an inverse of two or more properties // 2) a list/array is involved as range in the property or its inverse // 1) var key = new Tuple <string, string>(docAttr.Inverse, targetString); if (attribInverses.ContainsKey(key)) { if (attribInverses[key] > 1) { continue; } } // 2.a) if (docAttr.GetAggregation() == DocAggregationEnum.LIST || docAttr.GetAggregation() == DocAggregationEnum.ARRAY) { continue; } // 2.b) if (targetEntity != null) { bool toBeSkipped = false; foreach (DocAttribute docAttrInv in targetEntity.Attributes) { if (docAttrInv.Name == invpropname) { if (docAttrInv.GetAggregation() == DocAggregationEnum.LIST || docAttrInv.GetAggregation() == DocAggregationEnum.ARRAY) { toBeSkipped = true; break; } } } if (toBeSkipped) { continue; } } } // set actual target string actualTargetString = ToOwlClass(targetString); if (docAttr.GetAggregation() == DocAggregationEnum.LIST || docAttr.GetAggregation() == DocAggregationEnum.ARRAY) { string newlistdef = createListClass(actualTargetString); actualTargetString = actualTargetString + "_List"; if (newlistdef.Length > 0) { sbLists.Append(newlistdef); } DocAttribute docAggregate = docAttr.AggregationAttribute; while (docAggregate != null) { newlistdef = createListClass(actualTargetString); actualTargetString = actualTargetString + "_List"; if (newlistdef.Length > 0) { sbLists.Append(newlistdef); } docAggregate = docAggregate.AggregationAttribute; } } // create property propname = docAttr.Name; propfullname = propname + "_" + docEntity.Name; if (propfullname.Length > 0) { propfullname = char.ToLower(propfullname[0]) + propfullname.Substring(1); } propfullname = "ifc:" + propfullname; sbProps.AppendLine(propfullname); sbProps.Append("\trdf:type \towl:ObjectProperty "); // functional if (docAttr.GetAggregation() == DocAggregationEnum.NONE || docAttr.GetAggregation() == DocAggregationEnum.LIST || docAttr.GetAggregation() == DocAggregationEnum.ARRAY || (docAttr.GetAggregation() == DocAggregationEnum.SET && docAttr.GetAggregationNestingUpper() == 1)) { sbProps.Append(", owl:FunctionalProperty "); } sbProps.Append(";"); sbProps.AppendLine(); // inverse if (invpropname != null && targetEntity != null) { invpropfullname = invpropname + "_" + targetEntity.Name; if (invpropfullname.Length > 0) { invpropfullname = char.ToLower(invpropfullname[0]) + invpropfullname.Substring(1); } invpropfullname = "ifc:" + invpropfullname; sbProps.AppendLine("\towl:inverseOf \t" + invpropfullname + " ;"); } // domain sbProps.AppendLine("\trdfs:domain " + ToOwlClass(docEntity.Name) + " ;"); // range sbProps.AppendLine("\trdfs:range " + actualTargetString + " ;"); // label sbProps.AppendLine("\trdfs:label \"" + propname + "\" ."); sbProps.AppendLine(); // create restrictions { // only sb.AppendLine("\trdfs:subClassOf "); sb.AppendLine("\t\t[ "); sb.AppendLine("\t\t\trdf:type owl:Restriction ;"); sb.AppendLine("\t\t\towl:allValuesFrom " + actualTargetString + " ;"); sb.AppendLine("\t\t\towl:onProperty " + propfullname); sb.AppendLine("\t\t] ;"); if (docAttr.GetAggregation() == DocAggregationEnum.NONE || docAttr.GetAggregation() == DocAggregationEnum.LIST || docAttr.GetAggregation() == DocAggregationEnum.ARRAY) { sb.AppendLine("\t" + "rdfs:subClassOf "); sb.AppendLine("\t\t" + "["); sb.AppendLine("\t\t\t" + "rdf:type owl:Restriction ;"); if (docAttr.IsOptional) { sb.AppendLine("\t\t\t" + "owl:maxQualifiedCardinality \"" + 1 + "\"^^xsd:nonNegativeInteger ;"); } else { sb.AppendLine("\t\t\t" + "owl:qualifiedCardinality \"" + 1 + "\"^^xsd:nonNegativeInteger ;"); } sb.AppendLine("\t\t\towl:onProperty " + propfullname + " ;"); sb.AppendLine("\t\t\t" + "owl:onClass " + actualTargetString); sb.AppendLine("\t\t] ;"); } if (docAttr.GetAggregation() == DocAggregationEnum.SET) { int mincard = 0; if (docAttr.AggregationLower != null) { mincard = Int32.Parse(docAttr.AggregationLower); } int maxcard = 0; if (String.IsNullOrEmpty(docAttr.AggregationUpper) || !Int32.TryParse(docAttr.AggregationUpper, out maxcard)) { maxcard = 0; } if (docAttr.IsOptional) { mincard = 0; } if (mincard == maxcard && mincard > 0) { sb.AppendLine("\t" + "rdfs:subClassOf "); sb.AppendLine("\t\t" + "["); sb.AppendLine("\t\t\t" + "rdf:type owl:Restriction ;"); sb.AppendLine("\t\t\t" + "owl:qualifiedCardinality \"" + mincard + "\"^^xsd:nonNegativeInteger ;"); sb.AppendLine("\t\t\towl:onProperty " + propfullname + " ;"); sb.AppendLine("\t\t\t" + "owl:onClass " + actualTargetString); sb.AppendLine("\t\t] ;"); } else { if (mincard > 0) { sb.AppendLine("\t" + "rdfs:subClassOf "); sb.AppendLine("\t\t" + "["); sb.AppendLine("\t\t\t" + "rdf:type owl:Restriction ;"); sb.AppendLine("\t\t\t" + "owl:minQualifiedCardinality \"" + mincard + "\"^^xsd:nonNegativeInteger ;"); sb.AppendLine("\t\t\towl:onProperty " + propfullname + " ;"); sb.AppendLine("\t\t\t" + "owl:onClass " + actualTargetString); sb.AppendLine("\t\t] ;"); } if (maxcard > 0) { sb.AppendLine("\t" + "rdfs:subClassOf "); sb.AppendLine("\t\t" + "["); sb.AppendLine("\t\t\t" + "rdf:type owl:Restriction ;"); sb.AppendLine("\t\t\t" + "owl:maxQualifiedCardinality \"" + maxcard + "\"^^xsd:nonNegativeInteger ;"); sb.AppendLine("\t\t\towl:onProperty " + propfullname + " ;"); sb.AppendLine("\t\t\t" + "owl:onClass " + actualTargetString); sb.AppendLine("\t\t] ;"); } } } if (docAttr.GetAggregation() == DocAggregationEnum.LIST || docAttr.GetAggregation() == DocAggregationEnum.ARRAY) { int mincard = 0; if (docAttr.AggregationLower != null) { mincard = Int32.Parse(docAttr.AggregationLower); } int maxcard = 0; if (String.IsNullOrEmpty(docAttr.AggregationUpper) || !Int32.TryParse(docAttr.AggregationUpper, out maxcard)) { maxcard = 0; } if (docAttr.GetAggregation() == DocAggregationEnum.ARRAY) { mincard = maxcard - mincard + 1; maxcard = mincard; } if (mincard >= 1) { string cards = ""; cards += WriteMinCardRestr(actualTargetString, propfullname, mincard, true); cards += " ;"; sb.AppendLine(cards); } if (maxcard > 1) { string cards = ""; string emptyListTgt = actualTargetString.Substring(0, actualTargetString.Length - 4) + "EmptyList"; cards += WriteMaxCardRestr(emptyListTgt, propfullname, maxcard, true); cards += " ;"; sb.AppendLine(cards); } } } } sb.AppendLine("\trdf:type \towl:Class ."); sb.AppendLine(); if (fullListing) { sb.Append(sbProps.ToString()); sb.Append(sbLists.ToString()); } return(sb.ToString()); }
public string FormatEntity(DocEntity docEntity, Dictionary <string, DocObject> map, Dictionary <DocObject, bool> included) { StringBuilder sb = new StringBuilder(); sb.Append("public "); if (docEntity.IsAbstract()) { sb.Append("abstract "); } sb.Append("partial class " + docEntity.Name); bool hasentry = false; if (!String.IsNullOrEmpty(docEntity.BaseDefinition)) { sb.Append(" : "); sb.Append(docEntity.BaseDefinition); hasentry = true; } // implement any selects BuildSelectEntries(sb, docEntity, map, included, hasentry); sb.AppendLine(); sb.AppendLine("{"); sb.AppendLine(); //sb.AppendLine("// Schema properties"); //sb.AppendLine(); // fields int order = 0; foreach (DocAttribute docAttribute in docEntity.Attributes) { bool inscope = false; if (included != null) { included.TryGetValue(docAttribute, out inscope); } else { inscope = true; } if (docAttribute.Inverse == null) { // System.Runtime.Serialization -- used by Windows Communication Foundation formatters to indicate data serialization inclusion and order sb.AppendLine("\t[DataMember(Order=" + order + ")] "); order++; } else if (inscope) { // System.ComponentModel.DataAnnotations for capturing inverse properties -- EntityFramework navigation properties sb.AppendLine("\t[InverseProperty(\"" + docAttribute.Inverse + "\")] "); } // documentation -- need to escape content... ////sb.AppendLine("\t[Description(\"" + docAttribute.Documentation + "\")]"); if (docAttribute.Inverse == null || inscope) { DocObject docRef = null; if (docAttribute.DefinedType != null) { map.TryGetValue(docAttribute.DefinedType, out docRef); } string optional = ""; if (docAttribute.IsOptional && (docRef == null || docRef is DocDefined)) { optional = "?"; } switch (docAttribute.GetAggregation()) { case DocAggregationEnum.SET: sb.AppendLine("\tpublic ISet<" + FormatIdentifier(docAttribute.DefinedType) + "> " + docAttribute.Name + " {get; set;}"); break; case DocAggregationEnum.LIST: sb.AppendLine("\tpublic IList<" + FormatIdentifier(docAttribute.DefinedType) + "> " + docAttribute.Name + " {get; set;}"); break; default: sb.AppendLine("\tpublic " + FormatIdentifier(docAttribute.DefinedType) + optional + " " + docAttribute.Name + " {get; set;}"); break; } } sb.AppendLine(); } // sb.AppendLine(); //sb.AppendLine("// Exchange properties"); // then, model views within scope foreach (DocModelView docView in this.m_project.ModelViews) { if (included == null || included.ContainsKey(docView)) // todo: make option when generating to indicate which views... { foreach (DocConceptRoot docRoot in docView.ConceptRoots) { if (docRoot.ApplicableEntity == docEntity) { foreach (DocTemplateUsage docConcept in docRoot.Concepts) { // sub-templates: traverse through if (docConcept.Items.Count > 0) { string template = docConcept.Definition.Name.Replace(" ", "_"); // no sub-templates: use direct (e.g. ports) foreach (DocTemplateItem docItem in docConcept.Items) { string name = docItem.GetParameterValue("Name"); if (docItem.Concepts.Count > 0) { // drill into each concept foreach (DocTemplateUsage docInner in docItem.Concepts) { foreach (DocTemplateItem docInnerItem in docInner.Items) { string attr = docInnerItem.GetParameterValue("PropertyName"); // temphack string type = docInnerItem.GetParameterValue("Value"); if (attr != null && type != null && attr.Length > 1) { sb.AppendLine("\tpublic " + type + " " + attr); sb.AppendLine("\t{"); sb.AppendLine("\t\tget"); sb.AppendLine("\t\t{"); sb.AppendLine("\t\t\treturn Template." + template + ".GetValue(this, \"" + name + "\", \"" + attr + "\") as " + type + ";"); sb.AppendLine("\t\t}"); sb.AppendLine("\t\tset"); sb.AppendLine("\t\t{"); sb.AppendLine("\t\t\tTemplate." + template + ".SetValue(this, \"" + name + "\", \"" + attr + "\", value);"); sb.AppendLine("\t\t}"); sb.AppendLine("\t}"); sb.AppendLine(); } } } } else { string type = docItem.GetParameterValue("Value"); if (type == null) { // find type according to template //docConcept.Definition. } if (name != null && type != null) { sb.AppendLine("\tpublic " + type + " " + name); sb.AppendLine("\t{"); sb.AppendLine("\t\tget"); sb.AppendLine("\t\t{"); sb.AppendLine("\t\t\treturn Template." + template + ".GetValue(this, \"" + name + "\") as " + type + ";"); sb.AppendLine("\t\t}"); sb.AppendLine("\t\tset"); sb.AppendLine("\t\t{"); sb.AppendLine("\t\t\tTemplate." + template + ".SetValue(this, \"" + name + "\", value);"); sb.AppendLine("\t\t}"); sb.AppendLine("\t}"); sb.AppendLine(); } } } } } } } } } #if false // make an option... // constructor sb.AppendLine(); sb.AppendLine("\tpublic " + docEntity.Name + "()"); sb.AppendLine("\t{"); //... values... sb.AppendLine("\t}"); #endif // properties #if false // make an option... foreach (DocAttribute docAttribute in docEntity.Attributes) { sb.AppendLine(); switch (docAttribute.GetAggregation()) { case DocAggregationEnum.SET: sb.AppendLine("\tpublic ICollection<" + docAttribute.DefinedType + "> " + docAttribute.Name); break; case DocAggregationEnum.LIST: sb.AppendLine("\tpublic IList<" + docAttribute.DefinedType + "> " + docAttribute.Name); break; default: sb.AppendLine("\tpublic " + docAttribute.DefinedType + " " + docAttribute.Name); break; } sb.AppendLine("\t\t{"); sb.AppendLine("\t\tget"); sb.AppendLine("\t\t{"); sb.AppendLine("\t\t\treturn this._" + docAttribute.Name + ";"); sb.AppendLine("\t\t}"); if (docAttribute.GetAggregation() == DocAggregationEnum.NONE) { sb.AppendLine("\t\tset"); sb.AppendLine("\t\t{"); sb.AppendLine("\t\t\tthis.OnBeforePropertyChange(\"" + docAttribute.Name + "\");"); sb.AppendLine("\t\t\tthis._" + docAttribute.Name + " = value;"); sb.AppendLine("\t\t\tthis.OnAfterPropertyChange(\"" + docAttribute.Name + "\");"); sb.AppendLine("\t\t}"); } sb.AppendLine("\t}"); } #endif #if false // make an option... // serialization writer.WriteLine(); writer.WriteLine("\t\tprivate void GetObjectData(SerializationInfo info, StreamingContext context)"); writer.WriteLine("\t\t{"); foreach (DocAttribute docAttribute in docEntity.Attributes) { if (docAttribute.Inverse == null && docAttribute.Derived == null) { writer.WriteLine("\t\t\tinfo.AddValue(\"" + docAttribute.Name + "\", this._" + docAttribute.Name + ");"); } } writer.WriteLine("\t\t}"); writer.WriteLine(); writer.WriteLine("\t\tprivate void SetObjectData(SerializationInfo info, StreamingContext context)"); writer.WriteLine("\t\t{"); foreach (DocAttribute docAttribute in docEntity.Attributes) { if (docAttribute.Inverse == null && docAttribute.Derived == null) { string method = "GetValue"; writer.WriteLine("\t\t\tthis._" + docAttribute.Name + " = info." + method + "(\"" + docAttribute.Name + "\");"); } } writer.WriteLine("\t\t}"); #endif sb.AppendLine("}"); return(sb.ToString()); }