private static void DrawAttribute( Graphics g, int lane, List<int> lanes, DocEntity docEntity, DocModelView docView, DocModelRuleAttribute ruleAttribute, Dictionary<string, DocObject> map, int offset, Dictionary<Rectangle, DocModelRule> layout, DocProject docProject, DocSchema docSchema, SEntity instance) { int x = lane * CX + FormatPNG.Border; int y = lanes[lane] + FormatPNG.Border; // find the index of the attribute List<DocAttribute> listAttr = new List<DocAttribute>(); BuildAttributeList(docEntity, listAttr, map); int iAttr = -1; for (int i = 0; i < listAttr.Count; i++) { if (listAttr[i].Name.Equals(ruleAttribute.Name)) { // found it iAttr = i; break; } } if (iAttr >= 0) { DocAttribute docAttr = listAttr[iAttr]; object valueinstance = null; if (instance != null) { System.Reflection.FieldInfo field = instance.GetType().GetField(docAttr.Name); if(field != null) { valueinstance = field.GetValue(instance); } } // map it foreach (DocModelRule ruleEach in ruleAttribute.Rules) { if (ruleEach is DocModelRuleEntity) { DocModelRuleEntity ruleEntity = (DocModelRuleEntity)ruleEach; DocObject docObj = null; if (docSchema != null) { docObj = docSchema.GetDefinition(ruleEntity.Name); if (docObj is DocDefinitionRef) docObj = null; } if (docObj == null) { map.TryGetValue(ruleEntity.Name, out docObj); } { int dest = FormatPNG.Border; if (lanes.Count > lane + 1) { dest = lanes[lane + 1] + FormatPNG.Border; } if (docObj is DocEntity) { DocEntity docEntityTarget = (DocEntity)docObj; // resolve inverse attribute List<DocAttribute> listTarget = new List<DocAttribute>(); BuildAttributeList(docEntityTarget, listTarget, map); for (int i = 0; i < listTarget.Count; i++) { DocAttribute docAttrTarget = listTarget[i]; if (docAttr.Inverse != null && docAttrTarget.Name.Equals(docAttr.Inverse)) { // found it dest += CY * (i + 1); break; } else if (docAttrTarget.Inverse != null && docAttr.Name.Equals(docAttrTarget.Inverse)) { //...also need to check for type compatibility bool found = false; DocEntity docTest = docEntity; while (docTest != null) { if (docTest.Name.Equals(docAttrTarget.DefinedType)) { found = true; break; } if (docTest.BaseDefinition == null) break; DocObject docBase = null; if (map.TryGetValue(docTest.BaseDefinition, out docBase)) { docTest = docBase as DocEntity; } else { break; } } // found it if (found) { dest += CY * (i + 1); break; } } } // draw the entity, recurse DrawEntity(g, lane + 1, lanes, docEntityTarget, docView, null, ruleEntity, map, layout, docProject, docSchema, valueinstance); } else { int targetY = lanes[lane + 1] + FormatPNG.Border; if (g != null) { Brush brush = Brushes.Black; if (instance != null) { if (valueinstance == null) { brush = Brushes.Red; } else if(valueinstance is System.Collections.IList) { brush = Brushes.Blue; } else { string typename = valueinstance.GetType().Name; if (typename == ruleEntity.Name) { brush = Brushes.Lime; } else { brush = Brushes.Red; } } } g.FillRectangle(brush, x + CX, targetY, CX - DX, CY); g.DrawRectangle(Pens.Black, x + CX, targetY, CX - DX, CY); using (Font font = new Font(FontFamily.GenericSansSerif, 8.0f)) { string content = ruleEntity.Name;//docObj.Name; foreach (DocModelRule ruleConstraint in ruleEntity.Rules) { if (ruleConstraint.Description != null && ruleConstraint.Description.StartsWith("Value=")) { content = ruleConstraint.Description.Substring(6); using (StringFormat fmt = new StringFormat()) { fmt.Alignment = StringAlignment.Far; g.DrawString(content, font, Brushes.White, new RectangleF(x + CX, targetY, CX - DX, CY), fmt); } } } g.DrawString(ruleEntity.Name, font, Brushes.White, x + CX, targetY); if (ruleEntity.Identification == "Value") { // mark rule serving as default value g.FillEllipse(Brushes.Green, new Rectangle(x + CX - DX - CY, y, CY, CY)); } } } // record rectangle if (layout != null) { layout.Add(new Rectangle(x + CX, targetY, CX - DX, CY), ruleEntity); } // increment lane offset for all lanes int minlane = targetY + CY * 2; int i = lane + 1; if (lanes[i] < minlane) { lanes[i] = minlane; } } // draw arrow if (g != null) { int x0 = x + CX - DX; int y0 = y + CY * (iAttr + 1) + CY / 2; int x1 = x + CX; int y1 = dest + CY / 2; int xM = x0 + DX / 2 - offset * 2; if(!String.IsNullOrEmpty(ruleAttribute.Identification)) { // mark the attribute as using parameter //g.DrawRectangle(Pens.Blue, x, y + CY * (iAttr + 1), CX - DX, CY); using (Font font = new Font(FontFamily.GenericSansSerif, 8.0f, FontStyle.Regular)) { using (StringFormat fmt = new StringFormat()) { fmt.Alignment = StringAlignment.Near; g.DrawString(docAttr.Name, font, Brushes.Blue, x, y + CY * (iAttr + 1), fmt); } } } g.DrawLine(Pens.Black, x0, y0, xM, y0); g.DrawLine(Pens.Black, xM, y0, xM, y1); g.DrawLine(Pens.Black, xM, y1, x1, y1); } } } } if (g != null && ruleAttribute.Identification == "Name") { // mark rule serving as default name g.FillEllipse(Brushes.Blue, new Rectangle(x + CX - DX - CY, y + CY * (iAttr+1), CY, CY)); } #if false string card = ruleAttribute.GetCardinalityExpression(); if (g != null && card != null) { card = card.Trim(); switch (docAttr.GetAggregation()) { case DocAggregationEnum.SET: card = "S" + card; break; case DocAggregationEnum.LIST: card = "L" + card; break; } int px = x + CX - DX; int py = y + CY * (iAttr + 1); g.FillRectangle(Brushes.White, px - CX / 5, py, CX / 5, CY); using (Font font = new Font(FontFamily.GenericSansSerif, 8.0f, FontStyle.Regular)) { using (StringFormat fmt = new StringFormat()) { fmt.Alignment = StringAlignment.Far; g.DrawString(card, font, Brushes.Blue, px, py, fmt); } } } #endif } }
/// <summary> /// Gets value referenced by path. /// </summary> /// <param name="target">The relative object to retrieve the value.</param> /// <param name="parameters">Optional parameters for substitution.</param> /// <returns>The value on the object along the expression path.</returns> public object GetValue(SEntity target, Dictionary<string, SEntity> parameters) { if (target == null) throw new ArgumentNullException("target"); if (this.m_type == null) { return target.GetType(); } if (!this.m_type.IsInstanceOfType(target)) return null; // doesn't apply if (this.m_property == null) { return target; // for general case, if no attribute specified, then return object itself //return target.GetType(); // need some way to extract type directly such as for COBie } object value = null; if (this.m_property.PropertyType.IsGenericType && typeof(System.Collections.IList).IsAssignableFrom(this.m_property.PropertyType) && (typeof(SEntity).IsAssignableFrom(this.m_property.PropertyType.GetGenericArguments()[0]) || this.m_property.PropertyType.GetGenericArguments()[0].IsInterface)) { System.Collections.IList list = (System.Collections.IList)this.m_property.GetValue(target, null); // if expecting array, then return it. //if (this.m_vector) if (this.m_vector || (this.m_identifier == null && this.m_inner == null)) // 2014-01-20: RICS export of door schedules to show quantity { return list; } else if (this.m_identifier != null && this.m_identifier.StartsWith("@") && parameters == null) { // return filtered list based on expected type -- may be none if no compatible types -- e.g. COBie properties only return IfcPropertyEnumeratedValue if (this.InnerPath != null && this.InnerPath.Type != null) { List<SEntity> listFilter = null; foreach (SEntity ent in list) { if (this.InnerPath.Type.IsInstanceOfType(ent)) { if (listFilter == null) { listFilter = new List<SEntity>(); } listFilter.Add(ent); } } return listFilter; } else { return list; } } if (list != null) { foreach (object eachelem in list) { // derived class may have its own specific property (e.g. IfcSIUnit, IfcConversionBasedUnit) if (this.m_identifier != null) { Type eachtype = eachelem.GetType(); DefaultPropertyAttribute[] attrs = (DefaultPropertyAttribute[])eachtype.GetCustomAttributes(typeof(DefaultPropertyAttribute), true); PropertyInfo propElem = null; if (attrs.Length > 0) { propElem = eachtype.GetProperty(attrs[0].Name); } else { propElem = eachtype.GetProperty("Name"); } if (propElem != null) { object eachname = propElem.GetValue(eachelem, null); // IStepValueString, or Enum (e.g. IfcNamedUnit.UnitType) #if false // special case for properties/quantities if (eachname == null && eachelem is IfcRelDefinesByProperties) { IfcRelDefinesByProperties rdp = (IfcRelDefinesByProperties)eachelem; eachname = rdp.RelatingPropertyDefinition.Name.GetValueOrDefault().Value; } #endif if (eachname != null) { if (this.m_identifier.StartsWith("@")) { // parameterized query -- substitute parameter if (parameters != null) { SEntity specelem = null; if (parameters.TryGetValue(this.m_identifier.Substring(1), out specelem)) { if (this.m_inner != null) { object eachvalue = this.m_inner.GetValue(specelem, parameters); return eachvalue; // return no matter what, since specific element was requested. } else { return specelem; } } } else { return null; // no parameters specified, so can't resolve value. } } else if (this.m_identifier.Equals(eachname.ToString())) { if (this.m_inner != null) { // yes -- drill in object eachvalue = this.m_inner.GetValue((SEntity)eachelem, parameters); if (eachvalue != null) { return eachvalue; // if no value, keep going until compatible match is found } } else { return eachelem; } } } } } else if (this.m_inner != null) { object eachvalue = this.m_inner.GetValue((SEntity)eachelem, parameters); if (eachvalue != null) { return eachvalue; } } else { return eachelem; } } } } else if (this.m_inner != null) { value = this.m_property.GetValue(target, null); if (value is SEntity) { value = this.m_inner.GetValue((SEntity)value, parameters); if (this.m_identifier != null && value != null) { // qualify the value Type eachtype = value.GetType(); DefaultMemberAttribute[] attrs = (DefaultMemberAttribute[])eachtype.GetCustomAttributes(typeof(DefaultMemberAttribute), true); PropertyInfo propElem = null; if (attrs.Length > 0) { propElem = eachtype.GetProperty(attrs[0].MemberName); } else { propElem = eachtype.GetProperty("Name"); } if (propElem != null) { object name = propElem.GetValue(value, null); if (name == null || !this.m_identifier.Equals(name.ToString())) { return null; } } } } } else { value = this.m_property.GetValue(target, null); } return value; }
private void WriteEntity(SEntity o) { // sanity check if(this.m_indent > 100) { return; } Type t = o.GetType(); string hyperlink = "../../schema/" + t.Namespace.ToLower() + "/lexical/" + t.Name.ToLower() + ".htm"; this.WriteStartElement(t.Name, hyperlink); #if false // id if (gen != null) { bool firstTime; long id = gen.GetId(o, out firstTime); writer.WriteAttributeString("id", "i" + id.ToString()); } #endif /* writer.WriteStartAttribute("id"); writer.WriteValue("i" + id.ToString()); writer.WriteEndAttribute();*/ // write fields as attributes bool haselements = false; IList<FieldInfo> fields = SEntity.GetFieldsOrdered(t); foreach (FieldInfo f in fields) { object v = f.GetValue(o); if(v != null) { if (f.FieldType.IsValueType) { Type ft = f.FieldType; if (ft.IsGenericType && ft.GetGenericTypeDefinition() == typeof(Nullable<>)) { // special case for Nullable types ft = ft.GetGenericArguments()[0]; } Type typewrap = null; while (ft.IsValueType && !ft.IsPrimitive) { FieldInfo fieldValue = ft.GetField("Value"); if (fieldValue != null) { v = fieldValue.GetValue(v); if (typewrap == null) { typewrap = ft; } ft = fieldValue.FieldType; } else { break; } } if (v != null) { string encodedvalue = System.Security.SecurityElement.Escape(v.ToString()); m_writer.Write(" "); m_writer.Write(f.Name); m_writer.Write("=\""); m_writer.Write(encodedvalue); //... escape it m_writer.Write("\""); } } else { haselements = true; } } } IList<FieldInfo> inverses = SEntity.GetFieldsInverse(t); if (haselements || inverses.Count > 0) { WriteOpenElement(); // write direct object references and lists foreach (FieldInfo f in fields) { DocXsdFormat format = GetXsdFormat(f); // hide fields where inverse attribute used instead if (!f.FieldType.IsValueType && (format == null || (format.XsdFormat != DocXsdFormatEnum.Hidden))) { WriteAttribute(o, f); } } // write inverse object references and lists foreach (FieldInfo f in inverses) { DocXsdFormat format = GetXsdFormat(f); if (format != null && format.XsdFormat == DocXsdFormatEnum.Element)//... check this { WriteAttribute(o, f); //... careful - don't write back-references... } } WriteEndElement(t.Name); } else { // close opening tag if (this.m_markup) { this.m_writer.WriteLine("/><br/>"); } else { this.m_writer.WriteLine("/>"); } this.m_indent--; } }
private void WriteReference(XmlWriter writer, SEntity r) { writer.WriteStartElement(r.GetType().Name); writer.WriteStartAttribute("xsi", "nil", null); writer.WriteValue(true); writer.WriteEndAttribute(); writer.WriteStartAttribute("ref"); writer.WriteValue("i" + r.OID.ToString()); writer.WriteEndAttribute(); writer.WriteEndElement(); }
/// <summary> /// </summary> /// <param name="o"></param> /// <returns></returns> private void WriteEntityAttributes(SEntity o) { Type t = o.GetType(); if (t.Name.Equals("IfcPixelTexture")) { this.ToString(); } IList<FieldInfo> fields = SEntity.GetFieldsAll(t); foreach (FieldInfo f in fields) { if (f.IsDefined(typeof(DataMemberAttribute))) { // write data type properties Type ft = f.FieldType; Console.Out.WriteLine("\r\n++ writing attribute: " + ft.Name); bool isvaluelist = (ft.IsGenericType && ft.GetGenericTypeDefinition() == typeof(List<>) && ft.GetGenericArguments()[0].IsValueType); bool isvaluelistlist = (ft.IsGenericType && // e.g. IfcTriangulatedFaceSet.Normals ft.GetGenericTypeDefinition() == typeof(List<>) && ft.GetGenericArguments()[0].IsGenericType && ft.GetGenericArguments()[0].GetGenericTypeDefinition() == typeof(List<>) && ft.GetGenericArguments()[0].GetGenericArguments()[0].IsValueType); if (isvaluelistlist || isvaluelist || ft.IsValueType) { //Console.Out.WriteLine("WriteDataValueAttribute()"); object v = f.GetValue(o); if (v != null) { m_writer.Write(";" + "\r\n"); //m_writer.Write(" "); WriteIndent(); ObjectProperty p = GetObjectProperty(f.Name + "_" + t.Name); if (p == null) Console.Out.WriteLine("Warning: objectproperty not found : " + f.Name + "_" + t.Name); m_writer.Write("ifcowl:" + p.name + " "); if (isvaluelistlist) { System.Collections.IList list = (System.Collections.IList)v; WriteListOfListWithValues(ft, list); } else if (isvaluelist) { System.Collections.IList list = (System.Collections.IList)v; WriteListWithValues(ft, list); } else { WriteTypeValue(ft,v); } } else { //Console.Out.WriteLine("Empty value: skipping"); } } else { //Console.Out.WriteLine("WriteObjectPropertyAttribute()"); //Writing object properties ObjectProperty p = GetObjectProperty(f.Name + "_" + o.GetType().Name); if (p == null) Console.Out.WriteLine("Warning: objectproperty not found : " + f.Name + "_" + o.GetType().Name); //Writing output object v = f.GetValue(o); if (v != null) { if (v.GetType() == typeof(SEntity)) { //WriteAttribute(o, f, owlClass); //m_writer.Write(owlClass + "_" + ((SEntity)value).OID); Console.Out.WriteLine("WARNING: ATTR object prop exception : " + v.ToString() + " - " + f.Name + " - " + ft.ToString()); } else { if (typeof(System.Collections.ICollection).IsAssignableFrom(ft)) { System.Collections.IList list = (System.Collections.IList)v; WriteListKindOfObjectProperty(f, v, ft, p, list); } else if (v is SEntity) { //found simple object property. give propertyname and URI num m_writer.Write(";" + "\r\n"); WriteIndent(); m_writer.Write("ifcowl:" + p.name + " "); Type vt = v.GetType(); this.m_writer.Write("inst:" + vt.Name + "_" + ((SEntity)v).OID); //There is more in the WriteAttibute method (HTM notation) } else if (f.FieldType.IsInterface && v is ValueType) { m_writer.Write(";" + "\r\n"); WriteIndent(); m_writer.Write("ifcowl:" + p.name + " "); Type vt = v.GetType(); Console.Out.WriteLine("WriteEntityAttributes.GetURIObject()"); URIObject newUriObject = GetURIObject(vt.Name, vt.GetField("Value").GetValue(v).ToString(), vt.GetField("Value").FieldType.Name); m_writer.Write("inst:" + newUriObject.URI); //this.WriteValueWrapper(v); } else if (f.FieldType.IsValueType) // must be IfcBinary { Console.Out.WriteLine("MESSAGE-CHECK: Write IfcBinary 1"); m_writer.Write(";" + "\r\n"); WriteIndent(); m_writer.Write("ifcowl:" + p.name + " "); FieldInfo fieldValue = f.FieldType.GetField("Value"); if (fieldValue != null) { v = fieldValue.GetValue(v); if (v is byte[]) { // binary data type - we don't support anything other than 8-bit aligned, though IFC doesn't either so no point in supporting extraBits byte[] bytes = (byte[])v; char[] s_hexchar = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; StringBuilder sb = new StringBuilder(bytes.Length * 2); for (int i = 0; i < bytes.Length; i++) { byte b = bytes[i]; sb.Append(s_hexchar[b / 0x10]); sb.Append(s_hexchar[b % 0x10]); } v = sb.ToString(); this.m_writer.WriteLine("\""+v+ "\""); } } } else { Console.Out.WriteLine("Warning: Found some other kind of object property: " + p.domain + " - " + p.name); } } } else { Console.Out.WriteLine("Empty value: skipping"); } } } else { //Console.Out.WriteLine("Found inverse property - skipping : " + f.Name); } } m_writer.Write(".\r\n\r\n"); Console.Out.WriteLine("End of attribute"); return; }
private void WriteEntity(SEntity o, long ID) { string newline = "\r\n"; if (this.m_markup) newline = "<br/>"; Type t = o.GetType(); string hyperlink = "../../schema/" + t.Namespace.ToLower() + "/lexical/" + t.Name.ToLower() + "_" + ID + ".htm"; this.WriteStartElement(t.Name+"_"+ID, hyperlink); this.m_writer.Write(newline); m_indent++; Console.Out.WriteLine("\r\n--- Writing entity : " + t.Name.ToString()); Console.Out.WriteLine("-----------------------------------"); this.WriteType("ifcowl:" + t.Name.ToString()); this.WriteEntityAttributes(o); Console.Out.WriteLine("--------------done---------------------"); }
private void LoadInstance(TreeNode tnParent, SEntity instance) { if (instance == null) return; // recursion stop limit (if user hits star button) if (tnParent != null && tnParent.Level > 32) return; if (tnParent != null && tnParent.Nodes.Count > 0 && tnParent.Nodes[0].Tag != null) { return; } if (tnParent != null) { tnParent.Nodes.Clear(); // remove placeholder } Dictionary<string, DocObject> mapEntity = new Dictionary<string, DocObject>(); Dictionary<string, string> mapSchema = new Dictionary<string, string>(); BuildMaps(mapEntity, mapSchema); Type t = instance.GetType(); DocDefinition docDef = this.m_project.GetDefinition(t.Name); if (docDef is DocEntity) { DocEntity docEntity = (DocEntity)docDef; List<DocAttribute> listAttr = new List<DocAttribute>(); FormatPNG.BuildAttributeList(docEntity, listAttr, mapEntity); foreach (DocAttribute docAttr in listAttr) { object value = null; System.Reflection.FieldInfo field = t.GetField(docAttr.Name); if (field != null) { value = field.GetValue(instance); // drill into underlying value if (value != null && !(value is SEntity)) { System.Reflection.FieldInfo fValue = value.GetType().GetField("Value"); if (fValue != null) { value = fValue.GetValue(value); } } } if (value != null) { TreeNode tn = new TreeNode(); tn.Tag = docAttr; tn.Text = docAttr.Name; if (value is SEntity) { tn.Text += " = " + value.GetType().Name;//((SEntity)value).OID; } else if (value is System.Collections.IList) { System.Collections.IList list = (System.Collections.IList)value; tn.Text += " = [" + list.Count + "]"; } else if (value != null) { tn.Text += " = " + value.ToString(); } if (tnParent != null) { tnParent.Nodes.Add(tn); } else { this.treeViewInstance.Nodes.Add(tn); } if (value is SEntity) { LoadInstance(tn, (SEntity)value); } else if (value is System.Collections.IList) { System.Collections.IList list = (System.Collections.IList)value; for (int i = 0; i < list.Count; i++) { TreeNode tnItem = new TreeNode(); tnItem.Tag = list[i]; tnItem.Text = (i + 1).ToString() + " = " + list[i].GetType().Name; tn.Nodes.Add(tnItem); TreeNode tnNull = new TreeNode(); tnItem.Nodes.Add(tnNull); } } } } } }
/// <summary> /// Returns true if any elements written (requiring closing tag); or false if not /// </summary> /// <param name="o"></param> /// <returns></returns> private bool WriteEntityAttributes(SEntity o) { Type t = o.GetType(); long oid = 0; if (this.m_saved.Contains(o)) { // give it an ID if needed (first pass) if (!this.m_idmap.TryGetValue(o, out oid)) { this.m_nextID++; this.m_idmap[o] = this.m_nextID; } // reference existing; return this.WriteReference(oid); return false; } // mark as saved this.m_saved.Add(o); if (this.m_idmap.TryGetValue(o, out oid)) { this.WriteIdentifier(oid); } bool previousattribute = false; // write fields as attributes bool haselements = false; IList<FieldInfo> fields = SEntity.GetFieldsAll(t); foreach (FieldInfo f in fields) { DocXsdFormat xsdformat = this.GetXsdFormat(f); if (f.IsDefined(typeof(DataMemberAttribute)) && (xsdformat == null || (xsdformat.XsdFormat != DocXsdFormatEnum.Element && xsdformat.XsdFormat != DocXsdFormatEnum.Attribute))) { // direct field Type ft = f.FieldType; bool isvaluelist = (ft.IsGenericType && ft.GetGenericTypeDefinition() == typeof(List<>) && ft.GetGenericArguments()[0].IsValueType); bool isvaluelistlist = (ft.IsGenericType && // e.g. IfcTriangulatedFaceSet.Normals ft.GetGenericTypeDefinition() == typeof(List<>) && ft.GetGenericArguments()[0].IsGenericType && ft.GetGenericArguments()[0].GetGenericTypeDefinition() == typeof(List<>) && ft.GetGenericArguments()[0].GetGenericArguments()[0].IsValueType); if (isvaluelistlist || isvaluelist || ft.IsValueType) { object v = f.GetValue(o); if (v != null) { if (previousattribute) { this.WriteAttributeDelimiter(); } previousattribute = true; this.WriteStartAttribute(f.Name); if (isvaluelistlist) { ft = ft.GetGenericArguments()[0].GetGenericArguments()[0]; FieldInfo fieldValue = ft.GetField("Value"); System.Collections.IList list = (System.Collections.IList)v; for (int i = 0; i < list.Count; i++) { System.Collections.IList listInner = (System.Collections.IList)list[i]; for (int j = 0; j < listInner.Count; j++) { if (i > 0 || j > 0) { this.m_writer.Write(" "); } object elem = listInner[j]; if (elem != null) // should never be null, but be safe { elem = fieldValue.GetValue(elem); string encodedvalue = System.Security.SecurityElement.Escape(elem.ToString()); this.m_writer.Write(encodedvalue); } } } } else if (isvaluelist) { ft = ft.GetGenericArguments()[0]; FieldInfo fieldValue = ft.GetField("Value"); System.Collections.IList list = (System.Collections.IList)v; for (int i = 0; i < list.Count; i++) { if (i > 0) { this.m_writer.Write(" "); } object elem = list[i]; if (elem != null) // should never be null, but be safe { elem = fieldValue.GetValue(elem); if (elem is byte[]) { // IfcPixelTexture.Pixels byte[] bytes = (byte[])elem; char[] s_hexchar = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; StringBuilder sb = new StringBuilder(bytes.Length * 2); for (int z = 0; z < bytes.Length; z++) { byte b = bytes[z]; sb.Append(s_hexchar[b / 0x10]); sb.Append(s_hexchar[b % 0x10]); } v = sb.ToString(); this.m_writer.Write(v); } else { string encodedvalue = System.Security.SecurityElement.Escape(elem.ToString()); this.m_writer.Write(encodedvalue); } } } } else { if (ft.IsGenericType && ft.GetGenericTypeDefinition() == typeof(Nullable<>)) { // special case for Nullable types ft = ft.GetGenericArguments()[0]; } Type typewrap = null; while (ft.IsValueType && !ft.IsPrimitive) { FieldInfo fieldValue = ft.GetField("Value"); if (fieldValue != null) { v = fieldValue.GetValue(v); if (typewrap == null) { typewrap = ft; } ft = fieldValue.FieldType; } else { break; } } if (ft.IsEnum || ft == typeof(bool)) { v = v.ToString().ToLowerInvariant(); } if (v is System.Collections.IList) { // IfcCompoundPlaneAngleMeasure System.Collections.IList list = (System.Collections.IList)v; for (int i = 0; i < list.Count; i++) { if (i > 0) { this.m_writer.Write(" "); } object elem = list[i]; if (elem != null) // should never be null, but be safe { string encodedvalue = System.Security.SecurityElement.Escape(elem.ToString()); this.m_writer.Write(encodedvalue); } } } else if (v != null) { string encodedvalue = System.Security.SecurityElement.Escape(v.ToString()); m_writer.Write(encodedvalue); //... escape it } } this.WriteEndAttribute(); } } else { haselements = true; } } else { // inverse haselements = true; } } if (haselements) { bool open = false; // write direct object references and lists foreach (FieldInfo f in fields) { DocXsdFormat format = GetXsdFormat(f); if (f.IsDefined(typeof(DataMemberAttribute)) && (format == null || (format.XsdFormat != DocXsdFormatEnum.Element && format.XsdFormat != DocXsdFormatEnum.Attribute))) { Type ft = f.FieldType; bool isvaluelist = (ft.IsGenericType && ft.GetGenericTypeDefinition() == typeof(List<>) && ft.GetGenericArguments()[0].IsValueType); bool isvaluelistlist = (ft.IsGenericType && // e.g. IfcTriangulatedFaceSet.Normals ft.GetGenericTypeDefinition() == typeof(List<>) && ft.GetGenericArguments()[0].IsGenericType && ft.GetGenericArguments()[0].GetGenericTypeDefinition() == typeof(List<>) && ft.GetGenericArguments()[0].GetGenericArguments()[0].IsValueType); // hide fields where inverse attribute used instead if (!f.FieldType.IsValueType && !isvaluelist && !isvaluelistlist && (format == null || (format.XsdFormat != DocXsdFormatEnum.Hidden))) { object value = f.GetValue(o); if (value != null) { if (!open) { WriteOpenElement(); open = true; } if (previousattribute) { this.WriteAttributeDelimiter(); } previousattribute = true; WriteAttribute(o, f, format); } } } else if (format != null && (format.XsdFormat == DocXsdFormatEnum.Element || format.XsdFormat == DocXsdFormatEnum.Attribute)) { object value = f.GetValue(o); if (value != null) { if (!open) { WriteOpenElement(); open = true; } if (previousattribute) { this.WriteAttributeDelimiter(); } previousattribute = true; WriteAttribute(o, f, format); } } else { object value = f.GetValue(o); // inverse // record it for downstream serialization if (value is System.Collections.IList) { System.Collections.IList invlist = (System.Collections.IList)value; foreach (SEntity invobj in invlist) { if (!this.m_saved.Contains(invobj)) { this.m_queue.Enqueue(invobj); } } } } } this.WriteAttributeTerminator(); return open; } else { this.WriteAttributeTerminator(); return false; } }
private void WriteEntity(SEntity o) { // sanity check if (this.m_indent > 100) { return; } if (o == null) return; Type t = o.GetType(); string hyperlink = "../../schema/" + t.Namespace.ToLower() + "/lexical/" + t.Name.ToLower() + ".htm"; this.WriteStartElementEntity(t.Name, hyperlink); bool close = this.WriteEntityAttributes(o); if (close) { this.WriteEndElementEntity(t.Name); } else { this.WriteCloseElementEntity(); } }