Ejemplo n.º 1
0
        private void WriteProperty(XmlMetaProperty property, IPersistEntity entity, XmlWriter output)
        {
            var propVal = property.MetaProperty.PropertyInfo.GetValue(entity, null);

            //handling of XML attributes is baked before
            if (property.IsAttributeValue)
            {
                property.AttributeSetter(propVal, output);
                return;
            }

            var propType = property.MetaProperty.PropertyInfo.PropertyType;
            var propName = property.MetaProperty.PropertyInfo.Name;
            var attr     = property.MetaProperty.EntityAttribute;

            WriteProperty(propName, propType, propVal, output, null, attr);
        }
Ejemplo n.º 2
0
        private void WriteProperties(IPersistEntity entity, XmlWriter output, ExpressType expressType)
        {
            List <XmlMetaProperty> properties;

            if (!_propertiesCache.TryGetValue(expressType.Type, out properties))
            {
                properties = XmlMetaProperty.GetProperties(expressType, _conf);
                //cache
                _propertiesCache.Add(expressType.Type, properties);
            }


            foreach (var property in properties) //only write out persistent attributes, ignore inverses
            {
                WriteProperty(property, entity, output);
            }
        }
Ejemplo n.º 3
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
        }
Ejemplo n.º 4
0
        private static void SetAttributeValueHandler(XmlMetaProperty metaProperty, List <entity> typeConfigurarions)
        {
            //all value types will be serialized as attributes. Nullable<> is also value type which is correct for this.
            var type = metaProperty.MetaProperty.PropertyInfo.PropertyType;

            type = GetNonNullableType(type);
            var propName = metaProperty.MetaProperty.PropertyInfo.Name;

            if (type.IsValueType || type == typeof(string))
            {
                if (typeof(IExpressComplexType).IsAssignableFrom(type))
                {
                    metaProperty.AttributeSetter = (value, writer) =>
                    {
                        if (value == null)
                        {
                            return;
                        }
                        writer.WriteAttributeString(propName, string.Join(" ", ((IExpressComplexType)value).Properties));
                    };
                }
                else if (type.IsEnum)
                {
                    metaProperty.AttributeSetter = (value, writer) =>
                    {
                        if (value == null)
                        {
                            return;
                        }
                        writer.WriteAttributeString(propName, (Enum.GetName(type, value) ?? "").ToLowerInvariant());
                    };
                }
                else
                {
                    metaProperty.AttributeSetter = (value, writer) =>
                    {
                        if (value == null)
                        {
                            return;
                        }
                        writer.WriteAttributeString(propName, value.ToString());
                    };
                }
                return;
            }

            //lists of value types will be serialized as lists. If this is not an IEnumerable this is not the case
            if (!typeof(IEnumerable).IsAssignableFrom(type) || !type.IsGenericType)
            {
                return;
            }

            var genType = type.GetGenericArguments()[0];

            if (genType.IsValueType || genType == typeof(string))
            {
                if (IsStringCompatible(genType))
                {
                    //check type configuration
                    if (typeConfigurarions != null &&
                        typeConfigurarions.Any(conf => conf.TaggLessAttributes
                                               .Any(a => a.@select == propName)))
                    {
                        metaProperty.AttributeSetter = (value, writer) =>
                        {
                            if (value == null)
                            {
                                return;
                            }
                            writer.WriteAttributeString(propName, string.Join(" ", ((IEnumerable)value).Cast <object>()));
                        };
                    }
                    //default for string is to be in a separate tags as strings might contain spaces which are
                    //used as a list separators in attribute lists
                    return;
                }
                metaProperty.AttributeSetter = (value, writer) =>
                {
                    if (value == null)
                    {
                        return;
                    }
                    writer.WriteAttributeString(propName, string.Join(" ", ((IEnumerable)value).Cast <object>()));
                };
                return;
            }

            //rectangular nested lists shall also be serialized as attribute if defined in configuration
            if (typeof(IEnumerable).IsAssignableFrom(genType) && typeConfigurarions != null &&
                typeConfigurarions.Any(conf => conf.TaggLessAttributes
                                       .Any(a => a.@select == propName)))
            {
                metaProperty.AttributeSetter = (value, writer) =>
                {
                    if (value == null)
                    {
                        return;
                    }
                    var enumeration = ((IEnumerable)value).Cast <IEnumerable>().SelectMany(o => o.Cast <object>());
                    writer.WriteAttributeString(propName, string.Join(" ", enumeration));
                };
            }
        }