PageRenderTime 1ms CodeModel.GetById 20ms app.highlight 9ms RepoModel.GetById 2ms app.codeStats 0ms

/src/EventStore.Core/Services/Transport/Http/AutoEventConverter.cs

https://github.com/elainte/EventStore
C# | 178 lines | 146 code | 23 blank | 9 comment | 11 complexity | 3402011988747ccd6846b3dc375ad28b MD5 | raw file
  1using System;
  2using System.Text;
  3using System.Xml.Linq;
  4using EventStore.Common.Log;
  5using EventStore.Core.Data;
  6using EventStore.Core.Messages;
  7using EventStore.Core.TransactionLog.LogRecords;
  8using EventStore.Transport.Http;
  9using EventStore.Transport.Http.Codecs;
 10using Newtonsoft.Json;
 11using Newtonsoft.Json.Linq;
 12using Formatting = Newtonsoft.Json.Formatting;
 13using System.Linq;
 14using EventStore.Common.Utils;
 15
 16namespace EventStore.Core.Services.Transport.Http
 17{
 18    public static class AutoEventConverter
 19    {
 20        private static readonly ILogger Log = LogManager.GetLogger("AutoEventConverter");
 21
 22        public static string SmartFormat(ResolvedEvent evnt, ICodec targetCodec)
 23        {
 24            var dto = CreateDataDto(evnt);
 25
 26            switch (targetCodec.ContentType)
 27            {
 28                case ContentType.Xml:
 29                case ContentType.ApplicationXml:
 30                    {
 31                        var serializeObject = JsonConvert.SerializeObject(dto.data);
 32                        var deserializeXmlNode = JsonConvert.DeserializeXmlNode(serializeObject, "data");
 33                        return deserializeXmlNode.InnerXml;
 34                    }
 35                case ContentType.Json:
 36                    return targetCodec.To(dto.data);
 37
 38
 39                case ContentType.Atom:
 40                case ContentType.EventXml:
 41                {
 42                    var serializeObject = JsonConvert.SerializeObject(dto);
 43                    var deserializeXmlNode = JsonConvert.DeserializeXmlNode(serializeObject, "event");
 44                    return deserializeXmlNode.InnerXml;
 45                }
 46
 47                case ContentType.EventJson:
 48                    return targetCodec.To(dto);
 49
 50
 51                default:
 52                    throw new NotSupportedException();
 53            }
 54        }
 55
 56        public static HttpClientMessageDto.ReadEventCompletedText CreateDataDto(ResolvedEvent evnt)
 57        {
 58            var dto = new HttpClientMessageDto.ReadEventCompletedText(evnt);
 59            if (evnt.Event.Flags.HasFlag(PrepareFlags.IsJson))
 60            {
 61                var deserializedData = Codec.Json.From<object>((string) dto.data);
 62                var deserializedMetadata = Codec.Json.From<object>((string) dto.metadata);
 63
 64                if (deserializedData != null)
 65                    dto.data = deserializedData;
 66                if (deserializedMetadata != null)
 67                    dto.metadata = deserializedMetadata;
 68            }
 69            return dto;
 70        }
 71
 72        //TODO GFY THERE IS WAY TOO MUCH COPYING/SERIALIZING/DESERIALIZING HERE!
 73        public static Event[] SmartParse(string request, ICodec sourceCodec, Guid includedId, string includedType=null)
 74        {
 75            switch(sourceCodec.ContentType)
 76            {
 77                case ContentType.Json:
 78                    return LoadRaw(request, true, includedId, includedType);
 79                case ContentType.EventJson:
 80                case ContentType.EventsJson:
 81                case ContentType.AtomJson:
 82                    var writeEvents = LoadFromJson(request);
 83                    if (writeEvents.IsEmpty())
 84                        return null;
 85                    return Parse(writeEvents);
 86
 87                case ContentType.Xml:
 88                    return LoadRaw(request, false, includedId, includedType);
 89                case ContentType.EventXml:
 90                case ContentType.EventsXml:
 91                case ContentType.ApplicationXml:
 92                case ContentType.Atom:
 93                    var writeEvents2 = LoadFromXml(request);
 94                    if (writeEvents2.IsEmpty())
 95                        return null;
 96                    return Parse(writeEvents2);
 97                default:
 98                    return null;
 99            }
100        }
101
102        private static Event[] LoadRaw(string data, bool isJson, Guid includedId, string includedType) {
103            var ret = new Event[1];
104            ret[0] = new Event(includedId, includedType, isJson, data, null);
105            return ret;
106        }
107
108        private static HttpClientMessageDto.ClientEventDynamic[] LoadFromJson(string json)
109        {
110            return Codec.Json.From<HttpClientMessageDto.ClientEventDynamic[]>(json);
111        }
112
113        private static HttpClientMessageDto.ClientEventDynamic[] LoadFromXml(string xml)
114        {
115            try
116            {
117                XDocument doc = XDocument.Parse(xml);
118
119                XNamespace jsonNsValue = "http://james.newtonking.com/projects/json";
120                XName jsonNsName = XNamespace.Xmlns + "json";
121
122                doc.Root.SetAttributeValue(jsonNsName, jsonNsValue);
123
124                var events = doc.Root.Elements()/*.ToArray()*/;
125                foreach (var @event in events)
126                {
127                    @event.Name = "events";
128                    @event.SetAttributeValue(jsonNsValue + "Array", "true");
129                }
130                //doc.Root.ReplaceNodes(events);
131//                foreach (var element in doc.Root.Descendants("data").Concat(doc.Root.Descendants("metadata")))
132//                {
133//                    element.RemoveAttributes();
134//                }
135
136                var json = JsonConvert.SerializeXNode(doc.Root, Formatting.None, true);
137                var root = JsonConvert.DeserializeObject<HttpClientMessageDto.WriteEventsDynamic>(json);
138                return root.events;
139//                var root = JsonConvert.DeserializeObject<JObject>(json);
140//                var dynamicEvents = root.ToObject<HttpClientMessageDto.WriteEventsDynamic>();
141//                return dynamicEvents.events;
142            }
143            catch (Exception e)
144            {
145                Log.InfoException(e, "Failed to load xml. Invalid format");
146                return null;
147            }
148        }
149
150        private static Event[] Parse(HttpClientMessageDto.ClientEventDynamic[] dynamicEvents)
151        {
152            var events = new Event[dynamicEvents.Length];
153            for (int i = 0, n = dynamicEvents.Length; i < n; ++i)
154            {
155                var textEvent = dynamicEvents[i];
156                bool dataIsJson;
157                bool metadataIsJson;
158                var data = AsBytes(textEvent.data, out dataIsJson);
159                var metadata = AsBytes(textEvent.metadata, out metadataIsJson);
160
161                events[i] = new Event(textEvent.eventId, textEvent.eventType, dataIsJson || metadataIsJson, data, metadata);
162            }
163            return events.ToArray();
164        }
165
166        private static byte[] AsBytes(object obj, out bool isJson)
167        {
168            if (obj is JObject)
169            {
170                isJson = true;
171                return Helper.UTF8NoBom.GetBytes(Codec.Json.To(obj));
172            }
173
174            isJson = false;
175            return Helper.UTF8NoBom.GetBytes((obj as string) ?? string.Empty);
176        }
177    }
178}