Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HiveStatistics/sources/HeuristicLab.Persistence/3.3/Default/Xml/XmlParser.cs @ 12584

Last change on this file since 12584 was 12584, checked in by dglaser, 9 years ago

#2388: Changed all files to connect to localhost / sqlexpress

HeuristicLab.Services.Hive-3.3:

  • Added Converter.cs and NewHiveService.cs, both will be integrated into existing HiveService.cs and Convert.cs when all methods are successfully implemented

HeuristicLab.Services.Hive.Web.Hive-3.3:

  • Added publish profiles

HeuristicLab.Services.WebApp.Statistics-3.3:

  • Added functionality to download TaskData as .hl file
File size: 11.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections;
24using System.Collections.Generic;
25using System.IO;
26using System.IO.Compression;
27using System.Xml;
28using HeuristicLab.Persistence.Core;
29using HeuristicLab.Persistence.Core.Tokens;
30using HeuristicLab.Persistence.Interfaces;
31
32namespace HeuristicLab.Persistence.Default.Xml {
33
34  /// <summary>
35  /// Main entry point of persistence loading from XML. Use the static
36  /// methods to load from a file or stream.
37  /// </summary>
38  public class XmlParser : IEnumerable<ISerializationToken> {
39
40    private readonly XmlTextReader reader;
41    private delegate IEnumerator<ISerializationToken> Handler();
42    private readonly Dictionary<string, Handler> handlers;
43
44    /// <summary>
45    /// Initializes a new instance of the <see cref="XmlParser"/> class.
46    /// </summary>
47    /// <param name="input">The input.</param>
48    public XmlParser(TextReader input) {
49      reader = new XmlTextReader(input);
50      reader.WhitespaceHandling = WhitespaceHandling.All;
51      reader.Normalization = false;
52      handlers = new Dictionary<string, Handler> {
53                     {XmlStringConstants.PRIMITIVE, ParsePrimitive},
54                     {XmlStringConstants.COMPOSITE, ParseComposite},
55                     {XmlStringConstants.REFERENCE, ParseReference},
56                     {XmlStringConstants.NULL, ParseNull},
57                     {XmlStringConstants.METAINFO, ParseMetaInfo},
58                     {XmlStringConstants.TYPE, ParseTypeInfo},
59                   };
60    }
61
62    /// <summary>
63    /// Returns an enumerator that iterates through the serialization tokens.
64    /// </summary>
65    /// <returns>
66    /// An that can be used to iterate through the collection of serialization tokens.
67    /// </returns>
68    public IEnumerator<ISerializationToken> GetEnumerator() {
69      while (reader.Read()) {
70        if (!reader.IsStartElement()) {
71          break;
72        }
73        IEnumerator<ISerializationToken> iterator;
74        try {
75          iterator = handlers[reader.Name].Invoke();
76        }
77        catch (KeyNotFoundException) {
78          throw new PersistenceException(String.Format(
79            "Invalid XML tag \"{0}\" in persistence file.",
80            reader.Name));
81        }
82        while (iterator.MoveNext()) {
83          yield return iterator.Current;
84        }
85      }
86    }
87
88    /// <summary>
89    /// Returns an enumerator that iterates through the serialization tokens.
90    /// </summary>
91    /// <returns>
92    /// An that can be used to iterate through the collection of serialization tokens.
93    /// </returns>
94    IEnumerator IEnumerable.GetEnumerator() {
95      return GetEnumerator();
96    }
97
98    private IEnumerator<ISerializationToken> ParsePrimitive() {
99      int? id = null;
100      string idString = reader.GetAttribute("id");
101      if (idString != null)
102        id = int.Parse(idString);
103      string name = reader.GetAttribute("name");
104      int typeId = int.Parse(reader.GetAttribute("typeId"));
105      string typeName = reader.GetAttribute("typeName");
106      string serializer = reader.GetAttribute("serializer");
107      if (typeName != null)
108        yield return new TypeToken(typeId, typeName, serializer);
109      XmlReader inner = reader.ReadSubtree();
110      inner.Read();
111      string xml = inner.ReadInnerXml();
112      inner.Close();
113      yield return new PrimitiveToken(name, typeId, id, new XmlString(xml));
114    }
115
116    private IEnumerator<ISerializationToken> ParseComposite() {
117      string name = reader.GetAttribute("name");
118      string idString = reader.GetAttribute("id");
119      int? id = null;
120      if (idString != null)
121        id = int.Parse(idString);
122      int typeId = int.Parse(reader.GetAttribute("typeId"));
123      string typeName = reader.GetAttribute("typeName");
124      string serializer = reader.GetAttribute("serializer");
125      if (typeName != null)
126        yield return new TypeToken(typeId, typeName, serializer);
127      yield return new BeginToken(name, typeId, id);
128      IEnumerator<ISerializationToken> iterator = GetEnumerator();
129      while (iterator.MoveNext())
130        yield return iterator.Current;
131      yield return new EndToken(name, typeId, id);
132    }
133
134    private IEnumerator<ISerializationToken> ParseReference() {
135      yield return new ReferenceToken(
136        reader.GetAttribute("name"),
137        int.Parse(reader.GetAttribute("ref")));
138    }
139
140    private IEnumerator<ISerializationToken> ParseNull() {
141      yield return new NullReferenceToken(reader.GetAttribute("name"));
142    }
143
144    private IEnumerator<ISerializationToken> ParseMetaInfo() {
145      yield return new MetaInfoBeginToken();
146      IEnumerator<ISerializationToken> iterator = GetEnumerator();
147      while (iterator.MoveNext())
148        yield return iterator.Current;
149      yield return new MetaInfoEndToken();
150    }
151
152    private IEnumerator<ISerializationToken> ParseTypeInfo() {
153      yield return new TypeToken(
154        int.Parse(reader.GetAttribute("id")),
155        reader.GetAttribute("typeName"),
156        reader.GetAttribute("serializer"));
157    }
158
159    /// <summary>
160    /// Parses the type cache.
161    /// </summary>
162    /// <param name="reader">The reader.</param>
163    /// <returns>A list of type mapping entries.</returns>
164    public static List<TypeMapping> ParseTypeCache(TextReader reader) {
165      try {
166        var typeCache = new List<TypeMapping>();
167        XmlReader xmlReader = XmlReader.Create(reader);
168        while (xmlReader.Read()) {
169          if (xmlReader.Name == XmlStringConstants.TYPE) {
170            typeCache.Add(new TypeMapping(
171              int.Parse(xmlReader.GetAttribute("id")),
172              xmlReader.GetAttribute("typeName"),
173              xmlReader.GetAttribute("serializer")));
174          }
175        }
176        return typeCache;
177      }
178      catch (PersistenceException) {
179        throw;
180      }
181      catch (Exception e) {
182        throw new PersistenceException("Unexpected exception during type cache parsing.", e);
183      }
184    }
185
186    /// <summary>
187    /// Deserializes an object from the specified filename.
188    /// </summary>
189    /// <param name="filename">The filename.</param>
190    /// <returns>A fresh object instance</returns>
191    public static object Deserialize(string filename) {
192      TimeSpan start = System.Diagnostics.Process.GetCurrentProcess().TotalProcessorTime;
193      try {
194        using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) {
195          try {
196            using (ZipArchive zip = new ZipArchive(fs)) {
197              return Deserialize(zip);
198            }
199          }
200          catch (Exception) {
201            return DeserializeWithGZip(fs);
202          }
203        }
204      }
205      finally {
206        TimeSpan end = System.Diagnostics.Process.GetCurrentProcess().TotalProcessorTime;
207        Tracing.Logger.Info(string.Format(
208          "deserialization of {0} took {1} seconds",
209          filename, (end - start).TotalSeconds));
210      }
211    }
212
213    /// <summary>
214    /// Deserializes the specified filename.
215    /// </summary>
216    /// <typeparam name="T">object type expected from the serialized file</typeparam>
217    /// <param name="filename">The filename.</param>
218    /// <returns>A fresh object of type T</returns>
219    public static T Deserialize<T>(string filename) {
220      return (T)Deserialize(filename);
221    }
222
223
224    /// <summary>
225    /// Deserializes an object from the specified stream using GZip compression.
226    /// </summary>
227    /// <param name="stream">The stream.</param>
228    /// <returns>A fresh object instance.</returns>
229    private static object DeserializeWithGZip(Stream stream) {
230      try {
231        using (StreamReader reader = new StreamReader(new GZipStream(stream, CompressionMode.Decompress))) {
232          XmlParser parser = new XmlParser(reader);
233          Deserializer deserializer = new Deserializer(new TypeMapping[] { });
234          return deserializer.Deserialize(parser);
235        }
236      }
237      catch (PersistenceException) {
238        throw;
239      }
240      catch (Exception x) {
241        throw new PersistenceException("Unexpected exception during deserialization", x);
242      }
243    }
244
245    /// <summary>
246    /// Deserializes an object from the specified stream using Zip compression.
247    /// </summary>
248    /// <param name="stream">The stream.</param>
249    /// <returns>A fresh object instance.</returns>
250    private static object DeserializeWithZip(Stream stream) {
251      ZipArchive zipFile = new ZipArchive(stream);
252      return Deserialize(zipFile);
253    }
254
255    /// <summary>
256    /// Deserializes an object from the specified stream.
257    /// </summary>
258    /// <typeparam name="T">object type expected from the serialized stream</typeparam>
259    /// <param name="stream">The stream.</param>
260    /// <param name="useZip">If true, uses zip for decompression, otherwise gzip.</param>
261    /// <returns>A fresh object instance.</returns>
262    public static T Deserialize<T>(Stream stream, bool useZip = false) {
263      return (T)Deserialize(stream, useZip);
264    }
265
266    /// <summary>
267    /// Deserializes an object from the specified stream.
268    /// </summary>
269    /// <param name="stream">The stream.</param>
270    /// <param name="useZip">If true, uses zip for decompression, otherwise gzip.</param>
271    /// <returns>A fresh object instance.</returns>
272    public static object Deserialize(Stream stream, bool useZip = false) {
273      if (useZip) {
274        return DeserializeWithZip(stream);
275      } else {
276        return DeserializeWithGZip(stream);
277      }
278    }
279
280    private static object Deserialize(ZipArchive zipFile) {
281      try {
282        ZipArchiveEntry typecache = zipFile.GetEntry("typecache.xml");
283        if (typecache == null) throw new PersistenceException("file does not contain typecache.xml");
284        Deserializer deSerializer;
285        using (StreamReader sr = new StreamReader(typecache.Open())) {
286          deSerializer = new Deserializer(ParseTypeCache(sr));
287        }
288
289        ZipArchiveEntry data = zipFile.GetEntry("data.xml");
290        if (data == null) throw new PersistenceException("file does not contain data.xml");
291        object result;
292        using (StreamReader sr = new StreamReader(data.Open())) {
293          XmlParser parser = new XmlParser(sr);
294          result = deSerializer.Deserialize(parser);
295        }
296
297        return result;
298      }
299      catch (PersistenceException) {
300        throw;
301      }
302      catch (Exception e) {
303        throw new PersistenceException("Unexpected exception during deserialization", e);
304      }
305    }
306  }
307}
Note: See TracBrowser for help on using the repository browser.