private void WriteProperty(string propName, Type propType, object propVal, object entity, XmlWriter output, int pos, EntityAttributeAttribute attr) { var optSet = propVal as IOptionalItemSet; if (optSet != null && !optSet.Initialized) { //don't write anything if this is uninitialized item set return; } if (propVal == null) //null or a value type that maybe null, need to write out sets and lists if they are mandatroy but empty { if (typeof(IExpressEnumerable).GetTypeInfo().IsAssignableFrom(propType) && attr.State == EntityAttributeState.Mandatory) //special case as these two classes are optimised { output.WriteStartElement(propName); output.WriteAttributeString("ex", "cType", null, attr.ListType); output.WriteEndElement(); } return; } if (propType.GetTypeInfo().IsGenericType&& propType.GetGenericTypeDefinition() == typeof(Nullable <>) && (propVal is IExpressValueType)) //deal with undefined types (nullables) { if (string.IsNullOrEmpty((propVal).ToString())) { output.WriteElementString(propName, (propVal).ToString()); } else { output.WriteStartElement(propName); if (pos > -1) { output.WriteAttributeString("pos", pos.ToString()); } var val = propVal as IExpressComplexType; if (val != null) { var complexProps = val.Properties; var wrapPos = 0; foreach (var complexProp in complexProps) { WriteProperty(propName, complexProp.GetType(), complexProp, entity, output, wrapPos, attr); wrapPos++; } } else { output.WriteValue((propVal).ToString()); } output.WriteEndElement(); } } else if (typeof(IExpressValueType).GetTypeInfo().IsAssignableFrom(propType)) { var realType = propVal.GetType(); if (realType != propType) //we have a type but it is a select type use the actual value but write out explicitly { output.WriteStartElement(propName); WriteProperty(realType.Name, realType, propVal, entity, output, pos, attr); output.WriteEndElement(); } else { if (pos > -1) { output.WriteStartElement(propName); output.WriteAttributeString("pos", pos.ToString()); output.WriteValue((propVal).ToString()); output.WriteEndElement(); } // if its nullable //if (((ExpressType)propVal).ToPart21 != "$") else { output.WriteElementString(propName, (propVal).ToString()); } } } else if (typeof(IExpressEnumerable).GetTypeInfo().IsAssignableFrom(propType)) { output.WriteStartElement(propName); output.WriteAttributeString("ex", "cType", null, attr.ListType); var i = 0; foreach (var item in ((IExpressEnumerable)propVal)) { WriteProperty(item.GetType().Name, item.GetType(), item, entity, output, i, attr); i++; } output.WriteEndElement(); } else if (typeof(IPersistEntity).GetTypeInfo().IsAssignableFrom(propType)) //all writable entities must support this interface and ExpressType have been handled so only entities left { var persistVal = (IPersistEntity)propVal; if (pos == -1) { output.WriteStartElement(propName); } if (_written.Contains(persistVal.EntityLabel)) //we have already written it so use an xlink { output.WriteStartElement(propVal.GetType().Name); output.WriteAttributeString("ref", string.Format("i{0}", persistVal.EntityLabel)); output.WriteAttributeString("xsi", "nil", null, "true"); if (pos > -1) //we are writing out a list element { output.WriteAttributeString("pos", pos.ToString()); } output.WriteEndElement(); } else { Write(persistVal, output, pos); } if (pos == -1) { output.WriteEndElement(); } } else if (typeof(IExpressComplexType).GetTypeInfo().IsAssignableFrom(propType)) //it is a complex value tpye { var properties = ((IExpressComplexType)propVal).Properties; } else if (propType.GetTypeInfo().IsValueType || propType == typeof(string) || propType == typeof(byte[])) //it might be an in-built value type double, string etc { var pInfoType = propVal.GetType(); if (pInfoType.GetTypeInfo().IsEnum) //convert enum { if (pos > -1) { output.WriteStartElement(propName); output.WriteAttributeString("pos", pos.ToString()); } else { output.WriteStartElement(propName); } output.WriteValue(propVal.ToString().ToLower()); } else if (pInfoType.GetTypeInfo().UnderlyingSystemType == typeof(Boolean)) { if (pos > -1) { output.WriteStartElement("ex", "boolean-wrapper", null); output.WriteAttributeString("pos", pos.ToString()); } else { output.WriteStartElement(propName); } output.WriteValue((bool)propVal ? "true" : "false"); } else if (pInfoType.GetTypeInfo().UnderlyingSystemType == typeof(Double)) { if (pos > -1) { output.WriteStartElement("ex", "double-wrapper", null); output.WriteAttributeString("pos", pos.ToString()); } else { output.WriteStartElement(propName); } output.WriteValue(string.Format(new Part21Formatter(), "{0:R}", propVal)); } else if (pInfoType.GetTypeInfo().UnderlyingSystemType == typeof(Int16)) { if (pos > -1) { output.WriteStartElement("ex", "integer-wrapper", null); output.WriteAttributeString("pos", pos.ToString()); } else { output.WriteStartElement(propName); } output.WriteValue(propVal.ToString()); } else if (pInfoType.GetTypeInfo().UnderlyingSystemType == typeof(Int32) || pInfoType.GetTypeInfo().UnderlyingSystemType == typeof(Int64)) { if (pos > -1) { output.WriteStartElement("ex", "long-wrapper", null); output.WriteAttributeString("pos", pos.ToString()); } else { output.WriteStartElement(propName); } output.WriteValue(propVal.ToString()); } else if (pInfoType.GetTypeInfo().UnderlyingSystemType == typeof(String)) //convert string { if (pos > -1) { output.WriteStartElement("ex", "string-wrapper", null); output.WriteAttributeString("pos", pos.ToString()); } else { output.WriteStartElement(propName); } output.WriteValue(string.Format(new Part21Formatter(), "{0}", propVal)); } else if (pInfoType.GetTypeInfo().UnderlyingSystemType == typeof(byte[])) //convert byte array { if (pos > -1) { output.WriteStartElement("ex", "hexBinary-wrapper", null); output.WriteAttributeString("pos", pos.ToString()); } else { output.WriteStartElement(propName); } var ba = (byte[])propVal; var hex = new System.Text.StringBuilder(ba.Length * 2); foreach (byte b in ba) { hex.AppendFormat("{0:X2}", b); } output.WriteValue(hex.ToString()); } else { throw new ArgumentException(string.Format("Invalid Value Type {0}", pInfoType.Name), "pInfoType"); } output.WriteEndElement(); } else if (typeof(IExpressSelectType).GetTypeInfo().IsAssignableFrom(propType)) // a select type get the type of the actual value { if (propVal != null) { var realType = propVal.GetType(); output.WriteStartElement(propName); if (typeof(IExpressValueType).GetTypeInfo().IsAssignableFrom(realType)) { //WriteProperty(model, realType.Name + "-wrapper", realType, propVal, entity, output, pos, attr); WriteProperty(realType.Name, realType, propVal, entity, output, pos, attr); } else { WriteProperty(realType.Name, realType, propVal, entity, output, -2, attr); } } output.WriteEndElement(); } //else // throw new Exception(string.Format("Entity of type {0} has illegal property {1} of type {2}", entity.GetType().ToString(), propType.Name, propType.Name)); }
public IfcEntityAttribute(string propertyName, string typeName, EntityAttributeAttribute attributeAttributeProperties) { PropertyName = propertyName; TypeName = typeName; AttributeAttributeProperties = attributeAttributeProperties; }
private void WriteProperty(string propName, Type propType, object propVal, XmlWriter output, int[] pos, EntityAttributeAttribute attr, bool wrap = false) { //don't write anything if this is uninitialized optional item set var optSet = propVal as IOptionalItemSet; if (optSet != null && !optSet.Initialized) { return; } //null or a value type that maybe null, need to write out sets and lists if they are mandatroy but empty if (propVal == null) { if (!typeof(IExpressEnumerable).GetTypeInfo().IsAssignableFrom(propType) || attr.State != EntityAttributeState.Mandatory) { return; } //write out empty mandatory set with proper enumeration type output.WriteStartElement(propName); //output.WriteAttributeString("cType", attr.ListType); output.WriteEndElement(); return; } if (propType.GetTypeInfo().IsInterface&& typeof(IExpressSelectType).GetTypeInfo().IsAssignableFrom(propType)) // a select type get the type of the actual value { var realType = propVal.GetType(); var exprType = _metadata.ExpressType(realType); var realName = exprType != null ? exprType.ExpressName : realType.Name; output.WriteStartElement(propName); WriteProperty(realName, realType, propVal, output, null, attr, true); output.WriteEndElement(); return; } //make sure we don't mess around with nullables propType = XmlMetaProperty.GetNonNullableType(propType); if (typeof(IExpressValueType).GetTypeInfo().IsAssignableFrom(propType)) { var cpl = propVal as IExpressComplexType; if (cpl != null) { var expT = _metadata.ExpressType(propVal.GetType()); if (expT != null && expT.UnderlyingType != null && typeof(IEnumerable <IPersistEntity>).GetTypeInfo().IsAssignableFrom(expT.UnderlyingType)) { output.WriteStartElement(expT.ExpressName + (wrap ? "-wrapper" : "")); var idx = new[] { 0 }; foreach (var ent in cpl.Properties.Cast <IPersistEntity>()) { WriteEntity(ent, output, false, idx); idx[0]++; } output.WriteEndElement(); return; } } var valString = cpl == null ? propVal.ToString() : string.Join(" ", cpl.Properties); output.WriteStartElement(propName + (wrap ? "-wrapper" : "")); if (pos != null) { output.WriteAttributeString("pos", string.Join(" ", pos)); } output.WriteValue(valString); output.WriteEndElement(); return; } if (typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(propType) && propType != typeof(string)) { //special case for IfcRelDefinesByProperties //if (propName == "RelatedObjects" && entity.ExpressType.Name == "IfcRelDefinesByProperties") if (attr.MaxCardinality != null && attr.MaxCardinality.Length == 1 && attr.MaxCardinality[0] == 1) //list which shouldn't have more than 1 element in is serialized as a single element { propVal = ((IEnumerable)propVal).Cast <object>().FirstOrDefault(); var relEntity = propVal as IPersistEntity; if (relEntity == null) { return; } WriteEntity(relEntity, output, false, null, propName); return; } var propValEnum = ((IEnumerable)propVal).Cast <object>().ToList(); //inverse attribute with no values if (attr.Order < 0 && !propValEnum.Any()) { return; } var idx = new List <int>(pos ?? new int[] {}) { 0 }; var depth = idx.Count - 1; if (depth == 0) { output.WriteStartElement(propName); //output.WriteAttributeString(_nsPrefix, "cType", _ns, attr.ListType); } foreach (var item in propValEnum) { var expT = _metadata.ExpressType(item.GetType()); var name = expT != null ? expT.ExpressName : item.GetType().Name; WriteProperty(name, item.GetType(), item, output, idx.ToArray(), attr, true); idx[depth]++; } if (depth == 0) { output.WriteEndElement(); } return; } if (typeof(IPersistEntity).GetTypeInfo().IsAssignableFrom(propType)) { var persistEntity = (IPersistEntity)propVal; WriteEntity(persistEntity, output, false, pos, propName); return; } //this will only be called from within the enumeration //as otherwise it will be serialized as XML attribute before if (propType.GetTypeInfo().IsValueType || typeof(string) == propType || typeof(byte[]) == propType) { var pInfoType = propVal.GetType(); string pValue; if (pInfoType.GetTypeInfo().IsEnum) //convert enum { output.WriteStartElement(propName); pValue = propVal.ToString().ToLower(); } else if (pInfoType.GetTypeInfo().UnderlyingSystemType == typeof(Boolean)) { output.WriteStartElement("boolean-wrapper"); pValue = (bool)propVal ? "true" : "false"; } else if (pInfoType.GetTypeInfo().UnderlyingSystemType == typeof(Double) || pInfoType.GetTypeInfo().UnderlyingSystemType == typeof(Single)) { output.WriteStartElement("double-wrapper"); pValue = string.Format(new Part21Formatter(), "{0:R}", propVal); } else if (pInfoType.GetTypeInfo().UnderlyingSystemType == typeof(Int16)) { output.WriteStartElement("integer-wrapper"); pValue = propVal.ToString(); } else if (pInfoType.GetTypeInfo().UnderlyingSystemType == typeof(Int32) || pInfoType.GetTypeInfo().UnderlyingSystemType == typeof(Int64)) { output.WriteStartElement("long-wrapper"); pValue = propVal.ToString(); } else if (pInfoType.GetTypeInfo().UnderlyingSystemType == typeof(String)) //convert string { output.WriteStartElement("string-wrapper"); pValue = string.Format(new Part21Formatter(), "{0}", propVal); } else if (pInfoType.GetTypeInfo().UnderlyingSystemType == typeof(byte[])) { output.WriteStartElement("hexBinary-wrapper"); var ba = (byte[])propVal; var hex = new System.Text.StringBuilder(ba.Length * 2); foreach (byte b in ba) { hex.AppendFormat("{0:X2}", b); } pValue = hex.ToString(); } else { throw new NotSupportedException(string.Format("Invalid Value Type {0}", pInfoType.Name)); } output.WriteAttributeString("pos", string.Join(" ", pos)); output.WriteValue(pValue); output.WriteEndElement(); return; } #if DEBUG throw new Exception("Unexpected type"); #endif }