source: branches/New Persistence Exploration/Persistence/Persistence/XmlFormatter.cs @ 1339

Last change on this file since 1339 was 1339, checked in by epitzer, 12 years ago

support composite value types (#506)

File size: 3.7 KB
Line 
1using System.Collections.Generic;
2using System;
3using System.Text;
4namespace Persistence {
5  public class XmlFormatter {
6
7    delegate string Formatter(ISerializationToken token);
8
9    private readonly Dictionary<Type, Formatter> formatters;
10    private int depth;
11
12    public XmlFormatter() {
13      formatters = new Dictionary<Type, Formatter>{
14                       {typeof (BeginToken), FormatBegin},
15                       {typeof (EndToken), FormatEnd},
16                       {typeof (PrimitiveToken), FormatPrimitive},
17                       {typeof (ReferenceToken), FormatReference},
18                       {typeof (NullReferenceToken), FormatNullReference}
19                     };
20      depth = 0;
21    }
22
23    private enum NodeType { Start, End, Inline } ;
24
25    private static string FormatNode(string name, Dictionary<string, string> attributes, NodeType type) {
26      StringBuilder sb = new StringBuilder();
27      sb.Append('<');
28      if (type == NodeType.End)
29        sb.Append('/');
30      sb.Append(name);     
31      foreach (var attribute in attributes) {
32        sb.Append(' ');
33        sb.Append(attribute.Key);
34        sb.Append("=\"");
35        sb.Append(attribute.Value);
36        sb.Append('"');
37      }
38      if (type == NodeType.Inline)
39        sb.Append('/');
40      sb.Append(">");
41      return sb.ToString();     
42    }
43
44    public string Format(ISerializationToken token) {
45      return formatters[token.GetType()](token);
46    }
47
48    private string Prefix {
49      get { return new string(' ', depth * 2); }
50    }
51
52    private string FormatBegin(ISerializationToken token) {     
53      BeginToken beginToken = (BeginToken)token;
54      var attributes = new Dictionary<string, string> {
55        {"name", beginToken.Accessor.Name},
56        {"type", beginToken.Accessor.Get().GetType().AssemblyQualifiedName } };
57      if ( beginToken.Id != null )
58        attributes.Add("id", beginToken.Id.ToString());                                           
59      string result = Prefix +
60                      FormatNode("COMPOSITE", attributes, NodeType.Start) + "\n";
61      depth += 1;
62      return result;
63    }
64
65    private string FormatEnd(ISerializationToken token) {     
66      depth -= 1;
67      return Prefix + "</COMPOSITE>\n";
68    }
69
70    private string FormatPrimitive(ISerializationToken token) {
71      PrimitiveToken dataToken = (PrimitiveToken)token;
72      Dictionary<string, string> attributes =
73        new Dictionary<string, string> {
74            {"type", dataToken.Accessor.Get().GetType().AssemblyQualifiedName}};
75      if ( !string.IsNullOrEmpty(dataToken.Accessor.Name) )
76        attributes.Add("name", dataToken.Accessor.Name);
77      if ( dataToken.Id != null )
78        attributes.Add("id", dataToken.Id.ToString());
79      return Prefix +
80        FormatNode("PRIMITIVE", attributes, NodeType.Start) +
81        dataToken.Data + "</PRIMITIVE>\n";     
82    }
83
84    private string FormatReference(ISerializationToken token) {
85      ReferenceToken refToken = (ReferenceToken) token;
86      Dictionary<string, string> attributes =
87        new Dictionary<string, string> {{"ref", refToken.Id.ToString()}};
88      if ( refToken.Name != null )
89        attributes.Add("name", refToken.Name);
90      return Prefix + FormatNode("REFERENCE", attributes, NodeType.Inline) + "\n"; 
91    }
92
93    private string FormatNullReference(ISerializationToken token) {
94      NullReferenceToken nullRefToken = (NullReferenceToken)token;
95      Dictionary<string, string> attributes = new Dictionary<string, string>();
96      if (nullRefToken.Name != null)
97        attributes.Add("name", nullRefToken.Name);
98      return Prefix + FormatNode("NULL", attributes, NodeType.Inline) + "\n";
99    }
100  }
101}
Note: See TracBrowser for help on using the repository browser.