Added hammock project to debug streaming issues
[pithos-ms-client] / trunk / hammock / src / net35 / Hammock.Extras / Serialization / SerializerBase.cs
1 using System;
2 #if NET40
3 using System.Dynamic;
4 #endif
5 using System.IO;
6 using System.Xml;
7 using Hammock.Serialization;
8 using Newtonsoft.Json;
9 using Newtonsoft.Json.Linq;
10 using Formatting = Newtonsoft.Json.Formatting;
11
12 namespace Hammock.Extras.Serialization
13 {
14     public abstract class SerializerBase : Utf8Serializer, ISerializer, IDeserializer
15     {
16         private readonly Newtonsoft.Json.JsonSerializer _serializer;
17
18         protected SerializerBase()
19             : this(new JsonSerializerSettings
20                        {
21                            MissingMemberHandling = MissingMemberHandling.Ignore,
22                            NullValueHandling = NullValueHandling.Ignore,
23                            DefaultValueHandling = DefaultValueHandling.Include,
24                            ContractResolver = new JsonConventionResolver()
25                        })
26         {
27
28         }
29
30         protected SerializerBase(JsonSerializerSettings settings)
31         {
32             _serializer = new Newtonsoft.Json.JsonSerializer
33                               {
34                                   ConstructorHandling = settings.ConstructorHandling,
35                                   ContractResolver = settings.ContractResolver,
36                                   ObjectCreationHandling = settings.ObjectCreationHandling,
37                                   MissingMemberHandling = settings.MissingMemberHandling,
38                                   DefaultValueHandling = settings.DefaultValueHandling,
39                                   NullValueHandling = settings.NullValueHandling
40                               };
41
42             foreach (var converter in settings.Converters)
43             {
44                 _serializer.Converters.Add(converter);
45             }
46         }
47
48         public abstract T Deserialize<T>(RestResponse<T> response);
49
50         public abstract object Deserialize(RestResponse response, Type type);
51
52 #if NET40
53         public abstract dynamic DeserializeDynamic<T>(RestResponse<T> response) where T : DynamicObject;
54 #endif
55         
56         public virtual object DeserializeJson(string content, Type type)
57         {
58             using (var stringReader = new StringReader(content))
59             {
60                 using (var jsonTextReader = new JsonTextReader(stringReader))
61                 {
62                     return _serializer.Deserialize(jsonTextReader, type);
63                 }
64             }
65         }
66
67         public virtual T DeserializeJson<T>(string content)
68         {
69             using (var stringReader = new StringReader(content))
70             {
71                 using (var jsonTextReader = new JsonTextReader(stringReader))
72                 {
73                     return _serializer.Deserialize<T>(jsonTextReader);
74                 }
75             }
76         }
77
78         public virtual T DeserializeXml<T>(RestResponse response)
79         {
80             return (T)DeserializeXml(response, typeof(T));
81         }
82
83         public virtual object DeserializeXml(RestResponse response, Type type)
84         {
85             var element = LoadXmlElement(response.Content);
86
87             return DeserializeXmlImpl(element, type);
88         }
89
90         private object DeserializeXmlImpl(XmlNode node, Type type)
91         {
92             var json = JsonConvert.SerializeXmlNode(node);
93             var instance = DeserializeJson(json, type);
94             return instance;
95         }
96
97         private static XmlElement LoadXmlElement(string content)
98         {
99             var document = new XmlDocument();
100             document.Load(new StringReader(content));
101             return document.DocumentElement;
102         }
103
104         public virtual object DeserializeXmlWithRoot(string content, Type type, string root)
105         {
106             var source = LoadXmlElement(content);
107             var inner = source.FirstChild;
108
109             var document = new XmlDocument();
110             var outer = document.CreateNode(XmlNodeType.Element, root, source.NamespaceURI);
111             inner = document.ImportNode(inner, true);
112
113             foreach(XmlAttribute attribute in source.Attributes)
114             {
115                 var attributeCopy = document.CreateAttribute(attribute.Name, attribute.LocalName, attribute.NamespaceURI);
116                 attributeCopy.Value = attribute.Value;
117                 if (outer.Attributes != null)
118                 {
119                     outer.Attributes.Append(attributeCopy);
120                 }
121             }
122
123             outer.AppendChild(inner);
124             document.AppendChild(outer);
125
126             var json = JsonConvert.SerializeXmlNode(document);
127             var relevant = JObject.Parse(json)[root].ToString();
128             var instance = DeserializeJson(relevant, type);
129             
130             return instance;
131         }
132
133         public virtual string SerializeJson(object instance, Type type)
134         {
135             using (var stringWriter = new StringWriter())
136             {
137                 using (var jsonTextWriter = new JsonTextWriter(stringWriter))
138                 {
139                     jsonTextWriter.Formatting = Formatting.Indented;
140                     jsonTextWriter.QuoteChar = '"';
141
142                     _serializer.Serialize(jsonTextWriter, instance);
143
144                     var result = stringWriter.ToString();
145                     return result;
146                 }
147             }
148         }
149
150         public virtual string SerializeXml(object instance, Type type)
151         {
152             var json = SerializeJson(instance, type);
153
154             var root = type.Name.ToLowerInvariant();
155
156             return SerializeXmlImpl(instance, type, json, root);
157         }
158
159         public virtual string SerializeXmlWithRoot(object instance, Type type, string root)
160         {
161             var json = SerializeJson(instance, type);
162
163             return SerializeXmlImpl(instance, type, json, root);
164         }
165
166         public virtual string SerializeXmlImpl(object instance, Type type, string json, string root)
167         {
168             // {"root":json }
169             json = string.Format("{{\"{0}\":{1} }}", root, json);
170
171             var document = JsonConvert.DeserializeXmlNode(json);
172
173             using (var stringWriter = new StringWriter())
174             {
175                 using (var xmlTextWriter = new XmlTextWriter(stringWriter))
176                 {
177                     document.WriteTo(xmlTextWriter);
178
179                     return stringWriter.ToString();
180                 }
181             }
182         }
183
184         public abstract string Serialize(object instance, Type type);
185
186         public abstract string ContentType { get; }
187     }
188 }