xenadmin/XenModel/XenAPI/Converters.cs
Konstantina Chremmou 2ff121fb55 CA-266891: fixed issue where enum properties were not serialised correctly.
Signed-off-by: Konstantina Chremmou <konstantina.chremmou@citrix.com>
2017-11-23 15:13:54 +00:00

274 lines
9.9 KiB
C#

/*
* Copyright (c) Citrix Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1) Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2) Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
namespace XenAPI
{
internal abstract class CustomJsonConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
}
internal class XenRefConverter<T> : CustomJsonConverter<XenRef<T>> where T : XenObject<T>
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken jToken = JToken.Load(reader);
var str = jToken.ToObject<string>();
return new XenRef<T>(str);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var reference = JObject.FromObject(value).GetValue("opaque_ref");
writer.WriteValue(reference);
}
}
internal class XenRefListConverter<T> : CustomJsonConverter<List<XenRef<T>>> where T : XenObject<T>
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken jToken = JToken.Load(reader);
var refList = new List<XenRef<T>>();
foreach (JToken token in jToken.ToArray())
{
var str = token.ToObject<string>();
refList.Add(new XenRef<T>(str));
}
return refList;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var list = value as List<XenRef<T>>;
writer.WriteStartArray();
if (list != null)
list.ForEach(v => writer.WriteValue(v.opaque_ref));
writer.WriteEndArray();
}
}
internal class XenRefXenObjectMapConverter<T> : CustomJsonConverter<Dictionary<XenRef<T>, T>> where T : XenObject<T>
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken jToken = JToken.Load(reader);
var dict = new Dictionary<XenRef<T>, T>();
foreach (JProperty property in jToken)
dict.Add(new XenRef<T>(property.Name), property.Value.ToObject<T>());
return dict;
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
internal class XenRefStringMapConverter<T> : CustomJsonConverter<Dictionary<XenRef<T>, string>> where T : XenObject<T>
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken jToken = JToken.Load(reader);
var dict = new Dictionary<XenRef<T>, string>();
foreach (JProperty property in jToken)
dict.Add(new XenRef<T>(property.Name), property.Value.ToString());
return dict;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var dict = value as Dictionary<XenRef<T>, string>;
writer.WriteStartObject();
if (dict != null)
{
foreach (var kvp in dict)
{
writer.WritePropertyName(kvp.Key.opaque_ref);
writer.WriteValue(kvp.Value);
}
}
writer.WriteEndObject();
}
}
internal class XenRefXenRefMapConverter<TK, TV> : CustomJsonConverter<Dictionary<XenRef<TK>, XenRef<TV>>> where TK : XenObject<TK> where TV : XenObject<TV>
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken jToken = JToken.Load(reader);
var dict = new Dictionary<XenRef<TK>, XenRef<TV>>();
foreach (JProperty property in jToken)
dict.Add(new XenRef<TK>(property.Name), new XenRef<TV>(property.Value.ToString()));
return dict;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var dict = value as Dictionary<XenRef<TK>, XenRef<TV>>;
writer.WriteStartObject();
if (dict != null)
{
foreach (var kvp in dict)
{
writer.WritePropertyName(kvp.Key.opaque_ref);
writer.WriteValue(kvp.Value.opaque_ref);
}
}
writer.WriteEndObject();
}
}
internal class StringXenRefMapConverter<T> : CustomJsonConverter<Dictionary<string, XenRef<T>>> where T : XenObject<T>
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken jToken = JToken.Load(reader);
var dict = new Dictionary<string, XenRef<T>>();
foreach (JProperty property in jToken)
dict.Add(property.Name, new XenRef<T>(property.Value.ToString()));
return dict;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var dict = value as Dictionary<string, XenRef<T>>;
writer.WriteStartObject();
if (dict != null)
{
foreach (var kvp in dict)
{
writer.WritePropertyName(kvp.Key);
writer.WriteValue(kvp.Value.opaque_ref);
}
}
writer.WriteEndObject();
}
}
internal class XenEventConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(Event).IsAssignableFrom(objectType);
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken jToken = JToken.Load(reader);
var id = jToken["id"];
var timestamp = jToken["timestamp"];
var operation = jToken["operation"];
var opaqueRef = jToken["ref"];
var class_ = jToken["class"];
var snapshot = jToken["snapshot"];
var newEvent = new Event
{
id = id == null ? 0 : id.ToObject<long>(),
timestamp = timestamp == null ? null : timestamp.ToObject<string>(),
operation = operation == null ? null : operation.ToObject<string>(),
opaqueRef = opaqueRef == null ? null : opaqueRef.ToObject<string>(),
class_ = class_ == null ? null : class_.ToObject<string>()
};
Type typ = Type.GetType(string.Format("XenAPI.{0}", newEvent.class_), false, true);
newEvent.snapshot = snapshot == null ? null : snapshot.ToObject(typ, serializer);
return newEvent;
}
}
internal class XenDateTimeConverter : IsoDateTimeConverter
{
private static readonly string[] DateFormats = {"yyyyMMddTHH:mm:ssZ", "yyyyMMddTHH:mm:ss"};
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken jToken = JToken.Load(reader);
return DateTime.ParseExact(jToken.ToString(), DateFormats, CultureInfo.InvariantCulture, DateTimeStyles.None);
}
}
internal class XenEnumConverter : StringEnumConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken jToken = JToken.Load(reader);
return Helper.EnumParseDefault(objectType, jToken.ToString());
}
}
}