Ejemplo n.º 1
0
        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
        }