using System.Collections.Generic; using System; using System.Text; namespace Persistence { public class XmlFormatter { delegate string Formatter(ISerializationToken token); private readonly Dictionary formatters; private int depth; public XmlFormatter() { formatters = new Dictionary{ {typeof (BeginToken), FormatBegin}, {typeof (EndToken), FormatEnd}, {typeof (PrimitiveToken), FormatPrimitive}, {typeof (ReferenceToken), FormatReference}, {typeof (NullReferenceToken), FormatNullReference} }; depth = 0; } private enum NodeType { Start, End, Inline } ; private static string FormatNode(string name, Dictionary attributes, NodeType type) { StringBuilder sb = new StringBuilder(); sb.Append('<'); if (type == NodeType.End) sb.Append('/'); sb.Append(name); foreach (var attribute in attributes) { sb.Append(' '); sb.Append(attribute.Key); sb.Append("=\""); sb.Append(attribute.Value); sb.Append('"'); } if (type == NodeType.Inline) sb.Append('/'); sb.Append(">"); return sb.ToString(); } public string Format(ISerializationToken token) { return formatters[token.GetType()](token); } private string Prefix { get { return new string(' ', depth * 2); } } private string FormatBegin(ISerializationToken token) { BeginToken beginToken = (BeginToken)token; var attributes = new Dictionary { {"name", beginToken.Accessor.Name}, {"type", beginToken.Accessor.Get().GetType().AssemblyQualifiedName } }; if ( beginToken.Id != null ) attributes.Add("id", beginToken.Id.ToString()); string result = Prefix + FormatNode("COMPOSITE", attributes, NodeType.Start) + "\n"; depth += 1; return result; } private string FormatEnd(ISerializationToken token) { depth -= 1; return Prefix + "\n"; } private string FormatPrimitive(ISerializationToken token) { PrimitiveToken dataToken = (PrimitiveToken)token; Dictionary attributes = new Dictionary { {"type", dataToken.Accessor.Get().GetType().AssemblyQualifiedName}}; if ( !string.IsNullOrEmpty(dataToken.Accessor.Name) ) attributes.Add("name", dataToken.Accessor.Name); if ( dataToken.Id != null ) attributes.Add("id", dataToken.Id.ToString()); return Prefix + FormatNode("PRIMITIVE", attributes, NodeType.Start) + dataToken.Data + "\n"; } private string FormatReference(ISerializationToken token) { ReferenceToken refToken = (ReferenceToken) token; Dictionary attributes = new Dictionary {{"ref", refToken.Id.ToString()}}; if ( refToken.Name != null ) attributes.Add("name", refToken.Name); return Prefix + FormatNode("REFERENCE", attributes, NodeType.Inline) + "\n"; } private string FormatNullReference(ISerializationToken token) { NullReferenceToken nullRefToken = (NullReferenceToken)token; Dictionary attributes = new Dictionary(); if (nullRefToken.Name != null) attributes.Add("name", nullRefToken.Name); return Prefix + FormatNode("NULL", attributes, NodeType.Inline) + "\n"; } } }