Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/XmlGenerator.cs @ 1553

Last change on this file since 1553 was 1553, checked in by epitzer, 15 years ago

Replace final fixes for broken parent references with separation of instance creation with meta information. (#548)

File size: 6.6 KB
Line 
1using System.Collections.Generic;
2using System;
3using System.Text;
4using HeuristicLab.Persistence.Interfaces;
5using HeuristicLab.Persistence.Core;
6using System.IO;
7using ICSharpCode.SharpZipLib.Zip;
8using HeuristicLab.Tracing;
9using log4net;
10using HeuristicLab.Persistence.Interfaces.Tokens;
11
12namespace HeuristicLab.Persistence.Default.Xml {
13
14  struct XmlStrings {
15    public const string PRIMITIVE = "PRIMITVE";
16    public const string COMPOSITE = "COMPOSITE";
17    public const string REFERENCE = "REFERENCE";
18    public const string NULL = "NULL";
19    public const string TYPECACHE = "TYPECACHE";
20    public const string TYPE = "TYPE";
21    public const string METAINFO = "METAINFO";
22  }
23
24  public abstract class Generator<T> {
25    public T Format(ISerializationToken token) {
26      Type type = token.GetType();
27      if (type == typeof(BeginToken))
28        return Format((BeginToken)token);
29      if (type == typeof(EndToken))
30        return Format((EndToken)token);
31      if (type == typeof(PrimitiveToken))
32        return Format((PrimitiveToken)token);
33      if (type == typeof(ReferenceToken))
34        return Format((ReferenceToken)token);
35      if (type == typeof(NullReferenceToken))
36        return Format((NullReferenceToken)token);
37      if (type == typeof(MetaInfoBeginToken))
38        return Format((MetaInfoBeginToken)token);
39      if (type == typeof(MetaInfoEndToken))
40        return Format((MetaInfoEndToken)token);
41      throw new ApplicationException("Invalid token of type " + type.FullName);
42    }
43    protected abstract T Format(BeginToken beginToken);
44    protected abstract T Format(EndToken endToken);
45    protected abstract T Format(PrimitiveToken primitiveToken);
46    protected abstract T Format(ReferenceToken referenceToken);
47    protected abstract T Format(NullReferenceToken nullReferenceToken);
48    protected abstract T Format(MetaInfoBeginToken metaInfoBeginToken);
49    protected abstract T Format(MetaInfoEndToken metaInfoEndToken);
50  }
51
52  public class XmlGenerator : Generator<string> {
53   
54    private int depth;
55
56    public XmlGenerator() {
57      depth = 0;
58    }
59
60    private enum NodeType { Start, End, Inline } ;
61
62    private static string FormatNode(string name,
63        Dictionary<string, object> attributes,
64        NodeType type) {
65      return FormatNode(name, attributes, type, " ");
66    }
67
68    private static string FormatNode(string name,
69        Dictionary<string, object> attributes,
70        NodeType type, string space) {
71      StringBuilder sb = new StringBuilder();
72      sb.Append('<');
73      if (type == NodeType.End)
74        sb.Append('/');
75      sb.Append(name);     
76      foreach (var attribute in attributes) {
77        if (attribute.Value != null && !string.IsNullOrEmpty(attribute.Value.ToString())) {
78          sb.Append(space);
79          sb.Append(attribute.Key);
80          sb.Append("=\"");
81          sb.Append(attribute.Value);
82          sb.Append('"');
83        }
84      }
85      if (type == NodeType.Inline)
86        sb.Append('/');
87      sb.Append(">");
88      return sb.ToString();     
89    }
90
91    private string Prefix {
92      get { return new string(' ', depth * 2); }
93    }
94
95    protected override string Format(BeginToken beginToken) {           
96      var attributes = new Dictionary<string, object> {
97        {"name", beginToken.Name},
98        {"typeId", beginToken.TypeId},
99        {"id", beginToken.Id}};
100      string result = Prefix +
101                      FormatNode(XmlStrings.COMPOSITE, attributes, NodeType.Start) + "\r\n";
102      depth += 1;
103      return result;
104    }
105
106    protected override string Format(EndToken endToken) {     
107      depth -= 1;
108      return Prefix + "</" + XmlStrings.COMPOSITE + ">\r\n";
109    }
110
111    protected override string Format(PrimitiveToken dataToken) {     
112      var attributes =
113        new Dictionary<string, object> {
114            {"typeId", dataToken.TypeId},
115            {"name", dataToken.Name},
116            {"id", dataToken.Id}};
117      return Prefix +
118        FormatNode(XmlStrings.PRIMITIVE, attributes, NodeType.Start) +
119        dataToken.SerialData + "</" + XmlStrings.PRIMITIVE + ">\r\n";     
120    }
121
122    protected override string Format(ReferenceToken refToken) {     
123      var attributes = new Dictionary<string, object> {
124        {"ref", refToken.Id},
125        {"name", refToken.Name}};                                       
126      return Prefix + FormatNode(XmlStrings.REFERENCE, attributes, NodeType.Inline) + "\r\n"; 
127    }
128
129    protected override string Format(NullReferenceToken nullRefToken) {     
130      var attributes = new Dictionary<string, object>{
131        {"name", nullRefToken.Name}};     
132      return Prefix + FormatNode(XmlStrings.NULL, attributes, NodeType.Inline) + "\r\n";
133    }
134
135    protected override string Format(MetaInfoBeginToken metaInfoBeginToken) {
136      string result = Prefix + "<" + XmlStrings.METAINFO + ">";
137      depth += 1;
138      return result;
139    }
140
141    protected override string Format(MetaInfoEndToken metaInfoEndToken) {
142      depth -= 1;
143      return Prefix + "</" + XmlStrings.METAINFO + ">";
144    }
145
146    public IEnumerable<string> Format(List<TypeMapping> typeCache) {
147      yield return "<" + XmlStrings.TYPECACHE + ">";
148      foreach (var mapping in typeCache)
149        yield return "  " + FormatNode(
150          XmlStrings.TYPE,
151          mapping.GetDict(),
152          NodeType.Inline,
153          "\r\n    ");
154      yield return "</" + XmlStrings.TYPECACHE + ">";
155    }
156
157    public static void Serialize(object o, string filename) {     
158      Serialize(o, filename, ConfigurationService.Instance.GetDefaultConfig(XmlFormat.Instance));
159    }
160
161    public static void Serialize(object obj, string filename, Configuration config) {
162      Serializer serializer = new Serializer(obj, config);
163      XmlGenerator generator = new XmlGenerator();
164      ZipOutputStream zipStream = new ZipOutputStream(File.Create(filename));
165      zipStream.SetLevel(9);     
166      zipStream.PutNextEntry(new ZipEntry("data.xml"));     
167      StreamWriter writer = new StreamWriter(zipStream);
168      ILog logger = Logger.GetDefaultLogger();     
169      foreach (ISerializationToken token in serializer) {
170        string line = generator.Format(token);
171        writer.Write(line);
172        logger.Debug(line);
173      }
174      writer.Flush();
175      zipStream.PutNextEntry(new ZipEntry("typecache.xml"));
176      writer = new StreamWriter(zipStream);
177      foreach (string line in generator.Format(serializer.TypeCache)) {
178        writer.WriteLine(line);
179        logger.Debug(line);
180      }
181      writer.Flush();           
182      zipStream.Close();     
183    }
184
185  }
186}
Note: See TracBrowser for help on using the repository browser.