/branches/0.8.x/src/Html.Downloader/Modules/RssMonitor/Engine/RssDataSerializer.cs
C# | 274 lines | 223 code | 51 blank | 0 comment | 8 complexity | 2055b8d488f3c2d6e9f275cb7d6959f8 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, CC-BY-SA-3.0
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.CompilerServices;
- using System.Text;
- using System.Xml;
- using System.Xml.Linq;
- using Html.Downloader.Engine.Common;
- using Melon.Commons.Configuration.Updates;
- using Melon.Commons.Repository;
-
- namespace Html.Downloader.Modules.RssMonitor.Engine
- {
- internal sealed class RssDataSerializer : IUpdateable
- {
- #region Private Fields
- private readonly VersionGraph graph;
- private readonly IRepositoryService repository;
- private readonly RepositoryPointcut pointcut;
- #endregion
- #region Constructors
- public RssDataSerializer(IRepositoryService repository, RepositoryPointcut pointcut)
- {
- this.graph = new VersionGraph();
- this.repository = repository;
- this.pointcut = pointcut;
- }
- #endregion
-
- #region IUpdateable Members
- public void SetCurrentVersion(int version)
- {
- this.graph.SetCurrentVersion(version);
- }
-
- public void SetDefaultVersion(int version)
- {
- this.graph.SetDefaultVersion(version);
- }
-
- public void AddUpdater(int from, int to, IUpdater updater)
- {
- this.graph.AddUpdater(from, to, updater);
- }
- #endregion
- #region ISerializer Members
- public void Serialize(RssData[] items)
- {
- var document = new XDocument(new XElement("Data", new XAttribute("version", 1)));
-
- foreach (var item in items)
- this.Serialize(document.Root, item);
-
- this.Save(document);
- }
-
- public RssData[] Deserialize()
- {
- var document = this.Load();
- var query = from element in document.Root.Elements()
- select this.Deserialize(element);
-
- return query.Where(x => x != null).ToArray();
- }
- #endregion
-
- #region Private Members
- [MethodImpl(MethodImplOptions.Synchronized)]
- private XDocument Load()
- {
- try
- {
- if (!this.repository.Exists(this.pointcut))
- return new XDocument(new XElement("Data", new XAttribute("version", 1)));
-
- var updater = new VersionUpdater(this.graph, new XmlVersionReader());
-
- using (var stream = updater.Update(this.repository.GetReadStream(this.pointcut)))
- using (var reader = XmlReader.Create(stream, new XmlReaderSettings { CloseInput = true }))
- return XDocument.Load(reader, LoadOptions.None);
- }
- catch (XmlException)
- {
- if (this.repository.HasCopy(this.pointcut))
- {
- this.repository.Revert(this.pointcut);
- return this.Load();
- }
-
- throw;
- }
- }
-
- [MethodImpl(MethodImplOptions.Synchronized)]
- private void Save(XDocument document)
- {
- using (var stream = this.repository.GetWriteStream(this.pointcut))
- using (var writer = new XmlTextWriter(stream, Encoding.UTF8) { Formatting = Formatting.Indented })
- document.Save(writer);
- }
-
- private void Serialize(XContainer container, RssData data)
- {
- var result = new XElement("Channel",
- new XAttribute("id", data.Channel.ToString()),
- new XAttribute("updated", data.Updated.ToString()),
- new XElement("Entries"));
-
- foreach (var entry in data.GetEntries())
- this.Serialize(result.Element("Entries"), entry);
-
- container.Add(result);
- }
-
- private void Serialize(XContainer container, RssEntry entry)
- {
- var result = new XElement("Entry",
- new XAttribute("id", entry.Id.ToString()),
- new XAttribute("updated", entry.Updated.ToString()),
- new XElement("Location", entry.Location.ToString()),
- new XElement("Title", entry.Title),
- new XElement("Published", entry.Published),
- new XElement("Content", new XCData(entry.Content)),
- new XElement("State", Enum.GetName(typeof(RssEntryState), entry.State)),
- new XElement("Links"),
- new XElement("Files"));
-
- foreach (var link in entry.GetLinks())
- this.Serialize(result.Element("Links"), link);
-
- foreach (var file in entry.GetFiles())
- this.Serialize(result.Element("Files"), file);
-
- container.Add(result);
- }
-
- private void Serialize(XContainer container, RssLink link)
- {
- var result = new XElement("Link",
- new XElement("Location", link.Location.ToString()),
- new XElement("State", Enum.GetName(typeof(RssLinkState), link.State == RssLinkState.Analyzing ? RssLinkState.Found : link.State)));
-
- container.Add(result);
- }
-
- private void Serialize(XContainer container, RssFile file)
- {
- var result = new XElement("File",
- new XAttribute("id", file.Id.ToString()),
- new XElement("Name", file.Name),
- new XElement("State", Enum.GetName(typeof(RssFileState), file.State)),
- new XElement("Verified", file.Verified == DateTime.MaxValue ? DateTime.MinValue : file.Verified),
- new XElement("Resources"));
-
- foreach (var resource in file.GetResources())
- this.Serialize(result.Element("Resources"), resource);
-
- container.Add(result);
- }
-
- private void Serialize(XContainer container, Resource resource)
- {
- var result = new XElement("Resource",
- new XAttribute("id", resource.Id),
- new XElement("Provider", resource.Provider.ToString()),
- new XElement("Name", resource.Name),
- new XElement("Location", resource.Location.ToString()),
- this.SerializeSize(resource.Size));
-
- container.Add(result);
- }
-
- private RssData Deserialize(XElement node)
- {
- var id = new Guid(node.Attribute("id").Value);
- var updated = DateTime.Parse(node.Attribute("updated").Value);
- var result = new RssData(id) { Updated = updated };
-
- var entries = from entry in node.Element("Entries").Elements("Entry")
- select this.Deserialize(entry, result);
-
- foreach (var entry in entries)
- result.AddEntry(entry);
-
- return result;
- }
-
- private RssEntry Deserialize(XElement node, RssData owner)
- {
- var id = new Guid(node.Attribute("id").Value);
- var updated = DateTime.Parse(node.Attribute("updated").Value);
- var location = new Uri(node.Element("Location").Value);
- var title = node.Element("Title").Value;
- var published = DateTime.Parse(node.Element("Published").Value);
- var content = node.Element("Content").Value;
- var state = (RssEntryState)Enum.Parse(typeof(RssEntryState), node.Element("State").Value);
- var result = new RssEntry(id, owner, location, title, published, content) { State = state, Updated = updated };
-
- var links = from link in node.Element("Links").Elements("Link")
- select this.DeserializeLink(link, result);
-
- foreach (var link in links)
- result.AddLink(link);
-
- var files = from file in node.Element("Files").Elements("File")
- select this.DeserializeFile(file, result);
-
- foreach (var file in files)
- result.AddFile(file);
-
- return result;
- }
-
- private RssLink DeserializeLink(XElement node, RssEntry owner)
- {
- var location = new Uri(node.Element("Location").Value);
- var state = (RssLinkState)Enum.Parse(typeof(RssLinkState), node.Element("State").Value);
-
- return new RssLink(owner, location) { State = state };
- }
-
- private RssFile DeserializeFile(XElement node, RssEntry owner)
- {
- var id = new Guid(node.Attribute("id").Value);
- var name = node.Element("Name").Value;
- var state = (RssFileState)Enum.Parse(typeof(RssFileState), node.Element("State").Value);
- var verified = DateTime.Parse(node.Element("Verified").Value);
- var result = new RssFile(id, owner, name) { State = state, Verified = verified };
-
- var resources = from resource in node.Element("Resources").Elements("Resource")
- select this.Deserialize(resource, result);
-
- foreach (var resource in resources)
- result.AddResource(resource);
-
- return result;
- }
-
- private Resource Deserialize(XElement node, RssFile owner)
- {
- var id = new Guid(node.Attribute("id").Value);
- var provider = new Guid(node.Element("Provider").Value);
- var name = node.Element("Name").Value;
- var size = this.DeserializeSize(node.Element("Size"));
- var location = new Uri(node.Element("Location").Value);
-
- return new Resource(id, provider, name, size, location);
- }
-
- private XElement SerializeSize(DataSize size)
- {
- var result = new XElement("Size",
- new XAttribute("mode", Enum.GetName(typeof(DataSizeMode), size.Mode)));
-
- if (size != DataSize.Unknown)
- result.Add(size.GetBytes());
-
- return result;
- }
-
- private DataSize DeserializeSize(XElement node)
- {
- var mode = (DataSizeMode)Enum.Parse(typeof(DataSizeMode), node.Attribute("mode").Value);
- var value = node.Value;
- var result = DataSize.Unknown;
-
- if (!String.IsNullOrEmpty(value))
- result = new DataSize(mode, Int64.Parse(value));
-
- return result;
- }
- #endregion
- }
- }