Ejemplo n.º 1
0
 private void IncludeTypes(Type provider, RecursionLimiter limiter)
 {
     foreach (var attrib in provider.GetTypeInfo().GetCustomAttributes <SoapIncludeAttribute>(false))
     {
         IncludeType(attrib.Type, limiter);
     }
 }
Ejemplo n.º 2
0
 private void IncludeTypes(ICustomAttributeProvider provider, RecursionLimiter limiter)
 {
     object[] attrs = provider.GetCustomAttributes(typeof(SoapIncludeAttribute), false);
     for (int i = 0; i < attrs.Length; i++)
     {
         IncludeType(((SoapIncludeAttribute)attrs[i]).Type, limiter);
     }
 }
Ejemplo n.º 3
0
        private ArrayMapping ImportArrayLikeMapping(ArrayModel model, RecursionLimiter limiter)
        {
            ArrayMapping mapping = new ArrayMapping();

            mapping.IsSoap = true;
            TypeMapping itemTypeMapping = ImportTypeMapping(model.Element, limiter);

            if (itemTypeMapping.TypeDesc.IsValueType && !itemTypeMapping.TypeDesc.IsPrimitive && !itemTypeMapping.TypeDesc.IsEnum)
            {
                throw new NotSupportedException(SR.Format(SR.XmlRpcArrayOfValueTypes, model.TypeDesc.FullName));
            }

            mapping.TypeDesc = model.TypeDesc;
            mapping.Elements = new ElementAccessor[] {
                CreateElementAccessor(itemTypeMapping, mapping.Namespace)
            };
            SetArrayMappingType(mapping);

            // in the case of an ArrayMapping we can have more that one mapping correspond to a type
            // examples of that are ArrayList and object[] both will map tp ArrayOfur-type
            // so we create a link list for all mappings of the same XSD type
            ArrayMapping existingMapping = (ArrayMapping)_types[mapping.TypeName, mapping.Namespace];

            if (existingMapping != null)
            {
                ArrayMapping first = existingMapping;
                while (existingMapping != null)
                {
                    if (existingMapping.TypeDesc == model.TypeDesc)
                    {
                        return(existingMapping);
                    }
                    existingMapping = existingMapping.Next;
                }
                mapping.Next = first;
                _types[mapping.TypeName, mapping.Namespace] = mapping;
                return(mapping);
            }
            _typeScope.AddTypeMapping(mapping);
            _types.Add(mapping.TypeName, mapping.Namespace, mapping);
            IncludeTypes(model.Type);
            return(mapping);
        }
Ejemplo n.º 4
0
        private void ImportAccessorMapping(MemberMapping accessor, FieldModel model, SoapAttributes a, string ns, XmlSchemaForm form, RecursionLimiter limiter)
        {
            Type   accessorType = model.FieldType;
            string accessorName = model.Name;

            accessor.TypeDesc = _typeScope.GetTypeDesc(accessorType);
            if (accessor.TypeDesc.IsVoid)
            {
                throw new InvalidOperationException(SR.XmlInvalidVoid);
            }

            SoapAttributeFlags flags = a.GetSoapFlags();

            if ((flags & SoapAttributeFlags.Attribute) == SoapAttributeFlags.Attribute)
            {
                if (!accessor.TypeDesc.IsPrimitive && !accessor.TypeDesc.IsEnum)
                {
                    throw new InvalidOperationException(SR.Format(SR.XmlIllegalSoapAttribute, accessorName, accessor.TypeDesc.FullName));
                }

                if ((flags & SoapAttributeFlags.Attribute) != flags)
                {
                    throw new InvalidOperationException(SR.XmlInvalidElementAttribute);
                }

                AttributeAccessor attribute = new AttributeAccessor();
                attribute.Name      = Accessor.EscapeQName(a.SoapAttribute == null || a.SoapAttribute.AttributeName.Length == 0 ? accessorName : a.SoapAttribute.AttributeName);
                attribute.Namespace = a.SoapAttribute == null || a.SoapAttribute.Namespace == null ? ns : a.SoapAttribute.Namespace;
                attribute.Form      = XmlSchemaForm.Qualified; // attributes are always qualified since they're only used for encoded soap headers
                attribute.Mapping   = ImportTypeMapping(_modelScope.GetTypeModel(accessorType), (a.SoapAttribute == null ? String.Empty : a.SoapAttribute.DataType), limiter);
                attribute.Default   = GetDefaultValue(model.FieldTypeDesc, a);
                accessor.Attribute  = attribute;
                accessor.Elements   = new ElementAccessor[0];
            }
            else
            {
                if ((flags & SoapAttributeFlags.Element) != flags)
                {
                    throw new InvalidOperationException(SR.XmlInvalidElementAttribute);
                }

                ElementAccessor element = new ElementAccessor();
                element.IsSoap    = true;
                element.Name      = XmlConvert.EncodeLocalName(a.SoapElement == null || a.SoapElement.ElementName.Length == 0 ? accessorName : a.SoapElement.ElementName);
                element.Namespace = ns;
                element.Form      = form;
                element.Mapping   = ImportTypeMapping(_modelScope.GetTypeModel(accessorType), (a.SoapElement == null ? String.Empty : a.SoapElement.DataType), limiter);
                if (a.SoapElement != null)
                {
                    element.IsNullable = a.SoapElement.IsNullable;
                }
                accessor.Elements = new ElementAccessor[] { element };
            }
        }
Ejemplo n.º 5
0
        private MemberMapping ImportFieldMapping(FieldModel model, SoapAttributes a, string ns, RecursionLimiter limiter)
        {
            if (a.SoapIgnore)
            {
                return(null);
            }
            MemberMapping member = new MemberMapping();

            member.IsSoap                       = true;
            member.Name                         = model.Name;
            member.CheckShouldPersist           = model.CheckShouldPersist;
            member.CheckSpecified               = model.CheckSpecified;
            member.MemberInfo                   = model.MemberInfo;
            member.CheckSpecifiedMemberInfo     = model.CheckSpecifiedMemberInfo;
            member.CheckShouldPersistMethodInfo = model.CheckShouldPersistMethodInfo;
            member.ReadOnly                     = model.ReadOnly; // || !model.FieldTypeDesc.HasDefaultConstructor;
            ImportAccessorMapping(member, model, a, ns, XmlSchemaForm.Unqualified, limiter);
            return(member);
        }
Ejemplo n.º 6
0
        private MemberMapping ImportMemberMapping(XmlReflectionMember xmlReflectionMember, string ns, XmlReflectionMember[] xmlReflectionMembers, XmlSchemaForm form, RecursionLimiter limiter)
        {
            SoapAttributes a = xmlReflectionMember.SoapAttributes;

            if (a.SoapIgnore)
            {
                return(null);
            }
            MemberMapping member = new MemberMapping();

            member.IsSoap = true;
            member.Name   = xmlReflectionMember.MemberName;
            bool       checkSpecified = XmlReflectionImporter.FindSpecifiedMember(xmlReflectionMember.MemberName, xmlReflectionMembers) != null;
            FieldModel model          = new FieldModel(xmlReflectionMember.MemberName, xmlReflectionMember.MemberType, _typeScope.GetTypeDesc(xmlReflectionMember.MemberType), checkSpecified, false);

            member.CheckShouldPersist = model.CheckShouldPersist;
            member.CheckSpecified     = model.CheckSpecified;
            member.ReadOnly           = model.ReadOnly; // || !model.FieldTypeDesc.HasDefaultConstructor;
            ImportAccessorMapping(member, model, a, ns, form, limiter);
            if (xmlReflectionMember.OverrideIsNullable)
            {
                member.Elements[0].IsNullable = false;
            }
            return(member);
        }
Ejemplo n.º 7
0
        private MembersMapping ImportMembersMapping(XmlReflectionMember[] xmlReflectionMembers, string ns, bool hasWrapperElement, bool writeAccessors, bool validateWrapperElement, RecursionLimiter limiter)
        {
            MembersMapping members = new MembersMapping();

            members.TypeDesc = _typeScope.GetTypeDesc(typeof(object[]));
            MemberMapping[] mappings = new MemberMapping[xmlReflectionMembers.Length];
            for (int i = 0; i < mappings.Length; i++)
            {
                try
                {
                    XmlReflectionMember member  = xmlReflectionMembers[i];
                    MemberMapping       mapping = ImportMemberMapping(member, ns, xmlReflectionMembers, hasWrapperElement ? XmlSchemaForm.Unqualified : XmlSchemaForm.Qualified, limiter);
                    if (member.IsReturnValue && writeAccessors)
                    { // no special treatment for return values with doc/enc
                        if (i > 0)
                        {
                            throw new InvalidOperationException(SR.XmlInvalidReturnPosition);
                        }
                        mapping.IsReturnValue = true;
                    }
                    mappings[i] = mapping;
                }
                catch (Exception e)
                {
                    if (e is OutOfMemoryException)
                    {
                        throw;
                    }
                    throw ReflectionException(xmlReflectionMembers[i].MemberName, e);
                }
            }
            members.Members           = mappings;
            members.HasWrapperElement = hasWrapperElement;
            if (hasWrapperElement)
            {
                members.ValidateRpcWrapperElement = validateWrapperElement;
            }
            members.WriteAccessors = writeAccessors;
            members.IsSoap         = true;
            if (hasWrapperElement && !writeAccessors)
            {
                members.Namespace = ns;
            }
            return(members);
        }
Ejemplo n.º 8
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);
        }
Ejemplo n.º 9
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);
        }
Ejemplo n.º 10
0
        private TypeMapping ImportTypeMapping(TypeModel model, string dataType, RecursionLimiter limiter)
        {
            if (dataType.Length > 0)
            {
                if (!model.TypeDesc.IsPrimitive)
                {
                    throw new InvalidOperationException(SR.Format(SR.XmlInvalidDataTypeUsage, dataType, "SoapElementAttribute.DataType"));
                }
                TypeDesc td = _typeScope.GetTypeDesc(dataType, XmlSchema.Namespace);
                if (td == null)
                {
                    throw new InvalidOperationException(SR.Format(SR.XmlInvalidXsdDataType, dataType, "SoapElementAttribute.DataType", new XmlQualifiedName(dataType, XmlSchema.Namespace).ToString()));
                }
                if (model.TypeDesc.FullName != td.FullName)
                {
                    throw new InvalidOperationException(SR.Format(SR.XmlDataTypeMismatch, dataType, "SoapElementAttribute.DataType", model.TypeDesc.FullName));
                }
            }

            SoapAttributes a = GetAttributes(model.Type);

            if ((a.GetSoapFlags() & ~SoapAttributeFlags.Type) != 0)
            {
                throw new InvalidOperationException(SR.Format(SR.XmlInvalidTypeAttributes, model.Type.FullName));
            }

            switch (model.TypeDesc.Kind)
            {
            case TypeKind.Enum:
                return(ImportEnumMapping((EnumModel)model));

            case TypeKind.Primitive:
                return(ImportPrimitiveMapping((PrimitiveModel)model, dataType));

            case TypeKind.Array:
            case TypeKind.Collection:
            case TypeKind.Enumerable:
                return(ImportArrayLikeMapping((ArrayModel)model, limiter));

            case TypeKind.Root:
            case TypeKind.Class:
            case TypeKind.Struct:
                if (model.TypeDesc.IsOptionalValue)
                {
                    TypeDesc       baseTypeDesc   = model.TypeDesc.BaseTypeDesc;
                    SoapAttributes baseAttributes = GetAttributes(baseTypeDesc.Type);
                    string         typeNs         = _defaultNs;
                    if (baseAttributes.SoapType != null && baseAttributes.SoapType.Namespace != null)
                    {
                        typeNs = baseAttributes.SoapType.Namespace;
                    }
                    TypeDesc    valueTypeDesc = string.IsNullOrEmpty(dataType) ? model.TypeDesc.BaseTypeDesc : _typeScope.GetTypeDesc(dataType, XmlSchema.Namespace);
                    string      xsdTypeName   = string.IsNullOrEmpty(dataType) ? model.TypeDesc.BaseTypeDesc.Name : dataType;
                    TypeMapping baseMapping   = GetTypeMapping(xsdTypeName, typeNs, valueTypeDesc);
                    if (baseMapping == null)
                    {
                        baseMapping = ImportTypeMapping(_modelScope.GetTypeModel(baseTypeDesc.Type), dataType, limiter);
                    }
                    return(CreateNullableMapping(baseMapping, model.TypeDesc.Type));
                }
                else
                {
                    return(ImportStructLikeMapping((StructModel)model, limiter));
                }

            default:
                throw new NotSupportedException(SR.Format(SR.XmlUnsupportedSoapTypeKind, model.TypeDesc.FullName));
            }
        }
Ejemplo n.º 11
0
 private TypeMapping ImportTypeMapping(TypeModel model, RecursionLimiter limiter)
 {
     return(ImportTypeMapping(model, String.Empty, limiter));
 }
Ejemplo n.º 12
0
 private void IncludeType(Type type, RecursionLimiter limiter)
 {
     ImportTypeMapping(_modelScope.GetTypeModel(type), limiter);
 }