Moved ProviderCollectionTest.cs from System assembly to System.Configuration.
[mono.git] / mcs / class / System.ServiceModel.Web / System.Runtime.Serialization.Json / DataContractJsonSerializer.cs
1 //
2 // DataContractJsonSerializer.cs
3 //
4 // Author:
5 //      Atsushi Enomoto  <atsushi@ximian.com>
6 //
7 // Copyright (C) 2007-2008 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 using System;
29 using System.Collections;
30 using System.Collections.Generic;
31 using System.Collections.ObjectModel;
32 using System.Globalization;
33 using System.IO;
34 using System.Reflection;
35 using System.Text;
36 using System.Xml;
37
38 namespace System.Runtime.Serialization.Json
39 {
40         public sealed class DataContractJsonSerializer : XmlObjectSerializer
41         {
42                 const string default_root_name = "root";
43
44                 #region lengthy constructor list
45
46                 public DataContractJsonSerializer (Type type)
47                         : this (type, Type.EmptyTypes)
48                 {
49                 }
50
51                 public DataContractJsonSerializer (Type type, IEnumerable<Type> knownTypes)
52                         : this (type, default_root_name, knownTypes)
53                 {
54                 }
55
56                 public DataContractJsonSerializer (Type type, string rootName)
57                         : this (type, rootName, Type.EmptyTypes)
58                 {
59                 }
60
61                 public DataContractJsonSerializer (Type type, XmlDictionaryString rootName)
62                         : this (type, rootName != null ? rootName.Value : default_root_name, Type.EmptyTypes)
63                 {
64                 }
65
66                 public DataContractJsonSerializer (Type type, string rootName, IEnumerable<Type> knownTypes)
67                         : this (type, rootName, knownTypes, int.MaxValue, false, null, true)
68                 {
69                 }
70
71                 public DataContractJsonSerializer (Type type, XmlDictionaryString rootName, IEnumerable<Type> knownTypes)
72                         : this (type, rootName != null ? rootName.Value : default_root_name, knownTypes)
73                 {
74                 }
75
76                 public DataContractJsonSerializer (Type type, IEnumerable<Type> knownTypes, int maxItemsInObjectGraph, bool ignoreExtensionDataObject, IDataContractSurrogate dataContractSurrogate, bool alwaysEmitTypeInformation)
77                         : this (type, default_root_name, knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, dataContractSurrogate, alwaysEmitTypeInformation)
78                 {
79                 }
80
81                 public DataContractJsonSerializer (Type type, string rootName, IEnumerable<Type> knownTypes, int maxItemsInObjectGraph, bool ignoreExtensionDataObject, IDataContractSurrogate dataContractSurrogate, bool alwaysEmitTypeInformation)
82                 {
83                         if (type == null)
84                                 throw new ArgumentNullException ("type");
85                         if (rootName == null)
86                                 throw new ArgumentNullException ("rootName");
87                         if (maxItemsInObjectGraph < 0)
88                                 throw new ArgumentOutOfRangeException ("maxItemsInObjectGraph");
89
90                         List<Type> types = new List<Type> ();
91                         types.Add (type);
92                         if (knownTypes != null)
93                                 types.AddRange (knownTypes);
94
95                         this.type = type;
96                         known_types = new ReadOnlyCollection<Type> (types);
97                         root = rootName;
98                         max_items = maxItemsInObjectGraph;
99                         ignore_extension = ignoreExtensionDataObject;
100                         surrogate = dataContractSurrogate;
101                         always_emit_type = alwaysEmitTypeInformation;
102                 }
103
104                 public DataContractJsonSerializer (Type type, XmlDictionaryString rootName, IEnumerable<Type> knownTypes, int maxItemsInObjectGraph, bool ignoreExtensionDataObject, IDataContractSurrogate dataContractSurrogate, bool alwaysEmitTypeInformation)
105                         : this (type, rootName != null ? rootName.Value : null, knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, dataContractSurrogate, alwaysEmitTypeInformation)
106                 {
107                 }
108
109                 #endregion
110
111                 Type type;
112                 string root;
113                 ReadOnlyCollection<Type> known_types;
114                 int max_items;
115                 bool ignore_extension;
116                 IDataContractSurrogate surrogate;
117                 bool always_emit_type;
118
119                 [MonoTODO]
120                 public IDataContractSurrogate DataContractSurrogate {
121                         get { return surrogate; }
122                 }
123
124                 [MonoTODO]
125                 public bool IgnoreExtensionDataObject {
126                         get { return ignore_extension; }
127                 }
128
129                 [MonoTODO]
130                 public ReadOnlyCollection<Type> KnownTypes {
131                         get { return known_types; }
132                 }
133
134                 public int MaxItemsInObjectGraph {
135                         get { return max_items; }
136                 }
137
138                 public override bool IsStartObject (XmlReader reader)
139                 {
140                         if (reader == null)
141                                 throw new ArgumentNullException ("reader");
142                         reader.MoveToContent ();
143                         return reader.IsStartElement (root, String.Empty);
144                 }
145
146                 public override bool IsStartObject (XmlDictionaryReader reader)
147                 {
148                         return IsStartObject ((XmlReader) reader);
149                 }
150
151                 public override object ReadObject (Stream stream)
152                 {
153                         return ReadObject (JsonReaderWriterFactory.CreateJsonReader (stream, new XmlDictionaryReaderQuotas ()));
154                 }
155
156                 public override object ReadObject (XmlDictionaryReader reader)
157                 {
158                         return ReadObject (reader, true);
159                 }
160
161                 public override object ReadObject (XmlReader reader)
162                 {
163                         return ReadObject (reader, true);
164                 }
165
166                 public override object ReadObject (XmlDictionaryReader reader, bool verifyObjectName)
167                 {
168                         return ReadObject ((XmlReader) reader, verifyObjectName);
169                 }
170
171                 public override object ReadObject (XmlReader reader, bool verifyObjectName)
172                 {
173                         if (reader == null)
174                                 throw new ArgumentNullException ("reader");
175                         try {
176                                 if (verifyObjectName && !IsStartObject (reader))
177                                         throw new SerializationException (String.Format ("Expected element was '{0}', but the actual input element was '{1}' in namespace '{2}'", root, reader.LocalName, reader.NamespaceURI));
178
179                                 return new JsonSerializationReader (this, reader, type, verifyObjectName).ReadRoot ();
180                         } catch (SerializationException) {
181                                 throw;
182                         } catch (Exception ex) {
183                                 throw new SerializationException ("Deserialization has failed", ex);
184                         }
185                 }
186
187                 public override void WriteObject (Stream stream, object graph)
188                 {
189                         WriteObject (JsonReaderWriterFactory.CreateJsonWriter (stream), graph);
190                 }
191
192                 public override void WriteObject (XmlWriter writer, object graph)
193                 {
194                         try {
195                                 WriteStartObject (writer, graph);
196                                 WriteObjectContent (writer, graph);
197                                 WriteEndObject (writer);
198                         } catch (NotImplementedException) {
199                                 throw;
200                         } catch (InvalidDataContractException) {
201                                 throw;
202                         } catch (Exception ex) {
203                                 throw new SerializationException (String.Format ("There was an error during serialization for object of type {0}", graph != null ? graph.GetType () : null), ex);
204                         }
205                 }
206
207                 public override void WriteObject (XmlDictionaryWriter writer, object graph)
208                 {
209                         WriteObject ((XmlWriter) writer, graph);
210                 }
211
212                 public override void WriteStartObject (XmlDictionaryWriter writer, object graph)
213                 {
214                         WriteStartObject ((XmlWriter) writer, graph);
215                 }
216
217                 public override void WriteStartObject (XmlWriter writer, object graph)
218                 {
219                         if (writer == null)
220                                 throw new ArgumentNullException ("writer");
221                         writer.WriteStartElement (root);
222                 }
223
224                 public override void WriteObjectContent (XmlDictionaryWriter writer, object graph)
225                 {
226                         WriteObjectContent ((XmlWriter) writer, graph);
227                 }
228
229                 public override void WriteObjectContent (XmlWriter writer, object graph)
230                 {
231                         new JsonSerializationWriter (this, writer, type, always_emit_type).WriteObjectContent (graph, true, false);
232                 }
233
234                 public override void WriteEndObject (XmlDictionaryWriter writer)
235                 {
236                         WriteEndObject ((XmlWriter) writer);
237                 }
238
239                 public override void WriteEndObject (XmlWriter writer)
240                 {
241                         if (writer == null)
242                                 throw new ArgumentNullException ("writer");
243                         writer.WriteEndElement ();
244                 }
245         }
246 }