Inheritance: YAXBaseAttribute
Example #1
0
        /// <summary>
        /// Creates a dictionary element according to the specified options, as described
        /// by the attribute instances.
        /// </summary>
        /// <param name="insertionLocation">The insertion location.</param>
        /// <param name="elementName">Name of the element.</param>
        /// <param name="elementValue">The element value, corresponding to a dictionary object.</param>
        /// <param name="dicAttrInst">reference to the dictionary attribute instance.</param>
        /// <param name="collectionAttrInst">reference to collection attribute instance.</param>
        /// <returns>
        /// an instance of <c>XElement</c> which contains the dictionary object
        /// serialized properly
        /// </returns>
        private XElement MakeDictionaryElement(
            XElement insertionLocation,
            XName elementName,
            object elementValue,
            YAXDictionaryAttribute dicAttrInst,
            YAXCollectionAttribute collectionAttrInst)
        {
            if (elementValue == null)
            {
                return new XElement(elementName, elementValue);
            }

            Type keyType, valueType;
            if (!ReflectionUtils.IsIDictionary(elementValue.GetType(), out keyType, out valueType))
            {
                throw new ArgumentException("elementValue must be a Dictionary");
            }

            var dicInst = elementValue as IEnumerable;
            bool isKeyAttrib = false;
            bool isValueAttrib = false;
            bool isKeyContent = false;
            bool isValueContent = false;
            string keyFormat = null;
            string valueFormat = null;
            XName keyAlias = elementName.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone() + "Key";
            XName valueAlias = elementName.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone() + "Value";

            XName eachElementName = null;
            if (collectionAttrInst != null && !String.IsNullOrEmpty(collectionAttrInst.EachElementName))
            {
                eachElementName = StringUtils.RefineSingleElement(collectionAttrInst.EachElementName);
                if (eachElementName.Namespace.HasNamespace())
                    RegisterNamespace(eachElementName.Namespace, null);
                eachElementName = eachElementName.OverrideNsIfEmpty(elementName.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone());
            }

            if (dicAttrInst != null)
            {
                if (dicAttrInst.EachPairName != null)
                {
                    eachElementName = StringUtils.RefineSingleElement(dicAttrInst.EachPairName);
                    if (eachElementName.Namespace.HasNamespace())
                        RegisterNamespace(eachElementName.Namespace, null);
                    eachElementName = eachElementName.OverrideNsIfEmpty(elementName.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone());
                }

                if (dicAttrInst.SerializeKeyAs == YAXNodeTypes.Attribute)
                {
                    isKeyAttrib = ReflectionUtils.IsBasicType(keyType);
                }
                else if (dicAttrInst.SerializeKeyAs == YAXNodeTypes.Content)
                {
                    isKeyContent = ReflectionUtils.IsBasicType(keyType);
                }

                if (dicAttrInst.SerializeValueAs == YAXNodeTypes.Attribute)
                {
                    isValueAttrib = ReflectionUtils.IsBasicType(valueType);
                }
                else if (dicAttrInst.SerializeValueAs == YAXNodeTypes.Content)
                {
                    isValueContent = ReflectionUtils.IsBasicType(valueType);
                }

                keyFormat = dicAttrInst.KeyFormatString;
                valueFormat = dicAttrInst.ValueFormatString;

                keyAlias = StringUtils.RefineSingleElement(dicAttrInst.KeyName ?? "Key");
                if (keyAlias.Namespace.HasNamespace())
                    RegisterNamespace(keyAlias.Namespace, null);
                keyAlias = keyAlias.OverrideNsIfEmpty(elementName.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone());

                valueAlias = StringUtils.RefineSingleElement(dicAttrInst.ValueName ?? "Value");
                if (valueAlias.Namespace.HasNamespace())
                    RegisterNamespace(valueAlias.Namespace, null);
                valueAlias = valueAlias.OverrideNsIfEmpty(elementName.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone());
            }

            XElement elem = new XElement(elementName, null);

            foreach (object obj in dicInst)
            {
                object keyObj = obj.GetType().GetProperty("Key").GetValue(obj, null);
                object valueObj = obj.GetType().GetProperty("Value").GetValue(obj, null);

                bool areKeyOfSameType = true;
                bool areValueOfSameType = true;

                if (keyObj != null && !keyObj.GetType().EqualsOrIsNullableOf(keyType))
                    areKeyOfSameType = false;

                if (valueObj != null && !valueObj.GetType().EqualsOrIsNullableOf(valueType))
                    areValueOfSameType = false;

                if (keyFormat != null)
                {
                    keyObj = ReflectionUtils.TryFormatObject(keyObj, keyFormat);
                }

                if (valueFormat != null)
                {
                    valueObj = ReflectionUtils.TryFormatObject(valueObj, valueFormat);
                }

                if (eachElementName == null)
                {
                    eachElementName = StringUtils.RefineSingleElement(ReflectionUtils.GetTypeFriendlyName(obj.GetType()));
                    eachElementName = eachElementName.OverrideNsIfEmpty(elementName.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone());
                }

                XElement elemChild = new XElement(eachElementName, null);

                if (isKeyAttrib && areKeyOfSameType)
                {
                    elemChild.AddAttributeNamespaceSafe(keyAlias, keyObj);
                }
                else if (isKeyContent && areKeyOfSameType)
                {
                    elemChild.AddXmlContent(keyObj);
                }
                else
                {
                    XElement addedElem = AddObjectToElement(elemChild, keyAlias, keyObj);
                    if (!areKeyOfSameType)
                    {
                        if (addedElem.Parent == null)
                        {
                            // sometimes empty elements are removed because its members are serialized in
                            // other elements, therefore we need to make sure to re-add the element.
                            elemChild.Add(addedElem);
                        }

                        addedElem.AddAttributeNamespaceSafe(m_yaxLibNamespaceUri + m_trueTypeAttrName, keyObj.GetType().FullName);
                        RegisterYaxLibNamespace();
                    }
                }

                if (isValueAttrib && areValueOfSameType)
                {
                    elemChild.AddAttributeNamespaceSafe(valueAlias, valueObj);
                }
                else if (isValueContent && areValueOfSameType)
                {
                    elemChild.AddXmlContent(valueObj);
                }
                else
                {
                    XElement addedElem = AddObjectToElement(elemChild, valueAlias, valueObj);
                    if (!areValueOfSameType)
                    {
                        if (addedElem.Parent == null)
                        {
                            // sometimes empty elements are removed because its members are serialized in
                            // other elements, therefore we need to make sure to re-add the element.
                            elemChild.Add(addedElem);
                        }

                        addedElem.AddAttributeNamespaceSafe(m_yaxLibNamespaceUri + m_trueTypeAttrName, valueObj.GetType().FullName);
                        RegisterYaxLibNamespace();
                    }
                }

                elem.Add(elemChild);
            }

            return elem;
        }
Example #2
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="MemberWrapper" /> class.
        /// </summary>
        /// <param name="memberInfo">The member-info to build this instance from.</param>
        /// <param name="callerSerializer">The caller serializer.</param>
        public MemberWrapper(MemberInfo memberInfo, YAXSerializer callerSerializer)
        {
            Order = int.MaxValue;

            if (!(memberInfo.MemberType == MemberTypes.Property || memberInfo.MemberType == MemberTypes.Field))
            {
                throw new Exception("Member must be either property or field");
            }

            _memberInfo = memberInfo;
            _isProperty = memberInfo.MemberType == MemberTypes.Property;

            Alias = StringUtils.RefineSingleElement(_memberInfo.Name);

            if (_isProperty)
            {
                _propertyInfoInstance = (PropertyInfo)memberInfo;
            }
            else
            {
                _fieldInfoInstance = (FieldInfo)memberInfo;
            }

            _memberType = _isProperty ? _propertyInfoInstance.PropertyType : _fieldInfoInstance.FieldType;

            _memberTypeWrapper = TypeWrappersPool.Pool.GetTypeWrapper(MemberType, callerSerializer);
            if (_memberTypeWrapper.HasNamespace)
            {
                Namespace       = _memberTypeWrapper.Namespace;
                NamespacePrefix = _memberTypeWrapper.NamespacePrefix;
            }

            InitInstance();

            TreatErrorsAs = callerSerializer != null ? callerSerializer.DefaultExceptionType : YAXExceptionTypes.Error;

            // discover YAXCustomSerializerAttributes earlier, because some other attributes depend on it
            var attrsToProcessEarlier = new HashSet <Type>
            {
                typeof(YAXCustomSerializerAttribute), typeof(YAXCollectionAttribute)
            };

            foreach (var attrType in attrsToProcessEarlier)
            {
                var customSerAttrs = Attribute.GetCustomAttributes(_memberInfo, attrType, true);
                foreach (var attr in customSerAttrs)
                {
                    ProcessYaxAttribute(attr);
                }
            }

            foreach (var attr in Attribute.GetCustomAttributes(_memberInfo, true))
            {
                // no need to process, it has been processed earlier
                if (attrsToProcessEarlier.Contains(attr.GetType()))
                {
                    continue;
                }

                if (attr is YAXBaseAttribute)
                {
                    ProcessYaxAttribute(attr);
                }
            }

            // now override some values from member-type-wrapper into member-wrapper
            // if member-type has collection attributes while the member itself does not have them,
            // then use those of the member-type
            if (_collectionAttributeInstance == null && _memberTypeWrapper.CollectionAttributeInstance != null)
            {
                _collectionAttributeInstance = _memberTypeWrapper.CollectionAttributeInstance;
            }
            _memberInfo.GetCustomAttributes(true);

            if (_dictionaryAttributeInstance == null && _memberTypeWrapper.DictionaryAttributeInstance != null)
            {
                _dictionaryAttributeInstance = _memberTypeWrapper.DictionaryAttributeInstance;
            }
        }
Example #3
0
        private object DeserializeTaggedDictionaryValue(XElement xelemValue, XName alias, Type type, 
            YAXCollectionAttribute colAttributeInstance, YAXDictionaryAttribute dicAttrInstance)
        {
            // otherwise the "else if(member.IsTreatedAsCollection)" block solves the problem
            Type keyType, valueType;
            if (!ReflectionUtils.IsIDictionary(type, out keyType, out valueType))
            {
                throw new Exception("elemValue must be a Dictionary");
            }

            Type pairType = null;
            ReflectionUtils.IsIEnumerable(type, out pairType);
            XName eachElementName = StringUtils.RefineSingleElement(ReflectionUtils.GetTypeFriendlyName(pairType));
            bool isKeyAttrib = false;
            bool isValueAttrib = false;
            bool isKeyContent = false;
            bool isValueContent = false;
            XName keyAlias = alias.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone() + "Key";
            XName valueAlias = alias.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone() + "Value";

            if (colAttributeInstance != null && colAttributeInstance.EachElementName != null)
            {
                eachElementName = StringUtils.RefineSingleElement(colAttributeInstance.EachElementName);
                eachElementName = eachElementName.OverrideNsIfEmpty(alias.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone());
            }

            if (dicAttrInstance != null)
            {
                if (dicAttrInstance.EachPairName != null)
                {
                    eachElementName = StringUtils.RefineSingleElement(dicAttrInstance.EachPairName);
                    eachElementName = eachElementName.OverrideNsIfEmpty(alias.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone());
                }

                if (dicAttrInstance.SerializeKeyAs == YAXNodeTypes.Attribute)
                {
                    isKeyAttrib = ReflectionUtils.IsBasicType(keyType);
                }
                else if (dicAttrInstance.SerializeKeyAs == YAXNodeTypes.Content)
                {
                    isKeyContent = ReflectionUtils.IsBasicType(keyType);
                }

                if (dicAttrInstance.SerializeValueAs == YAXNodeTypes.Attribute)
                {
                    isValueAttrib = ReflectionUtils.IsBasicType(valueType);
                }
                else if (dicAttrInstance.SerializeValueAs == YAXNodeTypes.Content)
                {
                    isValueContent = ReflectionUtils.IsBasicType(valueType);
                }

                if (dicAttrInstance.KeyName != null)
                {
                    keyAlias = StringUtils.RefineSingleElement(dicAttrInstance.KeyName);
                    keyAlias = keyAlias.OverrideNsIfEmpty(alias.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone());
                }
                if (dicAttrInstance.ValueName != null)
                {
                    valueAlias = StringUtils.RefineSingleElement(dicAttrInstance.ValueName);
                    valueAlias = valueAlias.OverrideNsIfEmpty(alias.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone());
                }
            }

            object dic = type.InvokeMember(string.Empty, System.Reflection.BindingFlags.CreateInstance, null, null, new object[0]);

            foreach (XElement childElem in xelemValue.Elements(eachElementName))
            {
                object key = null, value = null;
                YAXSerializer keySer = null, valueSer = null;

                bool isKeyFound = VerifyDictionaryPairElements(ref keyType, ref isKeyAttrib, ref isKeyContent, keyAlias, childElem);
                bool isValueFound = VerifyDictionaryPairElements(ref valueType, ref isValueAttrib, ref isValueContent, valueAlias, childElem);

                if (!isKeyFound && !isValueFound)
                    continue;

                if (isKeyFound)
                {
                    if (isKeyAttrib)
                    {
                        key = ReflectionUtils.ConvertBasicType(childElem.Attribute_NamespaceSafe(keyAlias).Value, keyType);
                    }
                    else if (isKeyContent)
                    {
                        key = ReflectionUtils.ConvertBasicType(childElem.GetXmlContent(), keyType);
                    }
                    else if (ReflectionUtils.IsBasicType(keyType))
                    {
                        key = ReflectionUtils.ConvertBasicType(childElem.Element(keyAlias).Value, keyType);
                    }
                    else
                    {
                        if (keySer == null)
                        {
                            keySer = new YAXSerializer(keyType, m_exceptionPolicy, m_defaultExceptionType, m_serializationOption);
                            keySer.SetNamespaceToOverrideEmptyNamespace(keyAlias.Namespace);
                        }

                        key = keySer.DeserializeBase(childElem.Element(keyAlias));
                        m_parsingErrors.AddRange(keySer.ParsingErrors);
                    }
                }

                if (isValueFound)
                {
                    if (isValueAttrib)
                    {
                        value = ReflectionUtils.ConvertBasicType(childElem.Attribute_NamespaceSafe(valueAlias).Value, valueType);
                    }
                    else if (isValueContent)
                    {
                        value = ReflectionUtils.ConvertBasicType(childElem.GetXmlContent(), valueType);
                    }
                    else if (ReflectionUtils.IsBasicType(valueType))
                    {
                        value = ReflectionUtils.ConvertBasicType(childElem.Element(valueAlias).Value, valueType);
                    }
                    else
                    {
                        if (valueSer == null)
                        {
                            valueSer = new YAXSerializer(valueType, m_exceptionPolicy, m_defaultExceptionType, m_serializationOption);
                            valueSer.SetNamespaceToOverrideEmptyNamespace(valueAlias.Namespace);
                        }

                        value = valueSer.DeserializeBase(childElem.Element(valueAlias));
                        m_parsingErrors.AddRange(valueSer.ParsingErrors);
                    }
                }

                try
                {
                    type.InvokeMember("Add", BindingFlags.InvokeMethod, null, dic, new object[] { key, value });
                }
                catch
                {
                    this.OnExceptionOccurred(
                        new YAXCannotAddObjectToCollection(alias.LocalName, new KeyValuePair<object, object>(key, value)),
                        m_defaultExceptionType);
                }
            }

            return dic;
        }
Example #4
0
        /// <summary>
        /// Processes the specified attribute which is an instance of <c>YAXAttribute</c>.
        /// </summary>
        /// <param name="attr">The attribute to process.</param>
        private void ProcessYaxAttribute(object attr)
        {
            if (attr is YAXCommentAttribute)
            {
                string comment = (attr as YAXCommentAttribute).Comment;
                if (!String.IsNullOrEmpty(comment))
                {
                    string[] comments = comment.Split(new [] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < comments.Length; i++)
                    {
                        comments[i] = String.Format(" {0} ", comments[i].Trim());
                    }

                    this.Comment = comments;
                }
            }
            else if (attr is YAXSerializableFieldAttribute)
            {
                IsAttributedAsSerializable = true;
            }
            else if (attr is YAXAttributeForClassAttribute)
            {
                // it is required that YAXCustomSerializerAttribute is processed earlier
                if (ReflectionUtils.IsBasicType(MemberType) || CustomSerializerType != null ||
                    (m_collectionAttributeInstance != null && m_collectionAttributeInstance.SerializationType == YAXCollectionSerializationTypes.Serially))
                {
                    IsSerializedAsAttribute = true;
                    SerializationLocation = ".";
                }
            }
            else if (attr is YAXValueForClassAttribute)
            {
                // it is required that YAXCustomSerializerAttribute is processed earlier
                if (ReflectionUtils.IsBasicType(MemberType) || CustomSerializerType != null ||
                    (m_collectionAttributeInstance != null && m_collectionAttributeInstance.SerializationType == YAXCollectionSerializationTypes.Serially))
                {
                    IsSerializedAsValue = true;
                    SerializationLocation = ".";
                }
            }
            else if (attr is YAXAttributeForAttribute)
            {
                // it is required that YAXCustomSerializerAttribute is processed earlier
                if (ReflectionUtils.IsBasicType(MemberType) || CustomSerializerType != null ||
                    (m_collectionAttributeInstance != null && m_collectionAttributeInstance.SerializationType == YAXCollectionSerializationTypes.Serially))
                {
                    IsSerializedAsAttribute = true;
                    string path, alias;
                    StringUtils.ExttractPathAndAliasFromLocationString((attr as YAXAttributeForAttribute).Parent, out path, out alias);

                    SerializationLocation = path;
                    if (!String.IsNullOrEmpty(alias))
                        Alias = StringUtils.RefineSingleElement(alias);
                }
            }
            else if (attr is YAXElementForAttribute)
            {
                IsSerializedAsElement = true;

                string path, alias;
                StringUtils.ExttractPathAndAliasFromLocationString((attr as YAXElementForAttribute).Parent, out path, out alias);

                SerializationLocation = path;
                if (!String.IsNullOrEmpty(alias))
                    Alias = StringUtils.RefineSingleElement(alias);
            }
            else if (attr is YAXValueForAttribute)
            {
                // it is required that YAXCustomSerializerAttribute is processed earlier
                if (ReflectionUtils.IsBasicType(this.MemberType) || CustomSerializerType != null ||
                    (m_collectionAttributeInstance != null && m_collectionAttributeInstance.SerializationType == YAXCollectionSerializationTypes.Serially))
                {
                    IsSerializedAsValue = true;

                    string path, alias;
                    StringUtils.ExttractPathAndAliasFromLocationString((attr as YAXValueForAttribute).Parent, out path, out alias);

                    SerializationLocation = path;
                    if (!String.IsNullOrEmpty(alias))
                        Alias = StringUtils.RefineSingleElement(alias);
                }
            }
            else if (attr is YAXDontSerializeAttribute)
            {
                IsAttributedAsDontSerialize = true;
            }
            else if (attr is YAXSerializeAsAttribute)
            {
                Alias = StringUtils.RefineSingleElement((attr as YAXSerializeAsAttribute).SerializeAs);
            }
            else if (attr is YAXCollectionAttribute)
            {
                m_collectionAttributeInstance = attr as YAXCollectionAttribute;
            }
            else if (attr is YAXDictionaryAttribute)
            {
                m_dictionaryAttributeInstance = attr as YAXDictionaryAttribute;
            }
            else if (attr is YAXErrorIfMissedAttribute)
            {
                var temp = attr as YAXErrorIfMissedAttribute;
                DefaultValue = temp.DefaultValue;
                TreatErrorsAs = temp.TreatAs;
            }
            else if (attr is YAXFormatAttribute)
            {
                Format = (attr as YAXFormatAttribute).Format;
            }
            else if (attr is YAXNotCollectionAttribute)
            {
                // arrays are always treated as collections
                if (!ReflectionUtils.IsArray(MemberType))
                    IsAttributedAsNotCollection = true;
            }
            else if (attr is YAXCustomSerializerAttribute)
            {
                Type serType = (attr as YAXCustomSerializerAttribute).CustomSerializerType;

                Type genTypeArg;
                bool isDesiredInterface = ReflectionUtils.IsDerivedFromGenericInterfaceType(serType, typeof(ICustomSerializer<>), out genTypeArg);

                if (!isDesiredInterface)
                {
                    throw new YAXException("The provided custom serialization type is not derived from the proper interface");
                }
                else if (genTypeArg != this.MemberType)
                {
                    throw new YAXException("The generic argument of the class and the member type do not match");
                }
                else
                {
                    CustomSerializerType = serType;
                }
            }
            else if(attr is YAXPreserveWhitespaceAttribute)
            {
                PreservesWhitespace = true;
            }
            else if (attr is YAXSerializableTypeAttribute)
            {
                // this should not happen
                throw new Exception("This attribute is not applicable to fields and properties!");
            }
            else if (attr is YAXNamespaceAttribute)
            {
                var nsAttrib = (attr as YAXNamespaceAttribute);
                Namespace = nsAttrib.Namespace;
                NamespacePrefix = nsAttrib.Prefix;
            }
            else if (attr is YAXTypeAttribute)
            {
                var yaxTypeAttr = attr as YAXTypeAttribute;
                string alias = yaxTypeAttr.Alias;
                if (alias != null)
                {
                    alias = alias.Trim();
                    if (alias.Length == 0)
                        alias = null;
                }

                if(m_possibleRealTypes.Any(x => x.Type == yaxTypeAttr.Type))
                    throw new YAXPolymorphicException(String.Format("The type \"{0}\" for field/property \"{1}\" has already been defined through another attribute.", yaxTypeAttr.Type.Name, m_memberInfo));

                if (alias != null && m_possibleRealTypes.Any(x => alias.Equals(x.Alias, StringComparison.Ordinal)))
                    throw new YAXPolymorphicException(String.Format("The alias \"{0}\" given to type \"{1}\" for field/property \"{2}\" has already been given to another type through another attribute.",
                        alias, yaxTypeAttr.Type.Name, m_memberInfo));

                m_possibleRealTypes.Add(yaxTypeAttr);
            }
            else if (attr is YAXCollectionItemTypeAttribute)
            {
                var yaxColletionItemTypeAttr = attr as YAXCollectionItemTypeAttribute;
                string alias = yaxColletionItemTypeAttr.Alias;
                if (alias != null)
                {
                    alias = alias.Trim();
                    if (alias.Length == 0)
                        alias = null;
                }

                if (m_possibleCollectionItemRealTypes.Any(x => x.Type == yaxColletionItemTypeAttr.Type))
                    throw new YAXPolymorphicException(String.Format("The collection-item type \"{0}\" for collection \"{1}\" has already been defined through another attribute.", yaxColletionItemTypeAttr.Type.Name, m_memberInfo));

                if (alias != null && m_possibleCollectionItemRealTypes.Any(x => alias.Equals(x.Alias, StringComparison.Ordinal)))
                    throw new YAXPolymorphicException(String.Format("The alias \"{0}\" given to collection-item type \"{1}\" for field/property \"{2}\" has already been given to another type through another attribute.",
                        alias, yaxColletionItemTypeAttr.Type.Name, m_memberInfo));

                m_possibleCollectionItemRealTypes.Add(yaxColletionItemTypeAttr);
            }
            else if (attr is YAXDontSerializeIfNullAttribute)
            {
                IsAttributedAsDontSerializeIfNull = true;
            }
            else if (attr is YAXElementOrder)
            {
                Order = (attr as YAXElementOrder).Order;
            }
            else
            {
                throw new Exception("Added new attribute type to the library but not yet processed!");
            }
        }
Example #5
0
        /// <summary>
        ///     Processes the specified attribute which is an instance of <c>YAXAttribute</c>.
        /// </summary>
        /// <param name="attr">The attribute to process.</param>
        private void ProcessYaxAttribute(object attr)
        {
            if (attr is YAXCommentAttribute)
            {
                var comment = (attr as YAXCommentAttribute).Comment;
                if (!string.IsNullOrEmpty(comment))
                {
                    var comments = comment.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                    for (var i = 0; i < comments.Length; i++)
                    {
                        comments[i] = string.Format(" {0} ", comments[i].Trim());
                    }

                    Comment = comments;
                }
            }
            else if (attr is YAXSerializableFieldAttribute)
            {
                IsAttributedAsSerializable = true;
            }
            else if (attr is YAXAttributeForClassAttribute)
            {
                // it is required that YAXCustomSerializerAttribute is processed earlier
                if (ReflectionUtils.IsBasicType(MemberType) || HasCustomSerializer || MemberTypeWrapper.HasCustomSerializer ||
                    _collectionAttributeInstance != null && _collectionAttributeInstance.SerializationType ==
                    YAXCollectionSerializationTypes.Serially)
                {
                    IsSerializedAsAttribute = true;
                    SerializationLocation   = ".";
                }
            }
            else if (attr is YAXValueForClassAttribute)
            {
                // it is required that YAXCustomSerializerAttribute is processed earlier
                if (ReflectionUtils.IsBasicType(MemberType) || HasCustomSerializer || MemberTypeWrapper.HasCustomSerializer ||
                    _collectionAttributeInstance != null && _collectionAttributeInstance.SerializationType ==
                    YAXCollectionSerializationTypes.Serially)
                {
                    IsSerializedAsValue   = true;
                    SerializationLocation = ".";
                }
            }
            else if (attr is YAXAttributeForAttribute)
            {
                // it is required that YAXCustomSerializerAttribute is processed earlier
                if (ReflectionUtils.IsBasicType(MemberType) || HasCustomSerializer ||
                    _collectionAttributeInstance != null && _collectionAttributeInstance.SerializationType ==
                    YAXCollectionSerializationTypes.Serially)
                {
                    IsSerializedAsAttribute = true;
                    string path, alias;
                    StringUtils.ExttractPathAndAliasFromLocationString((attr as YAXAttributeForAttribute).Parent,
                                                                       out path, out alias);

                    SerializationLocation = path;
                    if (!string.IsNullOrEmpty(alias))
                    {
                        Alias = StringUtils.RefineSingleElement(alias);
                    }
                }
            }
            else if (attr is YAXElementForAttribute)
            {
                IsSerializedAsElement = true;

                string path, alias;
                StringUtils.ExttractPathAndAliasFromLocationString((attr as YAXElementForAttribute).Parent, out path,
                                                                   out alias);

                SerializationLocation = path;
                if (!string.IsNullOrEmpty(alias))
                {
                    Alias = StringUtils.RefineSingleElement(alias);
                }
            }
            else if (attr is YAXValueForAttribute)
            {
                // it is required that YAXCustomSerializerAttribute is processed earlier
                if (ReflectionUtils.IsBasicType(MemberType) || HasCustomSerializer ||
                    _collectionAttributeInstance != null && _collectionAttributeInstance.SerializationType ==
                    YAXCollectionSerializationTypes.Serially)
                {
                    IsSerializedAsValue = true;

                    string path, alias;
                    StringUtils.ExttractPathAndAliasFromLocationString((attr as YAXValueForAttribute).Parent, out path,
                                                                       out alias);

                    SerializationLocation = path;
                    if (!string.IsNullOrEmpty(alias))
                    {
                        Alias = StringUtils.RefineSingleElement(alias);
                    }
                }
            }
            else if (attr is YAXDontSerializeAttribute)
            {
                IsAttributedAsDontSerialize = true;
            }
            else if (attr is YAXSerializeAsAttribute)
            {
                Alias = StringUtils.RefineSingleElement((attr as YAXSerializeAsAttribute).SerializeAs);
            }
            else if (attr is YAXCollectionAttribute)
            {
                _collectionAttributeInstance = attr as YAXCollectionAttribute;
            }
            else if (attr is YAXDictionaryAttribute)
            {
                _dictionaryAttributeInstance = attr as YAXDictionaryAttribute;
            }
            else if (attr is YAXErrorIfMissedAttribute)
            {
                var temp = attr as YAXErrorIfMissedAttribute;
                DefaultValue  = temp.DefaultValue;
                TreatErrorsAs = temp.TreatAs;
            }
            else if (attr is YAXFormatAttribute)
            {
                Format = (attr as YAXFormatAttribute).Format;
            }
            else if (attr is YAXNotCollectionAttribute)
            {
                // arrays are always treated as collections
                if (!ReflectionUtils.IsArray(MemberType))
                {
                    IsAttributedAsNotCollection = true;
                }
            }
            else if (attr is YAXCustomSerializerAttribute)
            {
                var serType = (attr as YAXCustomSerializerAttribute).CustomSerializerType;

                Type genTypeArg;
                var  isDesiredInterface =
                    ReflectionUtils.IsDerivedFromGenericInterfaceType(serType, typeof(ICustomSerializer <>),
                                                                      out genTypeArg);

                if (!isDesiredInterface)
                {
                    throw new YAXException(
                              "The provided custom serialization type is not derived from the proper interface");
                }
                if (genTypeArg != MemberType)
                {
                    throw new YAXException("The generic argument of the class and the member type do not match");
                }
                CustomSerializerType = serType;
            }
            else if (attr is YAXPreserveWhitespaceAttribute)
            {
                PreservesWhitespace = true;
            }
            else if (attr is YAXSerializableTypeAttribute)
            {
                // this should not happen
                throw new Exception("This attribute is not applicable to fields and properties!");
            }
            else if (attr is YAXNamespaceAttribute)
            {
                var nsAttrib = attr as YAXNamespaceAttribute;
                Namespace       = nsAttrib.Namespace;
                NamespacePrefix = nsAttrib.Prefix;
            }
            else if (attr is YAXTypeAttribute)
            {
                var yaxTypeAttr = attr as YAXTypeAttribute;
                var alias       = yaxTypeAttr.Alias;
                if (alias != null)
                {
                    alias = alias.Trim();
                    if (alias.Length == 0)
                    {
                        alias = null;
                    }
                }

                if (_possibleRealTypes.Any(x => x.Type == yaxTypeAttr.Type))
                {
                    throw new YAXPolymorphicException(string.Format(
                                                          "The type \"{0}\" for field/property \"{1}\" has already been defined through another attribute.",
                                                          yaxTypeAttr.Type.Name, _memberInfo));
                }

                if (alias != null && _possibleRealTypes.Any(x => alias.Equals(x.Alias, StringComparison.Ordinal)))
                {
                    throw new YAXPolymorphicException(string.Format(
                                                          "The alias \"{0}\" given to type \"{1}\" for field/property \"{2}\" has already been given to another type through another attribute.",
                                                          alias, yaxTypeAttr.Type.Name, _memberInfo));
                }

                _possibleRealTypes.Add(yaxTypeAttr);
            }
            else if (attr is YAXCollectionItemTypeAttribute)
            {
                var yaxColletionItemTypeAttr = attr as YAXCollectionItemTypeAttribute;
                var alias = yaxColletionItemTypeAttr.Alias;
                if (alias != null)
                {
                    alias = alias.Trim();
                    if (alias.Length == 0)
                    {
                        alias = null;
                    }
                }

                if (_possibleCollectionItemRealTypes.Any(x => x.Type == yaxColletionItemTypeAttr.Type))
                {
                    throw new YAXPolymorphicException(string.Format(
                                                          "The collection-item type \"{0}\" for collection \"{1}\" has already been defined through another attribute.",
                                                          yaxColletionItemTypeAttr.Type.Name, _memberInfo));
                }

                if (alias != null &&
                    _possibleCollectionItemRealTypes.Any(x => alias.Equals(x.Alias, StringComparison.Ordinal)))
                {
                    throw new YAXPolymorphicException(string.Format(
                                                          "The alias \"{0}\" given to collection-item type \"{1}\" for field/property \"{2}\" has already been given to another type through another attribute.",
                                                          alias, yaxColletionItemTypeAttr.Type.Name, _memberInfo));
                }

                _possibleCollectionItemRealTypes.Add(yaxColletionItemTypeAttr);
            }
            else if (attr is YAXDontSerializeIfNullAttribute)
            {
                IsAttributedAsDontSerializeIfNull = true;
            }
            else if (attr is YAXElementOrder)
            {
                Order = (attr as YAXElementOrder).Order;
            }
            else
            {
                throw new Exception("Added new attribute type to the library but not yet processed!");
            }
        }
Example #6
0
        /// <summary>
        /// Processes the specified attribute.
        /// </summary>
        /// <param name="attr">The attribute to process.</param>
        private void ProcessYAXAttribute(object attr)
        {
            if (attr is YAXCommentAttribute)
            {
                string comment = (attr as YAXCommentAttribute).Comment;
                if(!String.IsNullOrEmpty(comment))
                {
                    string[] comments = comment.Split(new [] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                    for(int i = 0; i < comments.Length; i++)
                    {
                        comments[i] = String.Format(" {0} ", comments[i].Trim());
                    }

                    this.Comment = comments;
                }
            }
            else if (attr is YAXSerializableTypeAttribute)
            {
                var theAttr = attr as YAXSerializableTypeAttribute;
                this.FieldsToSerialize = theAttr.FieldsToSerialize;
                if (theAttr.IsSerializationOptionSet())
                {
                    SerializationOption = theAttr.Options;
                    m_isSerializationOptionSetByAttribute = true;
                }
            }
            else if (attr is YAXSerializeAsAttribute)
            {
                Alias = StringUtils.RefineSingleElement((attr as YAXSerializeAsAttribute).SerializeAs);
            }
            else if (attr is YAXNotCollectionAttribute)
            {
                if(!ReflectionUtils.IsArray(m_udtType))
                    IsAttributedAsNotCollection = true;
            }
            else if (attr is YAXCustomSerializerAttribute)
            {
                Type serType = (attr as YAXCustomSerializerAttribute).CustomSerializerType;

                Type genTypeArg;
                bool isDesiredInterface = ReflectionUtils.IsDerivedFromGenericInterfaceType(serType, typeof(ICustomSerializer<>), out genTypeArg);

                if (!isDesiredInterface)
                {
                    throw new YAXException("The provided custom serialization type is not derived from the proper interface");
                }

                if (genTypeArg != UnderlyingType)
                {
                    throw new YAXException("The generic argument of the class and the type of the class do not match");
                }

                this.CustomSerializerType = serType;
            }
            else if(attr is YAXPreserveWhitespaceAttribute)
            {
                PreservesWhitespace = true;
            }
            else if (attr is YAXNamespaceAttribute)
            {
                var nsAttrib = (attr as YAXNamespaceAttribute);
                Namespace = nsAttrib.Namespace;
                NamespacePrefix = nsAttrib.Prefix;
            }
            else if (attr is YAXCollectionAttribute)
            {
                m_collectionAttributeInstance = attr as YAXCollectionAttribute;
            }
            else if (attr is YAXDictionaryAttribute)
            {
                m_dictionaryAttributeInstance = attr as YAXDictionaryAttribute;
            }
            else
            {
                throw new Exception("Attribute not applicable to types!");
            }
        }
Example #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MemberWrapper"/> class.
        /// </summary>
        /// <param name="memberInfo">The member-info to build this instance from.</param>
        /// <param name="callerSerializer">The caller serializer.</param>
        public MemberWrapper(MemberInfo memberInfo, YAXSerializer callerSerializer)
        {
            Order = Int32.MaxValue;

            if (!(memberInfo.MemberType == MemberTypes.Property || memberInfo.MemberType == MemberTypes.Field))
                throw new Exception("Member must be either property or field");

            m_memberInfo = memberInfo;
            m_isProperty = (memberInfo.MemberType == MemberTypes.Property);

            Alias = StringUtils.RefineSingleElement(m_memberInfo.Name);

            if (m_isProperty)
                m_propertyInfoInstance = (PropertyInfo)memberInfo;
            else
                m_fieldInfoInstance = (FieldInfo)memberInfo;

            m_memberType = m_isProperty ? m_propertyInfoInstance.PropertyType : m_fieldInfoInstance.FieldType;

            m_memberTypeWrapper = TypeWrappersPool.Pool.GetTypeWrapper(MemberType, callerSerializer);
            if (m_memberTypeWrapper.HasNamespace)
            {
                Namespace = m_memberTypeWrapper.Namespace;
                NamespacePrefix = m_memberTypeWrapper.NamespacePrefix;
            }

            InitInstance();

            TreatErrorsAs = callerSerializer != null ? callerSerializer.DefaultExceptionType : YAXExceptionTypes.Error;

            // discovver YAXCustomSerializerAttributes earlier, because some other attributes depend on it
            var attrsToProcessEarlier = new HashSet<Type> {typeof (YAXCustomSerializerAttribute), typeof (YAXCollectionAttribute)};
            foreach (var attrType in attrsToProcessEarlier)
            {
                var customSerAttrs = Attribute.GetCustomAttributes(m_memberInfo, attrType, true);
                foreach (var attr in customSerAttrs)
                {
                    ProcessYaxAttribute(attr);
                }
            }

            foreach (var attr in Attribute.GetCustomAttributes(m_memberInfo, true))
            {
                // no need to preces, it has been proccessed earlier
                if (attrsToProcessEarlier.Contains(attr.GetType()))
                    continue;

                if (attr is YAXBaseAttribute)
                    ProcessYaxAttribute(attr);
            }

            // now override some values from memeber-type-wrapper into member-wrapper
            // if member-type has collection attributes while the member itself does not have them,
            // then use those of the member-type
            if (m_collectionAttributeInstance == null && m_memberTypeWrapper.CollectionAttributeInstance != null)
                m_collectionAttributeInstance = m_memberTypeWrapper.CollectionAttributeInstance;

            if (m_dictionaryAttributeInstance == null && m_memberTypeWrapper.DictionaryAttributeInstance != null)
                m_dictionaryAttributeInstance = m_memberTypeWrapper.DictionaryAttributeInstance;
        }
Example #8
0
        /// <summary>
        /// Processes the specified attribute which is an instance of <c>YAXAttribute</c>.
        /// </summary>
        /// <param name="attr">The attribute to process.</param>
        private void ProcessYaxAttribute(object attr)
        {
            if (attr is YAXCommentAttribute)
            {
                string comment = (attr as YAXCommentAttribute).Comment;
                if (!String.IsNullOrEmpty(comment))
                {
                    string[] comments = comment.Split(new [] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < comments.Length; i++)
                    {
                        comments[i] = String.Format(" {0} ", comments[i].Trim());
                    }

                    this.Comment = comments;
                }
            }
            else if (attr is YAXSerializableFieldAttribute)
            {
                IsAttributedAsSerializable = true;
            }
            else if (attr is YAXAttributeForClassAttribute)
            {
                // it is required that YAXCustomSerializerAttribute is processed earlier
                if (ReflectionUtils.IsBasicType(MemberType) || CustomSerializerType != null ||
                    (m_collectionAttributeInstance != null && m_collectionAttributeInstance.SerializationType == YAXCollectionSerializationTypes.Serially))
                {
                    IsSerializedAsAttribute = true;
                    SerializationLocation = ".";
                }
            }
            else if (attr is YAXValueForClassAttribute)
            {
                // it is required that YAXCustomSerializerAttribute is processed earlier
                if (ReflectionUtils.IsBasicType(MemberType) || CustomSerializerType != null ||
                    (m_collectionAttributeInstance != null && m_collectionAttributeInstance.SerializationType == YAXCollectionSerializationTypes.Serially))
                {
                    IsSerializedAsValue = true;
                    SerializationLocation = ".";
                }
            }
            else if (attr is YAXAttributeForAttribute)
            {
                // it is required that YAXCustomSerializerAttribute is processed earlier
                if (ReflectionUtils.IsBasicType(MemberType) || CustomSerializerType != null ||
                    (m_collectionAttributeInstance != null && m_collectionAttributeInstance.SerializationType == YAXCollectionSerializationTypes.Serially))
                {
                    IsSerializedAsAttribute = true;
                    string path, alias;
                    StringUtils.ExttractPathAndAliasFromLocationString((attr as YAXAttributeForAttribute).Parent, out path, out alias);

                    SerializationLocation = path;
                    if (!String.IsNullOrEmpty(alias))
                        Alias = alias;
                }
            }
            else if (attr is YAXElementForAttribute)
            {
                IsSerializedAsElement = true;

                string path, alias;
                StringUtils.ExttractPathAndAliasFromLocationString((attr as YAXElementForAttribute).Parent, out path, out alias);

                SerializationLocation = path;
                if (!String.IsNullOrEmpty(alias))
                    Alias = alias;
            }
            else if (attr is YAXValueForAttribute)
            {
                // it is required that YAXCustomSerializerAttribute is processed earlier
                if (ReflectionUtils.IsBasicType(this.MemberType) || CustomSerializerType != null ||
                    (m_collectionAttributeInstance != null && m_collectionAttributeInstance.SerializationType == YAXCollectionSerializationTypes.Serially))
                {
                    IsSerializedAsValue = true;

                    string path, alias;
                    StringUtils.ExttractPathAndAliasFromLocationString((attr as YAXValueForAttribute).Parent, out path, out alias);

                    SerializationLocation = path;
                    if (!String.IsNullOrEmpty(alias))
                        Alias = alias;
                }
            }
            else if (attr is YAXDontSerializeAttribute)
            {
                IsAttributedAsDontSerialize = true;
            }
            else if (attr is YAXSerializeAsAttribute)
            {
                Alias = (attr as YAXSerializeAsAttribute).SerializeAs;
            }
            else if (attr is YAXCollectionAttribute)
            {
                m_collectionAttributeInstance = attr as YAXCollectionAttribute;
            }
            else if (attr is YAXDictionaryAttribute)
            {
                m_dictionaryAttributeInstance = attr as YAXDictionaryAttribute;
            }
            else if (attr is YAXErrorIfMissedAttribute)
            {
                var temp = attr as YAXErrorIfMissedAttribute;
                DefaultValue = temp.DefaultValue;
                TreatErrorsAs = temp.TreatAs;
            }
            else if (attr is YAXFormatAttribute)
            {
                Format = (attr as YAXFormatAttribute).Format;
            }
            else if (attr is YAXNotCollectionAttribute)
            {
                // arrays are always treated as collections
                if (!ReflectionUtils.IsArray(MemberType))
                    IsAttributedAsNotCollection = true;
            }
            else if (attr is YAXCustomSerializerAttribute)
            {
                Type serType = (attr as YAXCustomSerializerAttribute).CustomSerializerType;

                Type genTypeArg;
                bool isDesiredInterface = ReflectionUtils.IsDerivedFromGenericInterfaceType(serType, typeof(ICustomSerializer<>), out genTypeArg);

                if (!isDesiredInterface)
                {
                    throw new YAXException("The provided custom serialization type is not derived from the proper interface");
                }
                else if (genTypeArg != this.MemberType)
                {
                    throw new YAXException("The generic argument of the class and the member type do not match");
                }
                else
                {
                    CustomSerializerType = serType;
                }
            }
            //else if (attr is YAXCustomDeserializerAttribute)
            //{
            //    Type deserType = (attr as YAXCustomDeserializerAttribute).CustomDeserializerType;

            //    Type genTypeArg;
            //    bool isDesiredInterface = ReflectionUtils.IsDerivedFromGenericInterfaceType(deserType, typeof(ICustomSerializer<>), out genTypeArg);

            //    if (!isDesiredInterface)
            //    {
            //        throw new YAXException("The provided custom deserialization type is not derived from the proper interface");
            //    }
            //    else if (genTypeArg != this.MemberType)
            //    {
            //        throw new YAXException("The generic argument of the class and the member type do not match");
            //    }
            //    else
            //    {
            //        this.CustomDeserializerType = deserType;
            //    }
            //}
            else if (attr is YAXSerializableTypeAttribute)
            {
                // this should not happen
                throw new Exception("This attribute is not applicable to fields and properties!");
            }
            else
            {
                throw new Exception("Added new attribute type to the library but not yet processed!");
            }
        }
Example #9
0
        /// <summary>
        /// Creates a dictionary element according to the specified options, as described
        /// by the attribute instances.
        /// </summary>
        /// <param name="insertionLocation">The insertion location.</param>
        /// <param name="elementName">Name of the element.</param>
        /// <param name="elementValue">The element value, corresponding to a dictionary object.</param>
        /// <param name="dicAttrInst">reference to the dictionary attribute instance.</param>
        /// <param name="collectionAttrInst">reference to collection attribute instance.</param>
        /// <returns>
        /// an instance of <c>XElement</c> which contains the dictionary object
        /// serialized properly
        /// </returns>
        private XElement MakeDictionaryElement(
            XElement insertionLocation,
            string elementName,
            object elementValue,
            YAXDictionaryAttribute dicAttrInst,
            YAXCollectionAttribute collectionAttrInst)
        {
            if (elementValue == null)
            {
                return new XElement(elementName, elementValue);
            }

            Type keyType, valueType;
            if (!ReflectionUtils.IsIDictionary(elementValue.GetType(), out keyType, out valueType))
            {
                throw new ArgumentException("elementValue must be a Dictionary");
            }

            var dicInst = elementValue as IEnumerable;
            bool isKeyAttrib = false;
            bool isValueAttrib = false;
            string keyFormat = null;
            string valueFormat = null;
            string keyAlias = "Key";
            string valueAlias = "Value";

            string eachElementName = collectionAttrInst != null ? collectionAttrInst.EachElementName : null;

            if (dicAttrInst != null)
            {
                eachElementName = dicAttrInst.EachPairName ?? eachElementName;

                if (dicAttrInst.SerializeKeyAs == YAXNodeTypes.Attribute)
                {
                    isKeyAttrib = ReflectionUtils.IsBasicType(keyType);
                }

                if (dicAttrInst.SerializeValueAs == YAXNodeTypes.Attribute)
                {
                    isValueAttrib = ReflectionUtils.IsBasicType(valueType);
                }

                keyFormat = dicAttrInst.KeyFormatString;
                valueFormat = dicAttrInst.ValueFormatString;

                keyAlias = dicAttrInst.KeyName ?? "Key";
                valueAlias = dicAttrInst.ValueName ?? "Value";
            }

            XElement elem = new XElement(elementName, null);

            foreach (object obj in dicInst)
            {
                object keyObj = obj.GetType().GetProperty("Key").GetValue(obj, null);
                object valueObj = obj.GetType().GetProperty("Value").GetValue(obj, null);

                bool areKeyOfSameType = true;
                bool areValueOfSameType = true;

                if (keyObj != null && keyObj.GetType() != keyType)
                    areKeyOfSameType = false;

                if (valueObj != null && valueObj.GetType() != valueType)
                    areValueOfSameType = false;

                if (keyFormat != null)
                {
                    keyObj = ReflectionUtils.TryFormatObject(keyObj, keyFormat);
                }

                if (valueFormat != null)
                {
                    valueObj = ReflectionUtils.TryFormatObject(valueObj, valueFormat);
                }

                XElement elemChild = new XElement(eachElementName ?? ReflectionUtils.GetTypeFriendlyName(obj.GetType()), null);

                if (isKeyAttrib && areKeyOfSameType)
                {
                    elemChild.Add(new XAttribute(keyAlias, (keyObj ?? string.Empty).ToString()));
                }
                else
                {
                    XElement addedElem = AddObjectToElement(elemChild, keyAlias, keyObj);
                    if (!areKeyOfSameType)
                    {
                        if (addedElem.Parent == null)
                        {
                            // sometimes empty elements are removed because its members are serialized in
                            // other elements, therefore we need to make sure to re-add the element.
                            elemChild.Add(addedElem);
                        }

                        addedElem.Add(new XAttribute(s_namespaceURI + s_trueTypeAttrName, keyObj.GetType().FullName));
                        m_needsNamespaceAddition = true;
                    }
                }

                if (isValueAttrib && areValueOfSameType)
                {
                    elemChild.Add(new XAttribute(valueAlias, (valueObj ?? string.Empty).ToString()));
                }
                else
                {
                    XElement addedElem = AddObjectToElement(elemChild, valueAlias, valueObj);
                    if (!areValueOfSameType)
                    {
                        if(addedElem.Parent == null)
                        {
                            // sometimes empty elements are removed because its members are serialized in
                            // other elements, therefore we need to make sure to re-add the element.
                            elemChild.Add(addedElem);
                        }

                        addedElem.Add(new XAttribute(s_namespaceURI + s_trueTypeAttrName, valueObj.GetType().FullName));
                        m_needsNamespaceAddition = true;
                    }
                }

                elem.Add(elemChild);
            }

            return elem;
        }
Example #10
0
        /// <summary>
        /// Processes the specified attribute.
        /// </summary>
        /// <param name="attr">The attribute to process.</param>
        private void ProcessYAXAttribute(object attr)
        {
            if (attr is YAXCommentAttribute)
            {
                string comment = (attr as YAXCommentAttribute).Comment;
                if (!String.IsNullOrEmpty(comment))
                {
                    string[] comments = comment.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < comments.Length; i++)
                    {
                        comments[i] = String.Format(" {0} ", comments[i].Trim());
                    }

                    this.Comment = comments;
                }
            }
            else if (attr is YAXSerializableTypeAttribute)
            {
                var theAttr = attr as YAXSerializableTypeAttribute;
                this.FieldsToSerialize = theAttr.FieldsToSerialize;
                if (theAttr.IsSerializationOptionSet())
                {
                    this.SerializationOption = theAttr.Options;
                    this.m_isSerializationOptionSetByAttribute = true;
                }
            }
            else if (attr is YAXSerializeAsAttribute)
            {
                this.Alias = StringUtils.RefineSingleElement((attr as YAXSerializeAsAttribute).SerializeAs);
            }
            else if (attr is YAXNotCollectionAttribute)
            {
                if (!ReflectionUtils.IsArray(this.m_udtType))
                {
                    this.IsAttributedAsNotCollection = true;
                }
            }
            else if (attr is YAXCustomSerializerAttribute)
            {
                Type serType = (attr as YAXCustomSerializerAttribute).CustomSerializerType;

                Type genTypeArg;
                bool isDesiredInterface = ReflectionUtils.IsDerivedFromGenericInterfaceType(serType, typeof(ICustomSerializer <>), out genTypeArg);

                if (!isDesiredInterface)
                {
                    throw new YAXException("The provided custom serialization type is not derived from the proper interface");
                }

                if (genTypeArg != this.UnderlyingType)
                {
                    throw new YAXException("The generic argument of the class and the type of the class do not match");
                }

                this.CustomSerializerType = serType;
            }
            else if (attr is YAXPreserveWhitespaceAttribute)
            {
                this.PreservesWhitespace = true;
            }
            else if (attr is YAXNamespaceAttribute)
            {
                var nsAttrib = (attr as YAXNamespaceAttribute);
                this.Namespace       = nsAttrib.Namespace;
                this.NamespacePrefix = nsAttrib.Prefix;
            }
            else if (attr is YAXCollectionAttribute)
            {
                this.m_collectionAttributeInstance = attr as YAXCollectionAttribute;
            }
            else if (attr is YAXDictionaryAttribute)
            {
                this.m_dictionaryAttributeInstance = attr as YAXDictionaryAttribute;
            }
            else
            {
                throw new Exception("Attribute not applicable to types!");
            }
        }
Example #11
0
        /// <summary>
        /// Processes the specified attribute which is an instance of <c>YAXAttribute</c>.
        /// </summary>
        /// <param name="attr">The attribute to process.</param>
        private void ProcessYaxAttribute(object attr)
        {
            if (attr is YAXCommentAttribute)
            {
                string comment = (attr as YAXCommentAttribute).Comment;
                if (!String.IsNullOrEmpty(comment))
                {
                    string[] comments = comment.Split(new [] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < comments.Length; i++)
                    {
                        comments[i] = String.Format(" {0} ", comments[i].Trim());
                    }

                    this.Comment = comments;
                }
            }
            else if (attr is YAXSerializableFieldAttribute)
            {
                IsAttributedAsSerializable = true;
            }
            else if (attr is YAXAttributeForClassAttribute)
            {
                // it is required that YAXCustomSerializerAttribute is processed earlier
                if (ReflectionUtils.IsBasicType(MemberType) || CustomSerializerType != null ||
                    (m_collectionAttributeInstance != null && m_collectionAttributeInstance.SerializationType == YAXCollectionSerializationTypes.Serially))
                {
                    IsSerializedAsAttribute = true;
                    SerializationLocation   = ".";
                }
            }
            else if (attr is YAXValueForClassAttribute)
            {
                // it is required that YAXCustomSerializerAttribute is processed earlier
                if (ReflectionUtils.IsBasicType(MemberType) || CustomSerializerType != null ||
                    (m_collectionAttributeInstance != null && m_collectionAttributeInstance.SerializationType == YAXCollectionSerializationTypes.Serially))
                {
                    IsSerializedAsValue   = true;
                    SerializationLocation = ".";
                }
            }
            else if (attr is YAXAttributeForAttribute)
            {
                // it is required that YAXCustomSerializerAttribute is processed earlier
                if (ReflectionUtils.IsBasicType(MemberType) || CustomSerializerType != null ||
                    (m_collectionAttributeInstance != null && m_collectionAttributeInstance.SerializationType == YAXCollectionSerializationTypes.Serially))
                {
                    IsSerializedAsAttribute = true;
                    string path, alias;
                    StringUtils.ExttractPathAndAliasFromLocationString((attr as YAXAttributeForAttribute).Parent, out path, out alias);

                    SerializationLocation = path;
                    if (!String.IsNullOrEmpty(alias))
                    {
                        Alias = StringUtils.RefineSingleElement(alias);
                    }
                }
            }
            else if (attr is YAXElementForAttribute)
            {
                IsSerializedAsElement = true;

                string path, alias;
                StringUtils.ExttractPathAndAliasFromLocationString((attr as YAXElementForAttribute).Parent, out path, out alias);

                SerializationLocation = path;
                if (!String.IsNullOrEmpty(alias))
                {
                    Alias = StringUtils.RefineSingleElement(alias);
                }
            }
            else if (attr is YAXValueForAttribute)
            {
                // it is required that YAXCustomSerializerAttribute is processed earlier
                if (ReflectionUtils.IsBasicType(this.MemberType) || CustomSerializerType != null ||
                    (m_collectionAttributeInstance != null && m_collectionAttributeInstance.SerializationType == YAXCollectionSerializationTypes.Serially))
                {
                    IsSerializedAsValue = true;

                    string path, alias;
                    StringUtils.ExttractPathAndAliasFromLocationString((attr as YAXValueForAttribute).Parent, out path, out alias);

                    SerializationLocation = path;
                    if (!String.IsNullOrEmpty(alias))
                    {
                        Alias = StringUtils.RefineSingleElement(alias);
                    }
                }
            }
            else if (attr is YAXDontSerializeAttribute)
            {
                IsAttributedAsDontSerialize = true;
            }
            else if (attr is YAXSerializeAsAttribute)
            {
                Alias = StringUtils.RefineSingleElement((attr as YAXSerializeAsAttribute).SerializeAs);
            }
            else if (attr is YAXCollectionAttribute)
            {
                m_collectionAttributeInstance = attr as YAXCollectionAttribute;
            }
            else if (attr is YAXDictionaryAttribute)
            {
                m_dictionaryAttributeInstance = attr as YAXDictionaryAttribute;
            }
            else if (attr is YAXErrorIfMissedAttribute)
            {
                var temp = attr as YAXErrorIfMissedAttribute;
                DefaultValue  = temp.DefaultValue;
                TreatErrorsAs = temp.TreatAs;
            }
            else if (attr is YAXFormatAttribute)
            {
                Format = (attr as YAXFormatAttribute).Format;
            }
            else if (attr is YAXNotCollectionAttribute)
            {
                // arrays are always treated as collections
                if (!ReflectionUtils.IsArray(MemberType))
                {
                    IsAttributedAsNotCollection = true;
                }
            }
            else if (attr is YAXCustomSerializerAttribute)
            {
                Type serType = (attr as YAXCustomSerializerAttribute).CustomSerializerType;

                Type genTypeArg;
                bool isDesiredInterface = ReflectionUtils.IsDerivedFromGenericInterfaceType(serType, typeof(ICustomSerializer <>), out genTypeArg);

                if (!isDesiredInterface)
                {
                    throw new YAXException("The provided custom serialization type is not derived from the proper interface");
                }
                else if (genTypeArg != this.MemberType)
                {
                    throw new YAXException("The generic argument of the class and the member type do not match");
                }
                else
                {
                    CustomSerializerType = serType;
                }
            }
            else if (attr is YAXPreserveWhitespaceAttribute)
            {
                PreservesWhitespace = true;
            }
            else if (attr is YAXSerializableTypeAttribute)
            {
                // this should not happen
                throw new Exception("This attribute is not applicable to fields and properties!");
            }
            else if (attr is YAXNamespaceAttribute)
            {
                var nsAttrib = (attr as YAXNamespaceAttribute);
                Namespace       = nsAttrib.Namespace;
                NamespacePrefix = nsAttrib.Prefix;
            }
            else
            {
                throw new Exception("Added new attribute type to the library but not yet processed!");
            }
        }
Example #12
0
        private object DeserializeTaggedDictionaryValue(XElement xelemValue, XName alias, Type type, 
            YAXCollectionAttribute colAttributeInstance, YAXDictionaryAttribute dicAttrInstance)
        {
            // otherwise the "else if(member.IsTreatedAsCollection)" block solves the problem
            Type keyType, valueType;
            if (!ReflectionUtils.IsIDictionary(type, out keyType, out valueType))
            {
                throw new Exception("elemValue must be a Dictionary");
            }

            // deserialize non-collection fields
            var namespaceToOverride = alias.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone();
            var containerSer = NewInternalSerializer(type, namespaceToOverride, null);
            containerSer.IsCraetedToDeserializeANonCollectionMember = true;
            containerSer.RemoveDeserializedXmlNodes = true;
            object dic = containerSer.DeserializeBase(xelemValue);
            FinalizeNewSerializer(containerSer, false);

            // now try to deserialize collection fields
            Type pairType = null;
            ReflectionUtils.IsIEnumerable(type, out pairType);
            XName eachElementName = StringUtils.RefineSingleElement(ReflectionUtils.GetTypeFriendlyName(pairType));
            bool isKeyAttrib = false;
            bool isValueAttrib = false;
            bool isKeyContent = false;
            bool isValueContent = false;
            XName keyAlias = alias.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone() + "Key";
            XName valueAlias = alias.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone() + "Value";

            if (colAttributeInstance != null && colAttributeInstance.EachElementName != null)
            {
                eachElementName = StringUtils.RefineSingleElement(colAttributeInstance.EachElementName);
                eachElementName = eachElementName.OverrideNsIfEmpty(alias.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone());
            }

            if (dicAttrInstance != null)
            {
                if (dicAttrInstance.EachPairName != null)
                {
                    eachElementName = StringUtils.RefineSingleElement(dicAttrInstance.EachPairName);
                    eachElementName = eachElementName.OverrideNsIfEmpty(alias.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone());
                }

                if (dicAttrInstance.SerializeKeyAs == YAXNodeTypes.Attribute)
                {
                    isKeyAttrib = ReflectionUtils.IsBasicType(keyType);
                }
                else if (dicAttrInstance.SerializeKeyAs == YAXNodeTypes.Content)
                {
                    isKeyContent = ReflectionUtils.IsBasicType(keyType);
                }

                if (dicAttrInstance.SerializeValueAs == YAXNodeTypes.Attribute)
                {
                    isValueAttrib = ReflectionUtils.IsBasicType(valueType);
                }
                else if (dicAttrInstance.SerializeValueAs == YAXNodeTypes.Content)
                {
                    isValueContent = ReflectionUtils.IsBasicType(valueType);
                }

                if (dicAttrInstance.KeyName != null)
                {
                    keyAlias = StringUtils.RefineSingleElement(dicAttrInstance.KeyName);
                    keyAlias = keyAlias.OverrideNsIfEmpty(alias.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone());
                }
                if (dicAttrInstance.ValueName != null)
                {
                    valueAlias = StringUtils.RefineSingleElement(dicAttrInstance.ValueName);
                    valueAlias = valueAlias.OverrideNsIfEmpty(alias.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone());
                }
            }

            foreach (XElement childElem in xelemValue.Elements(eachElementName))
            {
                object key = null, value = null;
                YAXSerializer keySer = null, valueSer = null;

                bool isKeyFound = VerifyDictionaryPairElements(ref keyType, ref isKeyAttrib, ref isKeyContent, keyAlias, childElem);
                bool isValueFound = VerifyDictionaryPairElements(ref valueType, ref isValueAttrib, ref isValueContent, valueAlias, childElem);

                if (!isKeyFound && !isValueFound)
                    continue;

                if (isKeyFound)
                {
                    if (isKeyAttrib)
                    {
                        key = ReflectionUtils.ConvertBasicType(childElem.Attribute_NamespaceSafe(keyAlias, m_documentDefaultNamespace).Value, keyType);
                    }
                    else if (isKeyContent)
                    {
                        key = ReflectionUtils.ConvertBasicType(childElem.GetXmlContent(), keyType);
                    }
                    else if (ReflectionUtils.IsBasicType(keyType))
                    {
                        key = ReflectionUtils.ConvertBasicType(childElem.Element(keyAlias).Value, keyType);
                    }
                    else
                    {
                        if (keySer == null)
                            keySer = NewInternalSerializer(keyType, keyAlias.Namespace, null);

                        key = keySer.DeserializeBase(childElem.Element(keyAlias));
                        FinalizeNewSerializer(keySer, false);
                    }
                }

                if (isValueFound)
                {
                    if (isValueAttrib)
                    {
                        value = ReflectionUtils.ConvertBasicType(childElem.Attribute_NamespaceSafe(valueAlias, m_documentDefaultNamespace).Value, valueType);
                    }
                    else if (isValueContent)
                    {
                        value = ReflectionUtils.ConvertBasicType(childElem.GetXmlContent(), valueType);
                    }
                    else if (ReflectionUtils.IsBasicType(valueType))
                    {
                        value = ReflectionUtils.ConvertBasicType(childElem.Element(valueAlias).Value, valueType);
                    }
                    else
                    {
                        if (valueSer == null)
                            valueSer = NewInternalSerializer(valueType, valueAlias.Namespace, null);

                        value = valueSer.DeserializeBase(childElem.Element(valueAlias));
                        FinalizeNewSerializer(valueSer, false);
                    }
                }

                try
                {
                    type.InvokeMember("Add", BindingFlags.InvokeMethod, null, dic, new object[] { key, value });
                }
                catch
                {
                    OnExceptionOccurred(
                        new YAXCannotAddObjectToCollection(alias.LocalName, new KeyValuePair<object, object>(key, value)),
                        m_defaultExceptionType);
                }
            }

            return dic;
        }