Inheritance: TypeModel
Beispiel #1
0
        public TypeModel GetTypeModel(Type type) {
            TypeModel model = (TypeModel)models[type];
            if (model != null) return model;
            TypeDesc typeDesc = typeScope.GetTypeDesc(type);

            switch (typeDesc.Kind) {
                case TypeKind.Enum: 
                    model = new EnumModel(type, typeDesc, this);
                    break;
                case TypeKind.Primitive:
                    model = new PrimitiveModel(type, typeDesc, this);
                    break;
                case TypeKind.Array:
                case TypeKind.Collection:
                case TypeKind.Enumerable:
                    model = new ArrayModel(type, typeDesc, this);
                    break;
                case TypeKind.Root:
                case TypeKind.Class:
                case TypeKind.Struct:
                case TypeKind.Interface:
                    model = new StructModel(type, typeDesc, this);
                    break;
                default:
                    if (!typeDesc.IsSpecial) throw new NotSupportedException(Res.GetString(Res.XmlUnsupportedTypeKind, type.FullName));
                    model = new SpecialModel(type, typeDesc, this);
                    break;
            }

            models.Add(type, model);
            return model;
        }
Beispiel #2
0
        internal TypeModel GetTypeModel(Type type, bool directReference)
        {
            TypeModel model;
            if (_models.TryGetValue(type, out model))
                return model;
            TypeDesc typeDesc = _typeScope.GetTypeDesc(type, null, directReference);

            switch (typeDesc.Kind)
            {
                case TypeKind.Enum:
                    model = new EnumModel(type, typeDesc, this);
                    break;
                case TypeKind.Primitive:
                    model = new PrimitiveModel(type, typeDesc, this);
                    break;
                case TypeKind.Array:
                case TypeKind.Collection:
                case TypeKind.Enumerable:
                    model = new ArrayModel(type, typeDesc, this);
                    break;
                case TypeKind.Root:
                case TypeKind.Class:
                case TypeKind.Struct:
                    model = new StructModel(type, typeDesc, this);
                    break;
                default:
                    if (!typeDesc.IsSpecial) throw new NotSupportedException(SR.Format(SR.XmlUnsupportedTypeKind, type.FullName));
                    model = new SpecialModel(type, typeDesc, this);
                    break;
            }

            _models.Add(type, model);
            return model;
        }
Beispiel #3
0
        private StructMapping ImportStructLikeMapping(StructModel model, RecursionLimiter limiter)
        {
            if (model.TypeDesc.Kind == TypeKind.Root)
            {
                return(this.GetRootMapping());
            }
            SoapAttributes a         = this.GetAttributes(model.Type);
            string         defaultNs = this.defaultNs;

            if ((a.SoapType != null) && (a.SoapType.Namespace != null))
            {
                defaultNs = a.SoapType.Namespace;
            }
            string        typeName    = XmlConvert.EncodeLocalName(this.XsdTypeName(model.Type, a, model.TypeDesc.Name));
            StructMapping typeMapping = (StructMapping)this.GetTypeMapping(typeName, defaultNs, model.TypeDesc);

            if (typeMapping == null)
            {
                typeMapping = new StructMapping {
                    IsSoap    = true,
                    TypeDesc  = model.TypeDesc,
                    Namespace = defaultNs,
                    TypeName  = typeName
                };
                if (a.SoapType != null)
                {
                    typeMapping.IncludeInSchema = a.SoapType.IncludeInSchema;
                }
                this.typeScope.AddTypeMapping(typeMapping);
                this.types.Add(typeName, defaultNs, typeMapping);
                if (limiter.IsExceededLimit)
                {
                    limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, typeMapping));
                    return(typeMapping);
                }
                limiter.Depth++;
                this.InitializeStructMembers(typeMapping, model, limiter);
                while (limiter.DeferredWorkItems.Count > 0)
                {
                    int index = limiter.DeferredWorkItems.Count - 1;
                    ImportStructWorkItem item = limiter.DeferredWorkItems[index];
                    if (this.InitializeStructMembers(item.Mapping, item.Model, limiter))
                    {
                        limiter.DeferredWorkItems.RemoveAt(index);
                    }
                }
                limiter.Depth--;
            }
            return(typeMapping);
        }
Beispiel #4
0
        internal FieldModel(MemberInfo memberInfo, Type fieldType, TypeDesc fieldTypeDesc)
        {
            _name          = memberInfo.Name;
            _fieldType     = fieldType;
            _fieldTypeDesc = fieldTypeDesc;
            _memberInfo    = memberInfo;
            _checkShouldPersistMethodInfo = memberInfo.DeclaringType !.GetMethod($"ShouldSerialize{memberInfo.Name}", Type.EmptyTypes);
            _checkShouldPersist           = _checkShouldPersistMethodInfo != null;

            FieldInfo?specifiedField = memberInfo.DeclaringType.GetField($"{memberInfo.Name}Specified");

            if (specifiedField != null)
            {
                if (specifiedField.FieldType != typeof(bool))
                {
                    throw new InvalidOperationException(SR.Format(SR.XmlInvalidSpecifiedType, specifiedField.Name, specifiedField.FieldType.FullName, typeof(bool).FullName));
                }
                _checkSpecified           = specifiedField.IsInitOnly ? SpecifiedAccessor.ReadOnly : SpecifiedAccessor.ReadWrite;
                _checkSpecifiedMemberInfo = specifiedField;
            }
            else
            {
                PropertyInfo?specifiedProperty = memberInfo.DeclaringType.GetProperty($"{memberInfo.Name}Specified");
                if (specifiedProperty != null)
                {
                    if (StructModel.CheckPropertyRead(specifiedProperty))
                    {
                        _checkSpecified           = specifiedProperty.CanWrite ? SpecifiedAccessor.ReadWrite : SpecifiedAccessor.ReadOnly;
                        _checkSpecifiedMemberInfo = specifiedProperty;
                    }
                    if (_checkSpecified != SpecifiedAccessor.None && specifiedProperty.PropertyType != typeof(bool))
                    {
                        throw new InvalidOperationException(SR.Format(SR.XmlInvalidSpecifiedType, specifiedProperty.Name, specifiedProperty.PropertyType.FullName, typeof(bool).FullName));
                    }
                }
            }
            if (memberInfo is PropertyInfo)
            {
                _readOnly   = !((PropertyInfo)memberInfo).CanWrite;
                _isProperty = true;
            }
            else if (memberInfo is FieldInfo)
            {
                _readOnly = ((FieldInfo)memberInfo).IsInitOnly;
            }
        }
Beispiel #5
0
        internal FieldModel(MemberInfo memberInfo, Type fieldType, TypeDesc fieldTypeDesc)
        {
            this.name          = memberInfo.Name;
            this.fieldType     = fieldType;
            this.fieldTypeDesc = fieldTypeDesc;
            this.memberInfo    = memberInfo;
            this.checkShouldPersistMethodInfo = memberInfo.DeclaringType.GetMethod("ShouldSerialize" + memberInfo.Name, new Type[0]);
            this.checkShouldPersist           = this.checkShouldPersistMethodInfo != null;

            FieldInfo specifiedField = memberInfo.DeclaringType.GetField(memberInfo.Name + "Specified");

            if (specifiedField != null)
            {
                if (specifiedField.FieldType != typeof(bool))
                {
                    throw new InvalidOperationException(Res.GetString(Res.XmlInvalidSpecifiedType, specifiedField.Name, specifiedField.FieldType.FullName, typeof(bool).FullName));
                }
                this.checkSpecified           = specifiedField.IsInitOnly ? SpecifiedAccessor.ReadOnly : SpecifiedAccessor.ReadWrite;
                this.checkSpecifiedMemberInfo = specifiedField;
            }
            else
            {
                PropertyInfo specifiedProperty = memberInfo.DeclaringType.GetProperty(memberInfo.Name + "Specified");
                if (specifiedProperty != null)
                {
                    if (StructModel.CheckPropertyRead(specifiedProperty))
                    {
                        this.checkSpecified           = specifiedProperty.CanWrite ? SpecifiedAccessor.ReadWrite : SpecifiedAccessor.ReadOnly;
                        this.checkSpecifiedMemberInfo = specifiedProperty;
                    }
                    if (this.checkSpecified != SpecifiedAccessor.None && specifiedProperty.PropertyType != typeof(bool))
                    {
                        throw new InvalidOperationException(Res.GetString(Res.XmlInvalidSpecifiedType, specifiedProperty.Name, specifiedProperty.PropertyType.FullName, typeof(bool).FullName));
                    }
                }
            }
            if (memberInfo is PropertyInfo)
            {
                readOnly   = !((PropertyInfo)memberInfo).CanWrite;
                isProperty = true;
            }
            else if (memberInfo is FieldInfo)
            {
                readOnly = ((FieldInfo)memberInfo).IsInitOnly;
            }
        }
Beispiel #6
0
        public TypeModel GetTypeModel(Type type)
        {
            TypeModel model = (TypeModel)models[type];

            if (model != null)
            {
                return(model);
            }
            TypeDesc typeDesc = typeScope.GetTypeDesc(type);

            switch (typeDesc.Kind)
            {
            case TypeKind.Enum:
                model = new EnumModel(type, typeDesc, this);
                break;

            case TypeKind.Primitive:
                model = new PrimitiveModel(type, typeDesc, this);
                break;

            case TypeKind.Array:
            case TypeKind.Collection:
            case TypeKind.Enumerable:
                model = new ArrayModel(type, typeDesc, this);
                break;

            case TypeKind.Root:
            case TypeKind.Class:
            case TypeKind.Struct:
            case TypeKind.Interface:
                model = new StructModel(type, typeDesc, this);
                break;

            default:
                if (!typeDesc.IsSpecial)
                {
                    throw new NotSupportedException(Res.GetString(Res.XmlUnsupportedTypeKind, type.FullName));
                }
                model = new SpecialModel(type, typeDesc, this);
                break;
            }

            models.Add(type, model);
            return(model);
        }
Beispiel #7
0
        internal TypeModel GetTypeModel(Type type, bool directReference)
        {
            TypeModel?model;

            if (_models.TryGetValue(type, out model))
            {
                return(model);
            }
            TypeDesc typeDesc = _typeScope.GetTypeDesc(type, null, directReference);

            switch (typeDesc.Kind)
            {
            case TypeKind.Enum:
                model = new EnumModel(type, typeDesc, this);
                break;

            case TypeKind.Primitive:
                model = new PrimitiveModel(type, typeDesc, this);
                break;

            case TypeKind.Array:
            case TypeKind.Collection:
            case TypeKind.Enumerable:
                model = new ArrayModel(type, typeDesc, this);
                break;

            case TypeKind.Root:
            case TypeKind.Class:
            case TypeKind.Struct:
                model = new StructModel(type, typeDesc, this);
                break;

            default:
                if (!typeDesc.IsSpecial)
                {
                    throw new NotSupportedException(SR.Format(SR.XmlUnsupportedTypeKind, type.FullName));
                }
                model = new SpecialModel(type, typeDesc, this);
                break;
            }

            _models.Add(type, model);
            return(model);
        }
Beispiel #8
0
        internal FieldModel(MemberInfo memberInfo, Type fieldType, TypeDesc fieldTypeDesc)
        {
            this.name               = memberInfo.Name;
            this.fieldType          = fieldType;
            this.fieldTypeDesc      = fieldTypeDesc;
            this.checkShouldPersist = memberInfo.DeclaringType.GetMethod("ShouldSerialize" + memberInfo.Name, new Type[0]) != null;
            FieldInfo field = memberInfo.DeclaringType.GetField(memberInfo.Name + "Specified");

            if (field != null)
            {
                if (field.FieldType != typeof(bool))
                {
                    throw new InvalidOperationException(Res.GetString("XmlInvalidSpecifiedType", new object[] { field.Name, field.FieldType.FullName, typeof(bool).FullName }));
                }
                this.checkSpecified = field.IsInitOnly ? SpecifiedAccessor.ReadOnly : SpecifiedAccessor.ReadWrite;
            }
            else
            {
                PropertyInfo property = memberInfo.DeclaringType.GetProperty(memberInfo.Name + "Specified");
                if (property != null)
                {
                    if (StructModel.CheckPropertyRead(property))
                    {
                        this.checkSpecified = property.CanWrite ? SpecifiedAccessor.ReadWrite : SpecifiedAccessor.ReadOnly;
                    }
                    if ((this.checkSpecified != SpecifiedAccessor.None) && (property.PropertyType != typeof(bool)))
                    {
                        throw new InvalidOperationException(Res.GetString("XmlInvalidSpecifiedType", new object[] { property.Name, property.PropertyType.FullName, typeof(bool).FullName }));
                    }
                }
            }
            if (memberInfo is PropertyInfo)
            {
                this.readOnly   = !((PropertyInfo)memberInfo).CanWrite;
                this.isProperty = true;
            }
            else if (memberInfo is FieldInfo)
            {
                this.readOnly = ((FieldInfo)memberInfo).IsInitOnly;
            }
        }
        internal TypeModel GetTypeModel(Type type, bool directReference)
        {
            TypeModel model = (TypeModel)this.models[type];

            if (model == null)
            {
                TypeDesc typeDesc = this.typeScope.GetTypeDesc(type, null, directReference);
                switch (typeDesc.Kind)
                {
                case TypeKind.Root:
                case TypeKind.Struct:
                case TypeKind.Class:
                    model = new StructModel(type, typeDesc, this);
                    break;

                case TypeKind.Primitive:
                    model = new PrimitiveModel(type, typeDesc, this);
                    break;

                case TypeKind.Enum:
                    model = new EnumModel(type, typeDesc, this);
                    break;

                case TypeKind.Array:
                case TypeKind.Collection:
                case TypeKind.Enumerable:
                    model = new ArrayModel(type, typeDesc, this);
                    break;

                default:
                    if (!typeDesc.IsSpecial)
                    {
                        throw new NotSupportedException(Res.GetString("XmlUnsupportedTypeKind", new object[] { type.FullName }));
                    }
                    model = new SpecialModel(type, typeDesc, this);
                    break;
                }
                this.models.Add(type, model);
            }
            return(model);
        }
        internal TypeModel GetTypeModel(Type type, bool directReference)
        {
            TypeModel model = (TypeModel) this.models[type];
            if (model == null)
            {
                TypeDesc typeDesc = this.typeScope.GetTypeDesc(type, null, directReference);
                switch (typeDesc.Kind)
                {
                    case TypeKind.Root:
                    case TypeKind.Struct:
                    case TypeKind.Class:
                        model = new StructModel(type, typeDesc, this);
                        break;

                    case TypeKind.Primitive:
                        model = new PrimitiveModel(type, typeDesc, this);
                        break;

                    case TypeKind.Enum:
                        model = new EnumModel(type, typeDesc, this);
                        break;

                    case TypeKind.Array:
                    case TypeKind.Collection:
                    case TypeKind.Enumerable:
                        model = new ArrayModel(type, typeDesc, this);
                        break;

                    default:
                        if (!typeDesc.IsSpecial)
                        {
                            throw new NotSupportedException(Res.GetString("XmlUnsupportedTypeKind", new object[] { type.FullName }));
                        }
                        model = new SpecialModel(type, typeDesc, this);
                        break;
                }
                this.models.Add(type, model);
            }
            return model;
        }
Beispiel #11
0
        private bool InitializeStructMembers(StructMapping mapping, StructModel model, RecursionLimiter limiter)
        {
            if (mapping.IsFullyInitialized)
            {
                return(true);
            }
            if (model.TypeDesc.BaseTypeDesc != null)
            {
                StructMapping baseMapping = ImportStructLikeMapping((StructModel)_modelScope.GetTypeModel(model.Type.BaseType, false), limiter);

                // check to see if the import of the baseMapping was deferred
                int baseIndex = limiter.DeferredWorkItems.IndexOf(mapping.BaseMapping);
                if (baseIndex < 0)
                {
                    mapping.BaseMapping = baseMapping;
                }
                else
                {
                    // the import of the baseMapping was deferred, make sure that the derived mappings is deferred as well
                    if (!limiter.DeferredWorkItems.Contains(mapping))
                    {
                        limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping));
                    }
                    // make sure that baseMapping get processed before the derived
                    int top = limiter.DeferredWorkItems.Count - 1;
                    if (baseIndex < top)
                    {
                        ImportStructWorkItem baseMappingWorkItem = limiter.DeferredWorkItems[baseIndex];
                        limiter.DeferredWorkItems[baseIndex] = limiter.DeferredWorkItems[top];
                        limiter.DeferredWorkItems[top]       = baseMappingWorkItem;
                    }
                    return(false);
                }
            }
            ArrayList members = new ArrayList();

            foreach (MemberInfo memberInfo in model.GetMemberInfos())
            {
                if (!(memberInfo is FieldInfo) && !(memberInfo is PropertyInfo))
                {
                    continue;
                }
                SoapAttributes memberAttrs = GetAttributes(memberInfo);
                if (memberAttrs.SoapIgnore)
                {
                    continue;
                }
                FieldModel fieldModel = model.GetFieldModel(memberInfo);
                if (fieldModel == null)
                {
                    continue;
                }
                MemberMapping member = ImportFieldMapping(fieldModel, memberAttrs, mapping.Namespace, limiter);
                if (member == null)
                {
                    continue;
                }

                if (!member.TypeDesc.IsPrimitive && !member.TypeDesc.IsEnum && !member.TypeDesc.IsOptionalValue)
                {
                    if (model.TypeDesc.IsValueType)
                    {
                        throw new NotSupportedException(SR.Format(SR.XmlRpcRefsInValueType, model.TypeDesc.FullName));
                    }
                    if (member.TypeDesc.IsValueType)
                    {
                        throw new NotSupportedException(SR.Format(SR.XmlRpcNestedValueType, member.TypeDesc.FullName));
                    }
                }
                if (mapping.BaseMapping != null)
                {
                    if (mapping.BaseMapping.Declares(member, mapping.TypeName))
                    {
                        continue;
                    }
                }
                members.Add(member);
            }
            mapping.Members = (MemberMapping[])members.ToArray(typeof(MemberMapping));
            if (mapping.BaseMapping == null)
            {
                mapping.BaseMapping = GetRootMapping();
            }
            IncludeTypes(model.Type, limiter);

            return(true);
        }
 private Type GetChoiceIdentifierType(XmlChoiceIdentifierAttribute choice, StructModel structModel, bool isArrayLike, string accessorName)
 {
     MemberInfo[] member = structModel.Type.GetMember(choice.MemberName, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
     if ((member == null) || (member.Length == 0))
     {
         PropertyInfo property = structModel.Type.GetProperty(choice.MemberName, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
         if (property == null)
         {
             throw new InvalidOperationException(Res.GetString("XmlChoiceIdentiferMemberMissing", new object[] { choice.MemberName, accessorName }));
         }
         member = new MemberInfo[] { property };
     }
     else if (member.Length > 1)
     {
         throw new InvalidOperationException(Res.GetString("XmlChoiceIdentiferAmbiguous", new object[] { choice.MemberName }));
     }
     FieldModel fieldModel = structModel.GetFieldModel(member[0]);
     if (fieldModel == null)
     {
         throw new InvalidOperationException(Res.GetString("XmlChoiceIdentiferMemberMissing", new object[] { choice.MemberName, accessorName }));
     }
     Type fieldType = fieldModel.FieldType;
     return this.CheckChoiceIdentifierType(fieldType, isArrayLike, choice.MemberName, accessorName);
 }
        StructMapping ImportStructLikeMapping(StructModel model, string ns, bool openModel, XmlAttributes a) {
            if (model.TypeDesc.Kind == TypeKind.Root) return GetRootMapping();
            if (a == null)
                a = GetAttributes(model.Type, false);

            string typeNs = ns;
            if (a.XmlType != null && a.XmlType.Namespace != null)
                typeNs = a.XmlType.Namespace;
            else if (a.XmlRoot != null && a.XmlRoot.Namespace != null)
                typeNs = a.XmlRoot.Namespace;

            string typeName = XsdTypeName(model.Type, a, model.TypeDesc.Name);
            typeName = XmlConvert.EncodeLocalName(typeName);

            StructMapping mapping = (StructMapping)GetTypeMapping(typeName, typeNs, model.TypeDesc, types, model.Type);
            if (mapping == null) {
                mapping = new StructMapping();
                mapping.TypeDesc = model.TypeDesc;
                mapping.Namespace = typeNs;
                mapping.TypeName = typeName;
                if (!mapping.IsAnonymousType)
                    types.Add(typeName, typeNs, mapping);
                else
                    anonymous[model.Type] = mapping;
                if (a.XmlType != null) {
                    mapping.IncludeInSchema = a.XmlType.IncludeInSchema;
                }

                if (model.TypeDesc.BaseTypeDesc != null) {
                    TypeModel baseModel = modelScope.GetTypeModel(model.Type.BaseType, false);
                    if (!(baseModel is StructModel)) {
                        //XmlUnsupportedInheritance=Using '{0}' as a base type for a class is not supported by XmlSerializer.
                         throw new NotSupportedException(Res.GetString(Res.XmlUnsupportedInheritance, model.Type.BaseType.FullName));
                    }
                    mapping.BaseMapping = ImportStructLikeMapping((StructModel)baseModel, mapping.Namespace, openModel, null);
                    ICollection values = mapping.BaseMapping.LocalAttributes.Values;
                    foreach (AttributeAccessor attribute in values) {
                        AddUniqueAccessor(mapping.LocalAttributes, attribute);
                    }
                    if (!mapping.BaseMapping.HasExplicitSequence()) {
                        values = mapping.BaseMapping.LocalElements.Values;
                        foreach (ElementAccessor e in values) {
                            AddUniqueAccessor(mapping.LocalElements, e);
                        }
                    }
                }
                ArrayList members = new ArrayList();
                TextAccessor textAccesor = null;
                bool hasElements = false;
                bool isSequence = false;
                
                foreach (MemberInfo memberInfo in model.GetMemberInfos()) {
                    if ((memberInfo.MemberType & (MemberTypes.Field | MemberTypes.Property)) == 0)
                        continue;
                    XmlAttributes memberAttrs = GetAttributes(memberInfo);
                    if (memberAttrs.XmlIgnore) continue;
                    FieldModel fieldModel = model.GetFieldModel(memberInfo);
                    if (fieldModel == null) continue;
                    try {
                        MemberMapping member = ImportFieldMapping(model, fieldModel, memberAttrs, mapping.Namespace);
                        if (member == null) continue;
                        if (mapping.BaseMapping != null) {
                            if (mapping.BaseMapping.Declares(member, mapping.TypeName)) continue;
                        }
                        isSequence |= member.IsSequence;
                        // add All memeber accessors to the scope accessors
                        AddUniqueAccessor(member, mapping.LocalElements, mapping.LocalAttributes, isSequence);

                        if (member.Text != null) {
                            if (!member.Text.Mapping.TypeDesc.CanBeTextValue && member.Text.Mapping.IsList)
                                throw new InvalidOperationException(Res.GetString(Res.XmlIllegalTypedTextAttribute, typeName, member.Text.Name, member.Text.Mapping.TypeDesc.FullName));
                            if (textAccesor != null) {
                                throw new InvalidOperationException(Res.GetString(Res.XmlIllegalMultipleText, model.Type.FullName));
                            }
                            textAccesor = member.Text;
                        }
                        if (member.Xmlns != null) {
                            if (mapping.XmlnsMember != null)
                                throw new InvalidOperationException(Res.GetString(Res.XmlMultipleXmlns, model.Type.FullName));
                            mapping.XmlnsMember = member;
                        }
                        if (member.Elements != null && member.Elements.Length != 0) {
                            hasElements = true;
                        }
                        members.Add(member);
                    }
                    catch (Exception e) {
                        if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
                            throw;
                        }
                        throw CreateMemberReflectionException(fieldModel, e);
                    }
                    catch {
                        throw CreateMemberReflectionException(fieldModel, null);
                    }
                }
                mapping.SetContentModel(textAccesor, hasElements);
                if (isSequence) {
                    Hashtable ids = new Hashtable();
                    for (int i = 0; i < members.Count; i++) {
                        MemberMapping member = (MemberMapping)members[i];
                        if (!member.IsParticle)
                            continue;
                        if (member.IsSequence) {
                            if (ids[member.SequenceId] != null) {
                                throw new InvalidOperationException(Res.GetString(Res.XmlSequenceUnique, member.SequenceId.ToString(CultureInfo.InvariantCulture), "Order", member.Name));
                            }
                            ids[member.SequenceId] = member;
                        }
                        else {
                            throw new InvalidOperationException(Res.GetString(Res.XmlSequenceInconsistent, "Order", member.Name));
                        }
                    }
                    members.Sort(new MemberMappingComparer());
                }
                mapping.Members = (MemberMapping[])members.ToArray(typeof(MemberMapping));

                if (mapping.BaseMapping == null) mapping.BaseMapping = GetRootMapping();

                if (mapping.XmlnsMember != null && mapping.BaseMapping.HasXmlnsMember)
                    throw new InvalidOperationException(Res.GetString(Res.XmlMultipleXmlns, model.Type.FullName));

                IncludeTypes(model.Type);
                typeScope.AddTypeMapping(mapping);
            }
            if (openModel)
                mapping.IsOpenModel = true;
            return mapping;
        }
        Type GetChoiceIdentifierType(XmlChoiceIdentifierAttribute choice, StructModel structModel, bool isArrayLike, string accessorName) {
            // check that the choice field exists

            MemberInfo[] infos = structModel.Type.GetMember(choice.MemberName, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
            if (infos == null || infos.Length == 0) {
                // if we can not find the choice identifier between fields, check proerties
                PropertyInfo info = structModel.Type.GetProperty(choice.MemberName, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
                
                if (info == null) {
                    // Missing '{0}' needed for serialization of choice '{1}'.
                    throw new InvalidOperationException(Res.GetString(Res.XmlChoiceIdentiferMemberMissing, choice.MemberName, accessorName));
                }
                infos = new MemberInfo[] { info };
            }
            else if (infos.Length > 1) {
                // Ambiguous choice identifer: there are several members named '{0}'.
                throw new InvalidOperationException(Res.GetString(Res.XmlChoiceIdentiferAmbiguous, choice.MemberName));
            }

            FieldModel member = structModel.GetFieldModel(infos[0]);
            if (member == null) {
                // Missing '{0}' needed for serialization of choice '{1}'.
                throw new InvalidOperationException(Res.GetString(Res.XmlChoiceIdentiferMemberMissing, choice.MemberName, accessorName));
            }
            Type enumType = member.FieldType;
            enumType = CheckChoiceIdentifierType(enumType, isArrayLike, choice.MemberName, accessorName);
            return enumType;
        }
 MemberMapping ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, string ns) {
     MemberMapping member = new MemberMapping();
     member.Name = model.Name;
     member.CheckShouldPersist = model.CheckShouldPersist;
     member.CheckSpecified = model.CheckSpecified;
     member.ReadOnly = model.ReadOnly; // || !model.FieldTypeDesc.HasDefaultConstructor;
     Type choiceIdentifierType = null;
     if (a.XmlChoiceIdentifier != null) {
         choiceIdentifierType = GetChoiceIdentifierType(a.XmlChoiceIdentifier, parent, model.FieldTypeDesc.IsArrayLike, model.Name);
     }
     ImportAccessorMapping(member, model, a, ns, choiceIdentifierType, false, false);
     return member;
 }
 internal ImportStructWorkItem(StructModel model, StructMapping mapping)
 {
     this.model   = model;
     this.mapping = mapping;
 }
 private bool InitializeStructMembers(StructMapping mapping, StructModel model, bool openModel, string typeName, RecursionLimiter limiter)
 {
     if (!mapping.IsFullyInitialized)
     {
         if (model.TypeDesc.BaseTypeDesc != null)
         {
             TypeModel typeModel = this.modelScope.GetTypeModel(model.Type.BaseType, false);
             if (!(typeModel is StructModel))
             {
                 throw new NotSupportedException(Res.GetString("XmlUnsupportedInheritance", new object[] { model.Type.BaseType.FullName }));
             }
             StructMapping mapping2 = this.ImportStructLikeMapping((StructModel) typeModel, mapping.Namespace, openModel, null, limiter);
             int index = limiter.DeferredWorkItems.IndexOf(mapping2);
             if (index >= 0)
             {
                 if (!limiter.DeferredWorkItems.Contains(mapping))
                 {
                     limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping));
                 }
                 int num2 = limiter.DeferredWorkItems.Count - 1;
                 if (index < num2)
                 {
                     ImportStructWorkItem item = limiter.DeferredWorkItems[index];
                     limiter.DeferredWorkItems[index] = limiter.DeferredWorkItems[num2];
                     limiter.DeferredWorkItems[num2] = item;
                 }
                 return false;
             }
             mapping.BaseMapping = mapping2;
             foreach (AttributeAccessor accessor in mapping.BaseMapping.LocalAttributes.Values)
             {
                 AddUniqueAccessor(mapping.LocalAttributes, accessor);
             }
             if (!mapping.BaseMapping.HasExplicitSequence())
             {
                 foreach (ElementAccessor accessor2 in mapping.BaseMapping.LocalElements.Values)
                 {
                     AddUniqueAccessor(mapping.LocalElements, accessor2);
                 }
             }
         }
         ArrayList list = new ArrayList();
         TextAccessor text = null;
         bool hasElements = false;
         bool isSequence = false;
         foreach (MemberInfo info in model.GetMemberInfos())
         {
             if ((info.MemberType & (MemberTypes.Property | MemberTypes.Field)) != 0)
             {
                 XmlAttributes a = this.GetAttributes(info);
                 if (!a.XmlIgnore)
                 {
                     FieldModel fieldModel = model.GetFieldModel(info);
                     if (fieldModel != null)
                     {
                         try
                         {
                             MemberMapping member = this.ImportFieldMapping(model, fieldModel, a, mapping.Namespace, limiter);
                             if ((member != null) && ((mapping.BaseMapping == null) || !mapping.BaseMapping.Declares(member, mapping.TypeName)))
                             {
                                 isSequence |= member.IsSequence;
                                 AddUniqueAccessor(member, mapping.LocalElements, mapping.LocalAttributes, isSequence);
                                 if (member.Text != null)
                                 {
                                     if (!member.Text.Mapping.TypeDesc.CanBeTextValue && member.Text.Mapping.IsList)
                                     {
                                         throw new InvalidOperationException(Res.GetString("XmlIllegalTypedTextAttribute", new object[] { typeName, member.Text.Name, member.Text.Mapping.TypeDesc.FullName }));
                                     }
                                     if (text != null)
                                     {
                                         throw new InvalidOperationException(Res.GetString("XmlIllegalMultipleText", new object[] { model.Type.FullName }));
                                     }
                                     text = member.Text;
                                 }
                                 if (member.Xmlns != null)
                                 {
                                     if (mapping.XmlnsMember != null)
                                     {
                                         throw new InvalidOperationException(Res.GetString("XmlMultipleXmlns", new object[] { model.Type.FullName }));
                                     }
                                     mapping.XmlnsMember = member;
                                 }
                                 if ((member.Elements != null) && (member.Elements.Length != 0))
                                 {
                                     hasElements = true;
                                 }
                                 list.Add(member);
                             }
                         }
                         catch (Exception exception)
                         {
                             if (((exception is ThreadAbortException) || (exception is StackOverflowException)) || (exception is OutOfMemoryException))
                             {
                                 throw;
                             }
                             throw this.CreateMemberReflectionException(fieldModel, exception);
                         }
                     }
                 }
             }
         }
         mapping.SetContentModel(text, hasElements);
         if (isSequence)
         {
             Hashtable hashtable = new Hashtable();
             for (int i = 0; i < list.Count; i++)
             {
                 MemberMapping mapping4 = (MemberMapping) list[i];
                 if (mapping4.IsParticle)
                 {
                     if (!mapping4.IsSequence)
                     {
                         throw new InvalidOperationException(Res.GetString("XmlSequenceInconsistent", new object[] { "Order", mapping4.Name }));
                     }
                     if (hashtable[mapping4.SequenceId] != null)
                     {
                         throw new InvalidOperationException(Res.GetString("XmlSequenceUnique", new object[] { mapping4.SequenceId.ToString(CultureInfo.InvariantCulture), "Order", mapping4.Name }));
                     }
                     hashtable[mapping4.SequenceId] = mapping4;
                 }
             }
             list.Sort(new MemberMappingComparer());
         }
         mapping.Members = (MemberMapping[]) list.ToArray(typeof(MemberMapping));
         if (mapping.BaseMapping == null)
         {
             mapping.BaseMapping = this.GetRootMapping();
         }
         if ((mapping.XmlnsMember != null) && mapping.BaseMapping.HasXmlnsMember)
         {
             throw new InvalidOperationException(Res.GetString("XmlMultipleXmlns", new object[] { model.Type.FullName }));
         }
         this.IncludeTypes(model.Type, limiter);
         this.typeScope.AddTypeMapping(mapping);
         if (openModel)
         {
             mapping.IsOpenModel = true;
         }
     }
     return true;
 }
Beispiel #18
0
        private bool InitializeStructMembers(StructMapping mapping, StructModel model, RecursionLimiter limiter)
        {
            if (mapping.IsFullyInitialized)
                return true;
            if (model.TypeDesc.BaseTypeDesc != null)
            {
                StructMapping baseMapping = ImportStructLikeMapping((StructModel)_modelScope.GetTypeModel(model.Type.GetTypeInfo().BaseType, false), limiter);

                // check to see if the import of the baseMapping was deffered
                int baseIndex = limiter.DeferredWorkItems.IndexOf(mapping.BaseMapping);
                if (baseIndex < 0)
                {
                    mapping.BaseMapping = baseMapping;
                }
                else
                {
                    // the import of the baseMapping was deffered, make sure that the derived mappings is deffered as well
                    if (!limiter.DeferredWorkItems.Contains(mapping))
                    {
                        limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping));
                    }
                    // make sure that baseMapping get processed before the derived
                    int top = limiter.DeferredWorkItems.Count - 1;
                    if (baseIndex < top)
                    {
                        ImportStructWorkItem baseMappingWorkItem = limiter.DeferredWorkItems[baseIndex];
                        limiter.DeferredWorkItems[baseIndex] = limiter.DeferredWorkItems[top];
                        limiter.DeferredWorkItems[top] = baseMappingWorkItem;
                    }
                    return false;
                }
            }
            ArrayList members = new ArrayList();
            foreach (MemberInfo memberInfo in model.GetMemberInfos())
            {
                if (!(memberInfo is FieldInfo) && !(memberInfo is PropertyInfo))
                    continue;
                SoapAttributes memberAttrs = GetAttributes(memberInfo);
                if (memberAttrs.SoapIgnore) continue;
                FieldModel fieldModel = model.GetFieldModel(memberInfo);
                if (fieldModel == null) continue;
                MemberMapping member = ImportFieldMapping(fieldModel, memberAttrs, mapping.Namespace, limiter);
                if (member == null) continue;

                if (!member.TypeDesc.IsPrimitive && !member.TypeDesc.IsEnum && !member.TypeDesc.IsOptionalValue)
                {
                    if (model.TypeDesc.IsValueType)
                        throw new NotSupportedException(SR.Format(SR.XmlRpcRefsInValueType, model.TypeDesc.FullName));
                    if (member.TypeDesc.IsValueType)
                        throw new NotSupportedException(SR.Format(SR.XmlRpcNestedValueType, member.TypeDesc.FullName));
                }
                if (mapping.BaseMapping != null)
                {
                    if (mapping.BaseMapping.Declares(member, mapping.TypeName)) continue;
                }
                members.Add(member);
            }
            mapping.Members = (MemberMapping[])members.ToArray(typeof(MemberMapping));
            if (mapping.BaseMapping == null) mapping.BaseMapping = GetRootMapping();
            IncludeTypes(model.Type.GetTypeInfo(), limiter);

            return true;
        }
        StructMapping ImportStructLikeMapping(StructModel model)
        {
            if (model.TypeDesc.Kind == TypeKind.Root)
            {
                return(GetRootMapping());
            }

            SoapAttributes a = GetAttributes(model.Type);

            string typeNs = defaultNs;

            if (a.SoapType != null && a.SoapType.Namespace != null)
            {
                typeNs = a.SoapType.Namespace;
            }

            string typeName = string.Empty;

            if (a.SoapType != null)
            {
                typeName = a.SoapType.TypeName;
            }
            if (typeName.Length == 0)
            {
                typeName = model.TypeDesc.Name;
            }


            StructMapping mapping = (StructMapping)GetTypeMapping(typeName, typeNs, model.TypeDesc);

            if (mapping == null)
            {
                mapping           = new StructMapping();
                mapping.IsSoap    = true;
                mapping.TypeDesc  = model.TypeDesc;
                mapping.Namespace = typeNs;
                mapping.TypeName  = typeName;
                if (a.SoapType != null)
                {
                    mapping.IncludeInSchema = a.SoapType.IncludeInSchema;
                }
                typeScope.AddTypeMapping(mapping);
                types.Add(typeName, typeNs, mapping);
                if (model.TypeDesc.BaseTypeDesc != null)
                {
                    mapping.BaseMapping = ImportStructLikeMapping((StructModel)modelScope.GetTypeModel(model.Type.BaseType, false));
                }
                ArrayList members = new ArrayList();
                foreach (MemberInfo memberInfo in model.GetMemberInfos())
                {
                    SoapAttributes memberAttrs = GetAttributes(memberInfo);
                    if (memberAttrs.SoapIgnore)
                    {
                        continue;
                    }
                    FieldModel fieldModel = model.GetFieldModel(memberInfo);
                    if (fieldModel == null)
                    {
                        continue;
                    }
                    MemberMapping member = ImportFieldMapping(fieldModel, memberAttrs, mapping.Namespace);
                    if (member == null)
                    {
                        continue;
                    }

                    if (!member.TypeDesc.IsPrimitive && !member.TypeDesc.IsEnum)
                    {
                        if (model.TypeDesc.IsValueType)
                        {
                            throw new NotSupportedException(Res.GetString(Res.XmlRpcRefsInValueType, model.TypeDesc.FullName));
                        }
                        if (member.TypeDesc.IsValueType)
                        {
                            throw new NotSupportedException(Res.GetString(Res.XmlRpcNestedValueType, member.TypeDesc.FullName));
                        }
                    }
                    if (mapping.BaseMapping != null)
                    {
                        if (mapping.BaseMapping.Declares(member, mapping.TypeName))
                        {
                            continue;
                        }
                    }
                    members.Add(member);
                }
                mapping.Members = (MemberMapping[])members.ToArray(typeof(MemberMapping));
                if (mapping.BaseMapping == null)
                {
                    mapping.BaseMapping = GetRootMapping();
                }
                IncludeTypes(model.Type);
            }
            return(mapping);
        }
 internal ImportStructWorkItem(StructModel model, StructMapping mapping) {
     this.model = model;
     this.mapping = mapping;
 }
 private MemberMapping ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, string ns, RecursionLimiter limiter)
 {
     MemberMapping accessor = new MemberMapping {
         Name = model.Name,
         CheckShouldPersist = model.CheckShouldPersist,
         CheckSpecified = model.CheckSpecified,
         ReadOnly = model.ReadOnly
     };
     Type choiceIdentifierType = null;
     if (a.XmlChoiceIdentifier != null)
     {
         choiceIdentifierType = this.GetChoiceIdentifierType(a.XmlChoiceIdentifier, parent, model.FieldTypeDesc.IsArrayLike, model.Name);
     }
     this.ImportAccessorMapping(accessor, model, a, ns, choiceIdentifierType, false, false, limiter);
     return accessor;
 }
 internal ImportStructWorkItem(StructModel model, StructMapping mapping)
 {
     _model = model;
     _mapping = mapping;
 }
Beispiel #23
0
        private StructMapping ImportStructLikeMapping(StructModel model, RecursionLimiter limiter)
        {
            if (model.TypeDesc.Kind == TypeKind.Root) return GetRootMapping();

            SoapAttributes a = GetAttributes(model.Type);

            string typeNs = _defaultNs;
            if (a.SoapType != null && a.SoapType.Namespace != null)
                typeNs = a.SoapType.Namespace;
            string typeName = XsdTypeName(model.Type, a, model.TypeDesc.Name);
            typeName = XmlConvert.EncodeLocalName(typeName);

            StructMapping mapping = (StructMapping)GetTypeMapping(typeName, typeNs, model.TypeDesc);
            if (mapping == null)
            {
                mapping = new StructMapping();
                mapping.IsSoap = true;
                mapping.TypeDesc = model.TypeDesc;
                mapping.Namespace = typeNs;
                mapping.TypeName = typeName;
                if (a.SoapType != null) mapping.IncludeInSchema = a.SoapType.IncludeInSchema;
                _typeScope.AddTypeMapping(mapping);
                _types.Add(typeName, typeNs, mapping);
                if (limiter.IsExceededLimit)
                {
                    limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping));
                    return mapping;
                }

                limiter.Depth++;

                InitializeStructMembers(mapping, model, limiter);
                while (limiter.DeferredWorkItems.Count > 0)
                {
                    int index = limiter.DeferredWorkItems.Count - 1;
                    ImportStructWorkItem item = limiter.DeferredWorkItems[index];
                    if (InitializeStructMembers(item.Mapping, item.Model, limiter))
                    {
                        //
                        // if InitializeStructMembers returns true, then there were *no* chages to the DeferredWorkItems
                        //
#if DEBUG
                        // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
                        if (index != limiter.DeferredWorkItems.Count - 1)
                            throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorDetails, "DeferredWorkItems.Count have changed"));
                        if (item != limiter.DeferredWorkItems[index])
                            throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorDetails, "DeferredWorkItems.Top have changed"));
#endif
                        // Remove the last work item
                        limiter.DeferredWorkItems.RemoveAt(index);
                    }
                }
                limiter.Depth--;
            }
            return mapping;
        }
Beispiel #24
0
 private bool InitializeStructMembers(StructMapping mapping, StructModel model, RecursionLimiter limiter)
 {
     if (!mapping.IsFullyInitialized)
     {
         if (model.TypeDesc.BaseTypeDesc != null)
         {
             StructMapping mapping2 = this.ImportStructLikeMapping((StructModel)this.modelScope.GetTypeModel(model.Type.BaseType, false), limiter);
             int           index    = limiter.DeferredWorkItems.IndexOf(mapping.BaseMapping);
             if (index >= 0)
             {
                 if (!limiter.DeferredWorkItems.Contains(mapping))
                 {
                     limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping));
                 }
                 int num2 = limiter.DeferredWorkItems.Count - 1;
                 if (index < num2)
                 {
                     ImportStructWorkItem item = limiter.DeferredWorkItems[index];
                     limiter.DeferredWorkItems[index] = limiter.DeferredWorkItems[num2];
                     limiter.DeferredWorkItems[num2]  = item;
                 }
                 return(false);
             }
             mapping.BaseMapping = mapping2;
         }
         ArrayList list = new ArrayList();
         foreach (MemberInfo info in model.GetMemberInfos())
         {
             if ((info.MemberType & (MemberTypes.Property | MemberTypes.Field)) != 0)
             {
                 SoapAttributes a = this.GetAttributes(info);
                 if (!a.SoapIgnore)
                 {
                     FieldModel fieldModel = model.GetFieldModel(info);
                     if (fieldModel != null)
                     {
                         MemberMapping member = this.ImportFieldMapping(fieldModel, a, mapping.Namespace, limiter);
                         if (member != null)
                         {
                             if ((!member.TypeDesc.IsPrimitive && !member.TypeDesc.IsEnum) && !member.TypeDesc.IsOptionalValue)
                             {
                                 if (model.TypeDesc.IsValueType)
                                 {
                                     throw new NotSupportedException(Res.GetString("XmlRpcRefsInValueType", new object[] { model.TypeDesc.FullName }));
                                 }
                                 if (member.TypeDesc.IsValueType)
                                 {
                                     throw new NotSupportedException(Res.GetString("XmlRpcNestedValueType", new object[] { member.TypeDesc.FullName }));
                                 }
                             }
                             if ((mapping.BaseMapping == null) || !mapping.BaseMapping.Declares(member, mapping.TypeName))
                             {
                                 list.Add(member);
                             }
                         }
                     }
                 }
             }
         }
         mapping.Members = (MemberMapping[])list.ToArray(typeof(MemberMapping));
         if (mapping.BaseMapping == null)
         {
             mapping.BaseMapping = this.GetRootMapping();
         }
         this.IncludeTypes(model.Type, limiter);
     }
     return(true);
 }
        StructMapping ImportStructLikeMapping(StructModel model, string ns, bool openModel, XmlAttributes a, RecursionLimiter limiter) {
            if (model.TypeDesc.Kind == TypeKind.Root) return GetRootMapping();
            if (a == null)
                a = GetAttributes(model.Type, false);

            string typeNs = ns;
            if (a.XmlType != null && a.XmlType.Namespace != null)
                typeNs = a.XmlType.Namespace;
            else if (a.XmlRoot != null && a.XmlRoot.Namespace != null)
                typeNs = a.XmlRoot.Namespace;

            string typeName = IsAnonymousType(a, ns) ? null : XsdTypeName(model.Type, a, model.TypeDesc.Name);
            typeName = XmlConvert.EncodeLocalName(typeName);

            StructMapping mapping = (StructMapping)GetTypeMapping(typeName, typeNs, model.TypeDesc, types, model.Type);
            if (mapping == null) {
                mapping = new StructMapping();
                mapping.TypeDesc = model.TypeDesc;
                mapping.Namespace = typeNs;
                mapping.TypeName = typeName;
                if (!mapping.IsAnonymousType)
                    types.Add(typeName, typeNs, mapping);
                else
                    anonymous[model.Type] = mapping;
                if (a.XmlType != null) {
                    mapping.IncludeInSchema = a.XmlType.IncludeInSchema;
                }

                if (limiter.IsExceededLimit) {
                    limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping));
                    return mapping;
                }

                limiter.Depth++;

                InitializeStructMembers(mapping, model, openModel, typeName, limiter);
                while (limiter.DeferredWorkItems.Count > 0) {
                    int index = limiter.DeferredWorkItems.Count - 1;
                    ImportStructWorkItem item = limiter.DeferredWorkItems[index];
                    if (InitializeStructMembers(item.Mapping, item.Model, openModel, typeName, limiter)) {
                        //
                        // if InitializeStructMembers returns true, then there were *no* chages to the DeferredWorkItems
                        //
#if DEBUG
                    // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
                    if (index != limiter.DeferredWorkItems.Count - 1)
                        throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "DeferredWorkItems.Count have changed"));
                    if (item != limiter.DeferredWorkItems[index])
                        throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "DeferredWorkItems.Top have changed"));
#endif
                        // Remove the last work item
                        limiter.DeferredWorkItems.RemoveAt(index);
                    }
                }
                limiter.Depth--;
            }
            return mapping;
        }
 private StructMapping ImportStructLikeMapping(StructModel model, string ns, bool openModel, XmlAttributes a, RecursionLimiter limiter)
 {
     if (model.TypeDesc.Kind == TypeKind.Root)
     {
         return this.GetRootMapping();
     }
     if (a == null)
     {
         a = this.GetAttributes(model.Type, false);
     }
     string str = ns;
     if ((a.XmlType != null) && (a.XmlType.Namespace != null))
     {
         str = a.XmlType.Namespace;
     }
     else if ((a.XmlRoot != null) && (a.XmlRoot.Namespace != null))
     {
         str = a.XmlRoot.Namespace;
     }
     string name = IsAnonymousType(a, ns) ? null : this.XsdTypeName(model.Type, a, model.TypeDesc.Name);
     name = XmlConvert.EncodeLocalName(name);
     StructMapping mapping = (StructMapping) this.GetTypeMapping(name, str, model.TypeDesc, this.types, model.Type);
     if (mapping == null)
     {
         mapping = new StructMapping {
             TypeDesc = model.TypeDesc,
             Namespace = str,
             TypeName = name
         };
         if (!mapping.IsAnonymousType)
         {
             this.types.Add(name, str, mapping);
         }
         else
         {
             this.anonymous[model.Type] = mapping;
         }
         if (a.XmlType != null)
         {
             mapping.IncludeInSchema = a.XmlType.IncludeInSchema;
         }
         if (limiter.IsExceededLimit)
         {
             limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping));
             return mapping;
         }
         limiter.Depth++;
         this.InitializeStructMembers(mapping, model, openModel, name, limiter);
         while (limiter.DeferredWorkItems.Count > 0)
         {
             int index = limiter.DeferredWorkItems.Count - 1;
             ImportStructWorkItem item = limiter.DeferredWorkItems[index];
             if (this.InitializeStructMembers(item.Mapping, item.Model, openModel, name, limiter))
             {
                 limiter.DeferredWorkItems.RemoveAt(index);
             }
         }
         limiter.Depth--;
     }
     return mapping;
 }
Beispiel #27
0
        private StructMapping ImportStructLikeMapping(StructModel model, RecursionLimiter limiter)
        {
            if (model.TypeDesc.Kind == TypeKind.Root)
            {
                return(GetRootMapping());
            }

            SoapAttributes a = GetAttributes(model.Type);

            string typeNs = _defaultNs;

            if (a.SoapType != null && a.SoapType.Namespace != null)
            {
                typeNs = a.SoapType.Namespace;
            }
            string typeName = XsdTypeName(model.Type, a, model.TypeDesc.Name);

            typeName = XmlConvert.EncodeLocalName(typeName);

            StructMapping mapping = (StructMapping)GetTypeMapping(typeName, typeNs, model.TypeDesc);

            if (mapping == null)
            {
                mapping           = new StructMapping();
                mapping.IsSoap    = true;
                mapping.TypeDesc  = model.TypeDesc;
                mapping.Namespace = typeNs;
                mapping.TypeName  = typeName;
                if (a.SoapType != null)
                {
                    mapping.IncludeInSchema = a.SoapType.IncludeInSchema;
                }
                _typeScope.AddTypeMapping(mapping);
                _types.Add(typeName, typeNs, mapping);
                if (limiter.IsExceededLimit)
                {
                    limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping));
                    return(mapping);
                }

                limiter.Depth++;

                InitializeStructMembers(mapping, model, limiter);
                while (limiter.DeferredWorkItems.Count > 0)
                {
                    int index = limiter.DeferredWorkItems.Count - 1;
                    ImportStructWorkItem item = limiter.DeferredWorkItems[index];
                    if (InitializeStructMembers(item.Mapping, item.Model, limiter))
                    {
                        //
                        // if InitializeStructMembers returns true, then there were *no* changes to the DeferredWorkItems
                        //
#if DEBUG
                        // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
                        if (index != limiter.DeferredWorkItems.Count - 1)
                        {
                            throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorDetails, "DeferredWorkItems.Count have changed"));
                        }
                        if (item != limiter.DeferredWorkItems[index])
                        {
                            throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorDetails, "DeferredWorkItems.Top have changed"));
                        }
#endif
                        // Remove the last work item
                        limiter.DeferredWorkItems.RemoveAt(index);
                    }
                }
                limiter.Depth--;
            }
            return(mapping);
        }
        bool InitializeStructMembers(StructMapping mapping, StructModel model, bool openModel, string typeName, RecursionLimiter limiter) {
            if (mapping.IsFullyInitialized)
                return true;

                if (model.TypeDesc.BaseTypeDesc != null) {
                    TypeModel baseModel = modelScope.GetTypeModel(model.Type.BaseType, false);
                    if (!(baseModel is StructModel)) {
                        //XmlUnsupportedInheritance=Using '{0}' as a base type for a class is not supported by XmlSerializer.
                         throw new NotSupportedException(Res.GetString(Res.XmlUnsupportedInheritance, model.Type.BaseType.FullName));
                    }
                StructMapping baseMapping = ImportStructLikeMapping((StructModel)baseModel, mapping.Namespace, openModel, null, limiter);
                // check to see if the import of the baseMapping was deffered
                int baseIndex = limiter.DeferredWorkItems.IndexOf(baseMapping);
                if (baseIndex < 0) {
                    mapping.BaseMapping = baseMapping;

                    ICollection values = mapping.BaseMapping.LocalAttributes.Values;
                    foreach (AttributeAccessor attribute in values) {
                        AddUniqueAccessor(mapping.LocalAttributes, attribute);
                    }
                    if (!mapping.BaseMapping.HasExplicitSequence()) {
                        values = mapping.BaseMapping.LocalElements.Values;
                        foreach (ElementAccessor e in values) {
                            AddUniqueAccessor(mapping.LocalElements, e);
                        }
                    }
                }
                else {
                    // the import of the baseMapping was deffered, make sure that the derived mappings is deffered as well
                    if (!limiter.DeferredWorkItems.Contains(mapping)) {
                        limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping));
                    }
                    // make sure that baseMapping get processed before the derived
                    int top = limiter.DeferredWorkItems.Count - 1;
                    if (baseIndex < top) {
                        ImportStructWorkItem baseMappingWorkItem = limiter.DeferredWorkItems[baseIndex];
                        limiter.DeferredWorkItems[baseIndex] = limiter.DeferredWorkItems[top];
                        limiter.DeferredWorkItems[top] = baseMappingWorkItem;
                    }
                    return false;
                }
            }
                ArrayList members = new ArrayList();
                TextAccessor textAccesor = null;
                bool hasElements = false;
                bool isSequence = false;
                
                foreach (MemberInfo memberInfo in model.GetMemberInfos()) {
                    if ((memberInfo.MemberType & (MemberTypes.Field | MemberTypes.Property)) == 0)
                        continue;
                    XmlAttributes memberAttrs = GetAttributes(memberInfo);
                    if (memberAttrs.XmlIgnore) continue;
                    FieldModel fieldModel = model.GetFieldModel(memberInfo);
                    if (fieldModel == null) continue;
                    try {
                    MemberMapping member = ImportFieldMapping(model, fieldModel, memberAttrs, mapping.Namespace, limiter);
                        if (member == null) continue;
                        if (mapping.BaseMapping != null) {
                            if (mapping.BaseMapping.Declares(member, mapping.TypeName)) continue;
                        }
                        isSequence |= member.IsSequence;
                        // add All memeber accessors to the scope accessors
                        AddUniqueAccessor(member, mapping.LocalElements, mapping.LocalAttributes, isSequence);

                        if (member.Text != null) {
                            if (!member.Text.Mapping.TypeDesc.CanBeTextValue && member.Text.Mapping.IsList)
                                throw new InvalidOperationException(Res.GetString(Res.XmlIllegalTypedTextAttribute, typeName, member.Text.Name, member.Text.Mapping.TypeDesc.FullName));
                            if (textAccesor != null) {
                                throw new InvalidOperationException(Res.GetString(Res.XmlIllegalMultipleText, model.Type.FullName));
                            }
                            textAccesor = member.Text;
                        }
                        if (member.Xmlns != null) {
                            if (mapping.XmlnsMember != null)
                                throw new InvalidOperationException(Res.GetString(Res.XmlMultipleXmlns, model.Type.FullName));
                            mapping.XmlnsMember = member;
                        }
                        if (member.Elements != null && member.Elements.Length != 0) {
                            hasElements = true;
                        }
                        members.Add(member);
                    }
                    catch (Exception e) {
                        if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
                            throw;
                        }
                        throw CreateMemberReflectionException(fieldModel, e);
                    }
                }
                mapping.SetContentModel(textAccesor, hasElements);
                if (isSequence) {
                    Hashtable ids = new Hashtable();
                    for (int i = 0; i < members.Count; i++) {
                        MemberMapping member = (MemberMapping)members[i];
                        if (!member.IsParticle)
                            continue;
                        if (member.IsSequence) {
                            if (ids[member.SequenceId] != null) {
                                throw new InvalidOperationException(Res.GetString(Res.XmlSequenceUnique, member.SequenceId.ToString(CultureInfo.InvariantCulture), "Order", member.Name));
                            }
                            ids[member.SequenceId] = member;
                        }
                        else {
                            throw new InvalidOperationException(Res.GetString(Res.XmlSequenceInconsistent, "Order", member.Name));
                        }
                    }
                    members.Sort(new MemberMappingComparer());
                }
                mapping.Members = (MemberMapping[])members.ToArray(typeof(MemberMapping));

                if (mapping.BaseMapping == null) mapping.BaseMapping = GetRootMapping();

                if (mapping.XmlnsMember != null && mapping.BaseMapping.HasXmlnsMember)
                    throw new InvalidOperationException(Res.GetString(Res.XmlMultipleXmlns, model.Type.FullName));

            IncludeTypes(model.Type, limiter);
                typeScope.AddTypeMapping(mapping);
            if (openModel)
                mapping.IsOpenModel = true;
            return true;
        }
        StructMapping ImportStructLikeMapping(StructModel model) {
            if (model.TypeDesc.Kind == TypeKind.Root) return GetRootMapping();

            SoapAttributes a = GetAttributes(model.Type);

            string typeNs = defaultNs;
            if (a.SoapType != null && a.SoapType.Namespace != null)
                typeNs = a.SoapType.Namespace;
            string typeName = XsdTypeName(model.Type, a, model.TypeDesc.Name);
            typeName = XmlConvert.EncodeLocalName(typeName);

            StructMapping mapping = (StructMapping)GetTypeMapping(typeName, typeNs, model.TypeDesc);
            if (mapping == null) {
                mapping = new StructMapping();
                mapping.IsSoap = true;
                mapping.TypeDesc = model.TypeDesc;
                mapping.Namespace = typeNs;
                mapping.TypeName = typeName;
                if (a.SoapType != null) mapping.IncludeInSchema = a.SoapType.IncludeInSchema;
                typeScope.AddTypeMapping(mapping);
                types.Add(typeName, typeNs, mapping);
                if (model.TypeDesc.BaseTypeDesc != null) {
                    mapping.BaseMapping = ImportStructLikeMapping((StructModel)modelScope.GetTypeModel(model.Type.BaseType, false));
                }
                ArrayList members = new ArrayList();
                foreach (MemberInfo memberInfo in model.GetMemberInfos()) {
                    if ((memberInfo.MemberType & (MemberTypes.Field | MemberTypes.Property)) == 0)
                        continue;
                    SoapAttributes memberAttrs = GetAttributes(memberInfo);
                    if (memberAttrs.SoapIgnore) continue;
                    FieldModel fieldModel = model.GetFieldModel(memberInfo);
                    if (fieldModel == null) continue;
                    MemberMapping member = ImportFieldMapping(fieldModel, memberAttrs, mapping.Namespace);
                    if (member == null) continue;

                    if (!member.TypeDesc.IsPrimitive && !member.TypeDesc.IsEnum && !member.TypeDesc.IsOptionalValue) {
                        if (model.TypeDesc.IsValueType)
                            throw new NotSupportedException(Res.GetString(Res.XmlRpcRefsInValueType, model.TypeDesc.FullName));
                        if (member.TypeDesc.IsValueType)
                            throw new NotSupportedException(Res.GetString(Res.XmlRpcNestedValueType, member.TypeDesc.FullName));
                    }
                    if (mapping.BaseMapping != null) {
                        if (mapping.BaseMapping.Declares(member, mapping.TypeName)) continue;
                    }
                    members.Add(member);
                }
                mapping.Members = (MemberMapping[])members.ToArray(typeof(MemberMapping));
                if (mapping.BaseMapping == null) mapping.BaseMapping = GetRootMapping();
                IncludeTypes(model.Type);
            }
            return mapping;
        }
Beispiel #30
0
        StructMapping ImportStructLikeMapping(StructModel model, string ns, XmlSchemaForm form) {
            if (model.TypeDesc.Kind == TypeKind.Root) return GetRootMapping();
            XmlAttributes a = GetAttributes(model.Type);

            string typeNs = ns;
            if (a.XmlType != null && a.XmlType.Namespace != null)
                typeNs = a.XmlType.Namespace;
            else if (a.XmlRoot != null && a.XmlRoot.Namespace != null)
                typeNs = a.XmlRoot.Namespace;

            string typeName = string.Empty;
            if (a.XmlType != null)
                typeName = a.XmlType.TypeName;
            if (typeName.Length == 0) 
                typeName = model.TypeDesc.Name;

            StructMapping mapping = (StructMapping)GetTypeMapping(typeName, typeNs, model.TypeDesc);
            if (mapping == null) {
                mapping = new StructMapping();
                mapping.TypeDesc = model.TypeDesc;
                mapping.Namespace = typeNs;
                mapping.TypeName = typeName;
                typeScope.AddTypeMapping(mapping);
                types.Add(typeName, typeNs, mapping);
                if (a.XmlType != null) {
                    mapping.IncludeInSchema = a.XmlType.IncludeInSchema;
                }
                if (model.TypeDesc.BaseTypeDesc != null) {
                    mapping.BaseMapping = ImportStructLikeMapping((StructModel)modelScope.GetTypeModel(model.Type.BaseType), mapping.Namespace, form);
                    ICollection values = mapping.BaseMapping.LocalElements.Values;
                    foreach (ElementAccessor e in values) {
                        AddUniqueAccessor(mapping.LocalElements, e);
                    }
                    values = mapping.BaseMapping.LocalAttributes.Values;
                    foreach (AttributeAccessor attribute in values) {
                        AddUniqueAccessor(mapping.LocalAttributes, attribute);
                    }
                }
                ArrayList members = new ArrayList();
                TextAccessor textAccesor = null;
                bool hasElements = false;

                foreach (MemberInfo memberInfo in model.GetMemberInfos()) {
                    XmlAttributes memberAttrs = GetAttributes(memberInfo);
                    if (memberAttrs.XmlIgnore) continue;
                    FieldModel fieldModel = model.GetFieldModel(memberInfo);
                    if (fieldModel == null) continue;
                    MemberMapping member = ImportFieldMapping(model, fieldModel, memberAttrs, mapping.Namespace, form);
                    if (member == null) continue;
                    if (mapping.BaseMapping != null) {
                        if (mapping.BaseMapping.Declares(member, mapping.TypeName)) continue;
                    }
                    // add All memeber accessors to the scope accessors
                    AddUniqueAccessor(member, mapping.LocalElements, mapping.LocalAttributes);

                    if (member.Text != null) {
                        if (!member.Text.Mapping.TypeDesc.CanBeTextValue && member.Text.Mapping.IsList)
                            throw new InvalidOperationException(Res.GetString(Res.XmlIllegalTypedTextAttribute, typeName, member.Text.Name, member.Text.Mapping.TypeDesc.FullName));
                        if (textAccesor != null) {
                            throw new InvalidOperationException(Res.GetString(Res.XmlIllegalMultipleText, model.Type.FullName));
                        }
                        textAccesor = member.Text;
                    }
                    if (member.Xmlns != null) {
                        if (mapping.XmlnsMember != null)
                            throw new InvalidOperationException(Res.GetString(Res.XmlMultipleXmlns, model.Type.FullName));
                        mapping.XmlnsMember = member;
                    }
                    if (member.Elements != null && member.Elements.Length != 0) {
                        hasElements = true;
                    }
                    members.Add(member);
                }
                mapping.SetContentModel(textAccesor, hasElements);
                mapping.Members = (MemberMapping[])members.ToArray(typeof(MemberMapping));

                if (mapping.BaseMapping == null) mapping.BaseMapping = GetRootMapping();

                if (mapping.XmlnsMember != null && mapping.BaseMapping.HasXmlnsMember)
                    throw new InvalidOperationException(Res.GetString(Res.XmlMultipleXmlns, model.Type.FullName));

                IncludeTypes(model.Type);
            }
            return mapping;
        }