Added hammock project to debug streaming issues
[pithos-ms-client] / trunk / hammock / src / net35 / Hammock.Extras / Serialization / JsonConventionResolver.cs
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Text;
5 using Newtonsoft.Json.Serialization;
6
7 namespace Hammock.Extras.Serialization
8 {
9     /// <summary>
10     /// Resolves all property names to JSON conventional standard,
11     /// i.e. JSON name "this_is_a_property" will map to the class property ThisIsAProperty.
12     /// Also finds any property names suffixed with "Attribute" and converts them
13     /// into @properties for XML serialization.
14     /// </summary>
15     public class JsonConventionResolver : DefaultContractResolver
16     {
17         public class ToStringComparer : IComparer
18         {
19             public int Compare(object x, object y)
20             {
21                 return x.ToString().CompareTo(y.ToString());
22             }
23         }
24
25         protected override IList<JsonProperty> CreateProperties(Type type, Newtonsoft.Json.MemberSerialization memberSerialization)
26         {
27             var properties = base.CreateProperties(type, memberSerialization);
28
29             return CreatePropertiesImpl(properties);
30         }
31
32         private static IList<JsonProperty> CreatePropertiesImpl(IList<JsonProperty> properties)
33         {
34             foreach (var property in properties)
35             {
36                 property.PropertyName = PascalCaseToElement(property.PropertyName);
37             }
38
39             // @'s must come first
40             var result = properties;
41
42             ArrayList.Adapter((IList)result).Sort(new ToStringComparer());
43
44             return result;
45         }
46
47         private static string PascalCaseToElement(string input)
48         {
49             if (string.IsNullOrEmpty(input))
50             {
51                 return null;
52             }
53
54             var attributeForSerialization = input.EndsWith("Attribute");
55             if(attributeForSerialization)
56             {
57                 input = input.Substring(0, input.LastIndexOf("Attribute"));
58             }
59             
60             var result = new StringBuilder();
61             result.Append(char.ToLowerInvariant(input[0]));
62             
63             for (var i = 1; i < input.Length; i++)
64             {
65                 if (char.IsLower(input[i]))
66                 {
67                     result.Append(input[i]);
68                 }
69                 else
70                 {
71                     result.Append("_");
72                     result.Append(char.ToLowerInvariant(input[i]));
73                 }
74             }
75
76             return attributeForSerialization? string.Concat("@", result) : result.ToString();
77         }
78     }
79 }