New test.
[mono.git] / mcs / class / System.XML / System.Xml.Serialization / XmlReflectionImporter.cs
index dadcf8711af2d04d3e0c74e0f5c8886b8563668e..3dce3f49832a278a63c753f34630ee9ac5f3105d 100644 (file)
@@ -106,46 +106,65 @@ namespace System.Xml.Serialization {
                        XmlReflectionMember [] members,
                        bool hasWrapperElement)
                {
-//                     Reset ();       Disabled. See ChangeLog
-
-                       XmlMemberMapping[] mapping = new XmlMemberMapping[members.Length];
-                       for (int n=0; n<members.Length; n++)
-                       {
-                               XmlTypeMapMember mapMem = CreateMapMember (null, members[n], ns);
-                               mapping[n] = new XmlMemberMapping (members[n].MemberName, ns, mapMem, false);
-                       }
-                       elementName = XmlConvert.EncodeLocalName (elementName);
-                       XmlMembersMapping mps = new XmlMembersMapping (elementName, ns, hasWrapperElement, false, mapping);
-                       mps.RelatedMaps = relatedMaps;
-                       mps.Format = SerializationFormat.Literal;
-                       Type[] extraTypes = includedTypes != null ? (Type[])includedTypes.ToArray(typeof(Type)) : null;
-                       mps.Source = new MembersSerializationSource (elementName, hasWrapperElement, members, false, true, ns, extraTypes);
-                       if (allowPrivateTypes) mps.Source.CanBeGenerated = false;
-                       return mps;
+                       return ImportMembersMapping (elementName, ns, members, hasWrapperElement, true);
                }
 
 #if NET_2_0
                [MonoTODO]
-               public XmlMembersMapping ImportMembersMapping (string elementName, 
+               public
+#endif
+               XmlMembersMapping ImportMembersMapping (string elementName, 
                        string ns, 
                        XmlReflectionMember[] members, 
                        bool hasWrapperElement, 
-                       bool rpc)
+                       bool writeAccessors)
                {
-                       throw new NotImplementedException ();
+                       return ImportMembersMapping (elementName, ns, members, hasWrapperElement, writeAccessors, true);
                }
 
+#if NET_2_0
                [MonoTODO]
-               public XmlMembersMapping ImportMembersMapping (string elementName, 
+               public
+#endif
+               XmlMembersMapping ImportMembersMapping (string elementName, 
                        string ns, 
                        XmlReflectionMember[] members, 
                        bool hasWrapperElement, 
-                       bool rpc
-                       bool openModel)
+                       bool writeAccessors
+                       bool validate)
                {
-                       throw new NotImplementedException ();
+                       return ImportMembersMapping (elementName, ns, members, hasWrapperElement, writeAccessors, validate, XmlMappingAccess.Read | XmlMappingAccess.Write);
                }
+
+#if NET_2_0
+               [MonoTODO] // FIXME: handle writeAccessors, validate, and mapping access
+               public
 #endif
+               XmlMembersMapping ImportMembersMapping (string elementName, 
+                       string ns, 
+                       XmlReflectionMember[] members, 
+                       bool hasWrapperElement, 
+                       bool writeAccessors, 
+                       bool validate,
+                       XmlMappingAccess access)
+               {
+//                     Reset ();       Disabled. See ChangeLog
+
+                       XmlMemberMapping[] mapping = new XmlMemberMapping[members.Length];
+                       for (int n=0; n<members.Length; n++)
+                       {
+                               XmlTypeMapMember mapMem = CreateMapMember (null, members[n], ns);
+                               mapping[n] = new XmlMemberMapping (members[n].MemberName, ns, mapMem, false);
+                       }
+                       elementName = XmlConvert.EncodeLocalName (elementName);
+                       XmlMembersMapping mps = new XmlMembersMapping (elementName, ns, hasWrapperElement, false, mapping);
+                       mps.RelatedMaps = relatedMaps;
+                       mps.Format = SerializationFormat.Literal;
+                       Type[] extraTypes = includedTypes != null ? (Type[])includedTypes.ToArray(typeof(Type)) : null;
+                       mps.Source = new MembersSerializationSource (elementName, hasWrapperElement, members, false, true, ns, extraTypes);
+                       if (allowPrivateTypes) mps.Source.CanBeGenerated = false;
+                       return mps;
+               }
 
                public XmlTypeMapping ImportTypeMapping (Type type)
                {
@@ -223,7 +242,7 @@ namespace System.Xml.Serialization {
                        string elementName;
                        bool includeInSchema = true;
                        XmlAttributes atts = null;
-                       bool nullable = true;
+                       bool nullable = CanBeNull (typeData);
 
                        if (defaultXmlType == null) defaultXmlType = typeData.XmlType;
 
@@ -331,7 +350,7 @@ namespace System.Xml.Serialization {
                                        XmlTypeMapMember mem = CreateMapMember (type, rmember, ns);
                                        mem.CheckOptionalValueType (type);
                                        classMap.AddMember (mem);
-                               } catch (InvalidOperationException ex) {
+                               } catch (Exception ex) {
                                        throw new InvalidOperationException (string.Format (
                                                CultureInfo.InvariantCulture, "There was an error" +
                                                " reflecting field '{0}'.", rmember.MemberName), ex);
@@ -873,7 +892,7 @@ namespace System.Xml.Serialization {
                                mapMember = member;
                        }
 
-                       mapMember.DefaultValue = atts.XmlDefaultValue;
+                       mapMember.DefaultValue = GetDefaultValue (typeData, atts.XmlDefaultValue);
                        mapMember.TypeData = typeData;
                        mapMember.Name = rmember.MemberName;
                        mapMember.IsReturnValue = rmember.IsReturnValue;
@@ -935,8 +954,8 @@ namespace System.Xml.Serialization {
                                if (elem.Form != XmlSchemaForm.Unqualified)
                                        elem.Namespace = (att.Namespace != null) ? att.Namespace : defaultNamespace;
                                elem.IsNullable = att.IsNullable;
-                               
-                               if (elem.IsNullable && elem.TypeData.IsValueType)
+
+                               if (elem.IsNullable && !elem.TypeData.IsNullable)
                                        throw new InvalidOperationException ("IsNullable may not be 'true' for value type " + elem.TypeData.FullTypeName + " in member '" + defaultName + "'");
                                        
                                if (elem.TypeData.IsComplexType)
@@ -1035,7 +1054,11 @@ namespace System.Xml.Serialization {
                
                bool CanBeNull (TypeData type)
                {
-                       return (type.SchemaType != SchemaTypes.Primitive || type.Type == typeof (string));
+#if !NET_2_0   // idiotic compatibility
+                       if (type.Type == typeof (XmlQualifiedName))
+                               return false;
+#endif
+                       return !type.Type.IsValueType;
                }
                
                public void IncludeType (Type type)
@@ -1063,6 +1086,32 @@ namespace System.Xml.Serialization {
                                IncludeType (at.Type);
                }
 
+               private object GetDefaultValue (TypeData typeData, object defaultValue)
+               {
+                       if (defaultValue == DBNull.Value || typeData.SchemaType != SchemaTypes.Enum)
+                               return defaultValue;
+
+                       // get string representation of enum value
+                       string namedValue = Enum.Format (typeData.Type, defaultValue, "g");
+                       // get decimal representation of enum value
+                       string decimalValue = Enum.Format (typeData.Type, defaultValue, "d");
+
+                       // if decimal representation matches string representation, then
+                       // the value is not defined in the enum type (as the "g" format
+                       // will return the decimal equivalent of the value if the value
+                       // is not equal to a combination of named enumerated constants
+                       if (namedValue == decimalValue) {
+                               string msg = string.Format (CultureInfo.InvariantCulture,
+                                       "Value '{0}' cannot be converted to {1}.", defaultValue,
+                                       defaultValue.GetType ().FullName);
+                               throw new InvalidOperationException (msg);
+                       }
+
+                       // XmlSerializer expects integral enum value
+                       //return namedValue.Replace (',', ' ');
+                       return defaultValue;
+               }
+
                #endregion // Methods
        }
 }