18using System.Collections.Generic;
22using Newtonsoft.Json.Linq;
27 internal class GPALElementConverter : JsonConverter
29 public override bool CanConvert(Type objectType)
31 return objectType == typeof(GPALElement) || objectType == typeof(List<GPALElement>);
34 public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
39 token = JToken.Load(reader);
43 GPAL.PublishSimpleEvent(GPALEventType.EXCEPTION, $
"Failed to load JSON token",
null, GPALObjectType.None, ex);
44 return objectType == typeof(List<GPALElement>) ?
new List<GPALElement>() : null;
47 if (token.Type == JTokenType.Array)
50 var jsonArray = (JArray)token;
51 var result =
new List<GPALElement>();
55 foreach (JToken maybeWrapped
in jsonArray)
57 JToken payload = maybeWrapped;
60 if (maybeWrapped.Type == JTokenType.Array && maybeWrapped.Children().Count() == 1)
62 payload = maybeWrapped.First;
66 GPALElement element =
null;
68 if (payload.Type == JTokenType.Object)
73 element = DeserializeSingleElement((JObject)payload, serializer);
77 GPAL.PublishSimpleEvent(Enums.GPALEventType.EXCEPTION,
78 "Normal object failed: " + ex.Message);
81 else if (payload.Type == JTokenType.String)
83 string raw = payload.Value<
string>();
84 if (
string.IsNullOrWhiteSpace(raw))
88 if (raw.TrimStart().StartsWith(
"{"))
92 var obj = JObject.Parse(raw);
93 element = DeserializeSingleElement(obj, serializer);
95 catch (JsonReaderException jex)
97 GPAL.PublishSimpleEvent(Enums.GPALEventType.WARNING,
98 "Element string failed parse: " + jex.Message);
104 if (element !=
null && element.Attributes !=
null && element.Attributes.Count > 0)
118 GPAL.PublishSimpleEvent(Enums.GPALEventType.WARNING,
119 "Dropped item — no valid element created");
125 else if (token.Type == JTokenType.Object)
130 var element = DeserializeSingleElement((JObject)token, serializer);
131 if (element !=
null && element.Attributes !=
null)
145 else if (token.Type == JTokenType.String)
150 var jsonString = token.Value<
string>();
151 var parsedObject = JObject.Parse(jsonString);
152 var element = DeserializeSingleElement(parsedObject, serializer);
153 if (element !=
null && element.Attributes !=
null)
164 return objectType == typeof(List<GPALElement>) ?
new List<GPALElement>() : null;
168 return objectType == typeof(List<GPALElement>) ?
new List<GPALElement>() : null;
170 private GPALElement DeserializeSingleElement(JObject jsonObject, JsonSerializer serializer)
172 var gpalelement =
new GPALElement();
175 if (jsonObject[
"Attributes"] !=
null)
177 var attributes =
new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
178 var attributesJson = jsonObject[
"Attributes"] as JObject;
180 if (attributesJson !=
null)
182 foreach (var prop
in attributesJson.Properties())
186 switch (prop.Name.ToLower())
189 var location = prop.Value.ToObject<Point>(serializer);
190 attributes[
"location"] = location;
195 var size = prop.Value.ToObject<Size>(serializer);
196 attributes[
"size"] = size;
200 var boundingRect = prop.Value.ToObject<ClientRectangle>(serializer);
201 attributes[
"boundingRect"] = boundingRect;
205 var xpaths = prop.Value.ToObject<List<XPathInfo>>(serializer);
206 attributes[
"xpaths"] = xpaths.FindAll(x => x !=
null).ToArray();
210 attributes[prop.Name] = prop.Value.ToObject<
object>(serializer);
218 GPAL.PublishSimpleEvent(GPALEventType.EXCEPTION, $
"Failed to deserialize property [{prop.Name}]",
null, GPALObjectType.None, ex);
221 gpalelement.Attributes = attributes;
225 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
"Attributes property is not a valid JObject");
230 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
"Attributes property is missing or null");
234 if (jsonObject[
"ElementHandle"] !=
null)
238 gpalelement.ElementHandle = jsonObject[
"ElementHandle"].ToObject<
string>(serializer);
243 GPAL.PublishSimpleEvent(GPALEventType.EXCEPTION, $
"Failed to deserialize ElementHandle",
null, GPALObjectType.None, ex);
250 public override void WriteJson(JsonWriter writer,
object value, JsonSerializer serializer)
252 GPAL.PublishSimpleEvent(GPALEventType.ERROR,
"Serialization not implemented");
255 public override bool CanWrite =>
false;
258 internal class PointConverter : JsonConverter
260 public override bool CanConvert(Type objectType)
262 return objectType == typeof(Point);
265 public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
269 JToken token = JToken.Load(reader);
270 if (token.Type == JTokenType.Object)
272 var obj = (JObject)token;
273 int x = obj[
"X"]?.Value<
int>() ?? 0;
274 int y = obj[
"Y"]?.Value<
int>() ?? 0;
275 return new Point(x, y);
277 else if (token.Type == JTokenType.String)
279 string[] parts = token.Value<
string>().Split(
',');
280 if (parts.Length == 2 &&
int.TryParse(parts[0], out
int x) &&
int.TryParse(parts[1], out
int y))
282 return new Point(x, y);
285 GPAL.PublishSimpleEvent(GPALEventType.WARNING, $
"Invalid Point format: [{token}]");
290 GPAL.PublishSimpleEvent(GPALEventType.EXCEPTION, $
"Failed to deserialize Point",
null, GPALObjectType.None, ex);
295 public override void WriteJson(JsonWriter writer,
object value, JsonSerializer serializer)
297 var point = (Point)value;
298 writer.WriteValue($
"{point.X},{point.Y}");
301 public override bool CanWrite =>
true;
304 internal class SizeConverter : JsonConverter
306 public override bool CanConvert(Type objectType)
308 return objectType == typeof(Size);
311 public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
315 JToken token = JToken.Load(reader);
316 if (token.Type == JTokenType.Object)
318 var obj = (JObject)token;
319 int width = obj[
"Width"]?.Value<
int>() ?? 0;
320 int height = obj[
"Height"]?.Value<
int>() ?? 0;
321 return new Size(width, height);
323 else if (token.Type == JTokenType.String)
325 string[] parts = token.Value<
string>().Split(
',');
326 if (parts.Length == 2 &&
int.TryParse(parts[0], out
int width) &&
int.TryParse(parts[1], out
int height))
328 return new Size(width, height);
331 GPAL.PublishSimpleEvent(GPALEventType.WARNING, $
"Invalid Size format: [{token}]");
336 GPAL.PublishSimpleEvent(GPALEventType.EXCEPTION, $
"Failed to deserialize Size",
null, GPALObjectType.None, ex);
341 public override void WriteJson(JsonWriter writer,
object value, JsonSerializer serializer)
343 var size = (Size)value;
344 writer.WriteValue($
"{size.Width},{size.Height}");
347 public override bool CanWrite =>
true;