public XmlSerializerGenerator(Type delegateType, Type trueType, bool update)
        {
            if (trueType == null)
            {
                trueType = delegateType;
            }

            this.delegateType = delegateType;
            this.trueType     = trueType;
            this.update       = update;
            Mappings          = XmlMapping.GetMappings(trueType).OrderBy(m => m.AttributeValue.FirstOrDefault() == "message").ToList();

            if (update)
            {
                Mappings = Mappings.Where(m =>
                {
                    var attrib = m.PropertyCache.GetAttribute <PropertyParameterAttribute>();

                    if (attrib != null && attrib.Property != null)
                    {
                        if (attrib.Property.Equals(Property.Name) || attrib.Property.Equals(Property.Id))
                        {
                            return(false);
                        }
                    }

                    return(true);
                }).ToList();
            }

            Target         = Expression.Variable(trueType, "obj"); //var obj;
            DelegateTarget = Expression.Parameter(delegateType, "obj");
        }
        private bool BuildConditions(XmlMapping mapping, int i, ref int mappingNameIndex, ref List <ConditionalExpression> result)
        {
            var type = Mappings[i].PropertyCache.Property.PropertyType;

            if (type.IsValueType && Nullable.GetUnderlyingType(type) == null)
            {
                var flagIndex = Expression.Constant(i);
                var flag      = Expression.ArrayIndex(XmlExpressionConstants.SerializerFlags, flagIndex); //flagArray[0]

                var nameIndex = Expression.Constant(mappingNameIndex);
                var name      = Expression.ArrayIndex(XmlExpressionConstants.SerializerNames, nameIndex);

                var assignName = XmlExpressionConstants.Serializer_Name(mapping.AttributeType).Assign(name);

                var throwNull = XmlExpressionConstants.Fail(null, type).Throw();                        //throw Fail(null, null, typeof(int));

                var block = Expression.Block(
                    assignName,
                    throwNull
                    );

                var condition = flag.Not().IfThen(block);

                result.Add(condition);
            }

            return(false);
        }
 public ValueDeserializer(
     XmlMapping mapping,
     XmlSerializerGenerator generator,
     Expression str)
 {
     this.mapping   = mapping;
     this.generator = generator;
     PropertyType   = mapping.PropertyCache.Property.PropertyType;
     valueConverter = GetValueConverter();
     readStr        = str;
 }
        private bool BuildTextConditions(XmlMapping mapping, int i, ref int mappingNameIndex, ref List <ConditionalExpression> result)
        {
            if (mapping.AttributeType == XmlAttributeType.Text)
            {
                var blockBuilder = new LadderCondition(mapping, i, this);

                var condition = blockBuilder.GetCondition(ref mappingNameIndex);

                result.Add(condition);
                return(true);
            }

            return(false);
        }
Example #5
0
        //todo: profile the performance of my method vs the .net method

        private void ProcessXmlAttribute(object obj, XmlMapping mapping, XElement elm)
        {
            var value = mapping.GetSingleXAttributeAttributeValue(elm);

            try
            {
                value = NullifyMissingValue(value);
                var finalValue = GetValue(value, mapping.PropertyCache, value?.Value, elm);

                mapping.PropertyCache.SetValue(obj, finalValue);
            }
            catch (Exception ex) when(!(ex is XmlDeserializationException))
            {
                throw new XmlDeserializationException(mapping.PropertyCache.Property.PropertyType.GetUnderlyingType(), XmlAttributeExceptionNode(value), ex);
            }
        }
Example #6
0
        private void ProcessSingleXmlElement(object obj, XmlMapping mapping, XElement elm)
        {
            var value = mapping.GetSingleXElementAttributeValue(elm);

            //priority is priority_raw on the root group, priority everywhere else. we need an alt xmlelement
            //ok we have one, we now need to treat attributevalue as a list

            try
            {
                ProcessXmlText(obj, mapping, value);
            }
            catch (Exception ex) when(!(ex is XmlDeserializationException))
            {
                throw new XmlDeserializationException(mapping.PropertyCache.Property.PropertyType.GetUnderlyingType(), value?.ToString() ?? "null", ex);
            }
        }
Example #7
0
        private void ProcessListEnumerableXmlElement(object obj, XmlMapping mapping, XElement elm)
        {
            var type           = mapping.PropertyCache.Property.PropertyType;
            var underlyingType = type.GetGenericArguments().First();

            var list = Activator.CreateInstance(type);

            var elms = mapping.AttributeValue.Select(a => elm.Elements(a)).First(x => x != null).ToList();

            foreach (var e in elms)
            {
                ((IList)list).Add(Deserialize(underlyingType, e));
            }

            mapping.PropertyCache.Property.SetValue(obj, list);
        }
Example #8
0
        private void ProcessXmlText(object obj, XmlMapping mapping, XElement elm)
        {
            var type = mapping.PropertyCache.Property.PropertyType;

            elm = NullifyMissingValue(elm);

            var finalValue = GetValue(elm, mapping.PropertyCache, elm?.Value, elm);

            if (type.IsValueType && Nullable.GetUnderlyingType(type) == null && finalValue == null)
            {
                if (!deserializeAll)
                {
                    return;
                }

                throw new XmlDeserializationException($"An error occurred while attempting to deserialize XML element '{mapping.AttributeValue.First()}' to property '{mapping.PropertyCache.Property.Name}': cannot assign 'null' to value type '{type.Name}'."); //value types cant be null
            }

            mapping.PropertyCache.SetValue(obj, finalValue);
        }
Example #9
0
        private void ProcessNonListEnumerableXmlElement(object obj, XmlMapping mapping, XElement elm)
        {
            var attribute = mapping.PropertyCache.GetAttribute <SplittableStringAttribute>();

            if (attribute != null)
            {
                var value = mapping.AttributeValue.Select(a => elm.Element(a)).FirstOrDefault(x => x != null);

                value = NullifyMissingValue(value);

                object finalVal = value;

                if (value != null)
                {
                    finalVal = value.Value.Trim().Split(new[] { attribute.Character }, StringSplitOptions.RemoveEmptyEntries);
                }

                mapping.PropertyCache.Property.SetValue(obj, finalVal);
            }
            else
            {
                throw new NotSupportedException(); //todo: add an appropriate failure message
            }
        }
Example #10
0
        private void ProcessXmlElement(object obj, XmlMapping mapping, XElement elm)
        {
            var type = mapping.PropertyCache.Property.PropertyType;

            if (typeof(IEnumerable).IsAssignableFrom(type) && type != typeof(string))
            {
                ProcessEnumerableXmlElement(obj, mapping, elm);
            }
            else
            {
                if (mapping.PropertyCache.Property.PropertyType.GetTypeCache().GetAttribute <XmlRootAttribute>() != null)
                {
                    var elms = mapping.AttributeValue.Select(a => elm.Elements(a)).First(x => x != null).FirstOrDefault();

                    var result = elms != null?Deserialize(mapping.PropertyCache.Property.PropertyType, elms) : null;

                    mapping.PropertyCache.Property.SetValue(obj, result);
                }
                else
                {
                    ProcessSingleXmlElement(obj, mapping, elm);
                }
            }
        }
        private Expression GetTextBlock(XmlMapping mapping)
        {
            var body = ForEachMappingValue <ConditionalExpression>(BuildTextConditions).Single().IfTrue;

            return(body);
        }
Example #12
0
        private Expression GetCaseBody(Enum property, Expression rawValue)
        {
            var viaObject = false;

            var typeLookup = property.GetEnumAttribute <TypeLookupAttribute>()?.Class; //ObjectPropertyInternal members don't necessarily have a type lookup

            if (typeLookup == null)
            {
                return(null);
            }

            var mappings   = ReflectionCacheManager.Map(typeLookup).Cache;
            var cache      = ObjectPropertyParser.GetPropertyInfoViaTypeLookup(property);
            var xmlElement = cache.GetAttribute <XmlElementAttribute>(); //todo: what if this objectproperty doesnt point to a member with an xmlelementattribute?

            XmlMapping mapping = null;

            if (xmlElement != null)
            {
                mapping = mappings.FirstOrDefault(m => m.AttributeValue[0] == xmlElement.ElementName);
            }
            else
            {
                var mergeAttribute = property.GetEnumAttribute <MergeableAttribute>();

                //If we're a property like LocationName, we don't exist server side - we're only used for constructing requests
                if (mergeAttribute != null)
                {
                    return(null);
                }

                //We have a property like Interval which uses a backing property instead.
                //Get the backing property so that we may extract the real value from the public
                //property
                var rawName     = ObjectPropertyParser.GetObjectPropertyNameViaCache(property, cache);
                var elementName = $"{HtmlParser.DefaultPropertyPrefix}{rawName.TrimEnd('_')}";

                mapping = mappings.FirstOrDefault(m => m.AttributeValue[0] == elementName);

                if (mapping != null)
                {
                    viaObject = true;
                }
            }

            if (mapping != null)
            {
                var deserializer = new ValueDeserializer(mapping, null, rawValue);
                var result       = deserializer.Deserialize();

                if (viaObject)
                {
                    //Construct an expression like return new TableSettings { intervalStr = "60|60 seconds" }.Interval;
                    var settingsObj    = Expression.Variable(typeLookup, "obj");
                    var assignObj      = settingsObj.Assign(Expression.New(typeLookup));
                    var internalProp   = Expression.MakeMemberAccess(settingsObj, mapping.PropertyCache.Property);
                    var assignInternal = internalProp.Assign(result);
                    var externalProp   = Expression.MakeMemberAccess(settingsObj, cache.Property);

                    return(Expression.Block(
                               new[] { settingsObj },
                               assignObj,
                               assignInternal,
                               Expression.Convert(externalProp, typeof(object))
                               ));
                }

                return(result);
            }

            //Property is not deserializable
            return(null);
        }
 public ValueDeserializer(XmlMapping mapping, XmlSerializerGenerator generator) : this(mapping, generator, null)
 {
     readStr = ReadString();
 }