Free cookie consent management tool by TermsFeed Policy Generator

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

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

Decomposers for all primitive types except string. (#563)

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