Creado apartir del commit b888de6c92056de294456f581a56e25e734d4ab7 de develop
This commit is contained in:
@@ -0,0 +1,273 @@
|
||||
using adas_core.Domain.Models.MongoModels;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.IO;
|
||||
using MongoDB.Bson.Serialization;
|
||||
using MongoDB.Bson.Serialization.Serializers;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace adas_core.Domain.Models.BsonConverters;
|
||||
|
||||
public class DictionaryBsonConverter : SerializerBase<Dictionary<string, object>>
|
||||
{
|
||||
public override Dictionary<string, object> Deserialize(BsonDeserializationContext context,
|
||||
BsonDeserializationArgs args)
|
||||
{
|
||||
var reader = context.Reader;
|
||||
var stepsDictionary = new Dictionary<string, object>();
|
||||
|
||||
if (reader.CurrentBsonType == BsonType.Document)
|
||||
{
|
||||
reader.ReadStartDocument();
|
||||
|
||||
while (reader.ReadBsonType() != BsonType.EndOfDocument)
|
||||
{
|
||||
var key = reader.ReadName();
|
||||
|
||||
switch (key.ToUpper())
|
||||
{
|
||||
case "STEPS":
|
||||
var stepList = BsonSerializer.Deserialize<List<Step>>(reader);
|
||||
stepsDictionary[key] = stepList;
|
||||
break;
|
||||
case "BEACONS":
|
||||
var beaconList = BsonSerializer.Deserialize<List<LightBeacon>>(reader);
|
||||
stepsDictionary[key] = beaconList;
|
||||
break;
|
||||
case "CAMERAS":
|
||||
var cameraList = BsonSerializer.Deserialize<List<Camera>>(reader);
|
||||
stepsDictionary[key] = cameraList;
|
||||
break;
|
||||
case "RELAY":
|
||||
var relayList = BsonSerializer.Deserialize<Relay>(reader);
|
||||
stepsDictionary[key] = relayList;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (reader.CurrentBsonType)
|
||||
{
|
||||
case BsonType.Int32:
|
||||
case BsonType.Int64:
|
||||
stepsDictionary[key] = BsonSerializer.Deserialize<long>(reader);
|
||||
break;
|
||||
case BsonType.Double:
|
||||
stepsDictionary[key] = BsonSerializer.Deserialize<double>(reader);
|
||||
break;
|
||||
case BsonType.String:
|
||||
stepsDictionary[key] = BsonSerializer.Deserialize<string>(reader);
|
||||
break;
|
||||
case BsonType.Boolean:
|
||||
stepsDictionary[key] = BsonSerializer.Deserialize<bool>(reader);
|
||||
break;
|
||||
case BsonType.Array:
|
||||
reader.ReadStartArray();
|
||||
var arrayItems = new List<object>();
|
||||
while (reader.ReadBsonType() != BsonType.EndOfDocument)
|
||||
switch (reader.CurrentBsonType)
|
||||
{
|
||||
case BsonType.String:
|
||||
arrayItems.Add(BsonSerializer.Deserialize<string>(reader));
|
||||
break;
|
||||
case BsonType.Int32:
|
||||
arrayItems.Add(BsonSerializer.Deserialize<int>(reader));
|
||||
break;
|
||||
case BsonType.Int64:
|
||||
arrayItems.Add(BsonSerializer.Deserialize<long>(reader));
|
||||
break;
|
||||
case BsonType.Boolean:
|
||||
arrayItems.Add(BsonSerializer.Deserialize<bool>(reader));
|
||||
break;
|
||||
case BsonType.Double:
|
||||
arrayItems.Add(BsonSerializer.Deserialize<double>(reader));
|
||||
break;
|
||||
case BsonType.ObjectId:
|
||||
arrayItems.Add(BsonSerializer.Deserialize<ObjectId>(reader));
|
||||
break;
|
||||
case BsonType.DateTime:
|
||||
arrayItems.Add(BsonSerializer.Deserialize<DateTime>(reader));
|
||||
break;
|
||||
|
||||
default:
|
||||
reader.SkipValue();
|
||||
break;
|
||||
}
|
||||
|
||||
reader.ReadEndArray();
|
||||
stepsDictionary[key] = arrayItems;
|
||||
break;
|
||||
default:
|
||||
var bsonDoc = BsonSerializer.Deserialize<BsonDocument>(reader);
|
||||
stepsDictionary[key] = bsonDoc.ToDictionary();
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
reader.ReadEndDocument();
|
||||
}
|
||||
|
||||
return stepsDictionary;
|
||||
}
|
||||
|
||||
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args,
|
||||
Dictionary<string, object> value)
|
||||
{
|
||||
var writer = context.Writer;
|
||||
writer.WriteStartDocument();
|
||||
|
||||
foreach (var item in value)
|
||||
{
|
||||
if (TrySerializeKeyValuePair(item, writer)) continue;
|
||||
|
||||
// Si llegamos a este punto, encontramos un tipo no soportado.
|
||||
writer.WriteName(item.Key);
|
||||
writer.WriteNull(); // Escribe un valor null si el tipo no es soportado.
|
||||
}
|
||||
|
||||
|
||||
writer.WriteEndDocument();
|
||||
}
|
||||
|
||||
private static bool TrySerializeKeyValuePair(KeyValuePair<string, object> item, IBsonWriter writer)
|
||||
{
|
||||
writer.WriteName(item.Key);
|
||||
|
||||
switch (item.Key)
|
||||
{
|
||||
case "steps":
|
||||
if (item.Value is JArray jSteps)
|
||||
{
|
||||
var steps = jSteps.ToObject<List<Step>>();
|
||||
BsonSerializer.Serialize(writer, typeof(List<Step>), steps);
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "beacons":
|
||||
if (item.Value is JArray jBeaconConfigs)
|
||||
{
|
||||
var beaconConfigs = jBeaconConfigs.ToObject<List<LightBeacon>>();
|
||||
BsonSerializer.Serialize(writer, typeof(List<LightBeacon>), beaconConfigs);
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
case "cameras":
|
||||
if (item.Value is JArray jCamerasConfigs)
|
||||
{
|
||||
var cameraConfigs = jCamerasConfigs.ToObject<List<Camera>>();
|
||||
BsonSerializer.Serialize(writer, typeof(List<Camera>), cameraConfigs);
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
case "relay":
|
||||
if (item.Value is JObject jRelayConfigs)
|
||||
{
|
||||
var relayConfigs = jRelayConfigs.ToObject<Relay>();
|
||||
BsonSerializer.Serialize(writer, relayConfigs);
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
case "uiFontProperties":
|
||||
{
|
||||
if (item.Value is JObject jUiFontData)
|
||||
{
|
||||
var uiFontData = jUiFontData.ToObject<UiFontData>();
|
||||
BsonSerializer.Serialize(writer, uiFontData);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (item.Value is Dictionary<string, object> nestedDictionary)
|
||||
{
|
||||
var bsonDoc = new BsonDocument(nestedDictionary);
|
||||
BsonSerializer.Serialize(writer, bsonDoc);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (item.Value is JArray jArray)
|
||||
{
|
||||
var listObjects = jArray.ToObject<List<object>>();
|
||||
BsonSerializer.Serialize(writer, listObjects);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Para otros tipos primitivos, utilizamos BsonValue.Create
|
||||
try
|
||||
{
|
||||
var bsonValue = BsonValue.Create(item.Value);
|
||||
switch (bsonValue.BsonType)
|
||||
{
|
||||
case BsonType.String:
|
||||
writer.WriteString(bsonValue.AsString);
|
||||
break;
|
||||
|
||||
case BsonType.Int32:
|
||||
writer.WriteInt32(bsonValue.AsInt32);
|
||||
break;
|
||||
|
||||
case BsonType.Int64:
|
||||
writer.WriteInt64(bsonValue.AsInt64);
|
||||
break;
|
||||
|
||||
case BsonType.Double:
|
||||
writer.WriteDouble(bsonValue.AsDouble);
|
||||
break;
|
||||
|
||||
case BsonType.Boolean:
|
||||
writer.WriteBoolean(bsonValue.AsBoolean);
|
||||
break;
|
||||
|
||||
case BsonType.Array:
|
||||
writer.WriteStartArray();
|
||||
foreach (var arrayValue in bsonValue.AsBsonArray)
|
||||
switch (arrayValue.BsonType)
|
||||
{
|
||||
case BsonType.String:
|
||||
writer.WriteString(arrayValue.AsString);
|
||||
break;
|
||||
|
||||
case BsonType.Int32:
|
||||
writer.WriteInt32(arrayValue.AsInt32);
|
||||
break;
|
||||
|
||||
case BsonType.Int64:
|
||||
writer.WriteInt64(arrayValue.AsInt64);
|
||||
break;
|
||||
|
||||
case BsonType.Double:
|
||||
writer.WriteDouble(arrayValue.AsDouble);
|
||||
break;
|
||||
|
||||
case BsonType.Boolean:
|
||||
writer.WriteBoolean(arrayValue.AsBoolean);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new BsonSerializationException(
|
||||
$"No se puede serializar el tipo Bson en el array: {arrayValue.BsonType}");
|
||||
}
|
||||
|
||||
writer.WriteEndArray();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"BsonType {bsonValue.BsonType} no es compatible.");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user