Files
adas-core/adas-core.Infrastructure/Utils/PatientPumpObservationConverter.cs
T

142 lines
7.9 KiB
C#

using System.Reflection;
using adas_core.Domain.Models;
using adas_core.Domain.Models.Pumps;
using MongoDB.Bson.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using JsonConverterAttribute = Newtonsoft.Json.JsonConverterAttribute;
namespace adas_core.Infrastructure.Utils;
/// <summary>
/// Provides JSON conversion for <see cref="PumpObservation"/> instances and supports BSON serialization through the <see cref="IBsonSerializer"/> interface.
/// </summary>
/// <!-- aidoc:v1 sig=8967a45 -->
public class PatientPumpObservationConverter : JsonConverter<PumpObservation>, IBsonSerializer
{
/// <summary>
/// Deserializes a BSON value into a .NET object using the provided deserialization context and arguments.
/// </summary>
/// <param name="context">The BSON deserialization context that provides access to the reader and configuration.</param>
/// <param name="args">The deserialization arguments containing additional settings for the operation.</param>
/// <returns>The deserialized object.</returns>
/// <exception cref="NotImplementedException">Thrown when the method is invoked, as the deserialization logic has not been implemented.</exception>
/// <!-- aidoc:v1 sig=2a74dda body=bfa6f2f -->
public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
throw new NotImplementedException();
}
/// <summary>
/// Serializes the specified value into BSON format using the provided serialization context and arguments.
/// This method is not yet implemented and currently throws an exception when invoked.
/// </summary>
/// <param name="context">The BSON serialization context that provides the writer and configuration for the operation.</param>
/// <param name="args">The BSON serialization arguments that influence the serialization behavior.</param>
/// <param name="value">The object to be serialized into BSON.</param>
/// <exception cref="NotImplementedException">Thrown because the method has not been implemented.</exception>
/// <!-- aidoc:v1 sig=bd1484e body=bfa6f2f -->
public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
{
throw new NotImplementedException();
}
public Type ValueType => typeof(PatientObservationAlarm);
/// <summary>
/// Deserializes a JSON representation into a <see cref="PumpObservation"/> instance.
/// This implementation is not yet provided and always throws an exception.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read JSON from.</param>
/// <param name="objectType">The type of the object to deserialize.</param>
/// <param name="existingValue">The existing value of the object being read, or <c>null</c> if there is no existing value.</param>
/// <param name="hasExistingValue">A value indicating whether <paramref name="existingValue"/> has a value.</param>
/// <param name="serializer">The <see cref="JsonSerializer"/> used for deserialization.</param>
/// <returns>A <see cref="PumpObservation"/> instance reconstructed from the JSON data.</returns>
/// <exception cref="NotImplementedException">Thrown because the method has not been implemented yet.</exception>
/// <!-- aidoc:v1 sig=5a89314 body=bfa6f2f -->
public override PumpObservation ReadJson(JsonReader reader, Type objectType,
PumpObservation? existingValue,
bool hasExistingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
/// <summary>
/// Serializes the specified value to JSON, applying string enum conversion to the Event, Status, PumpMode, InfusingStatus, and AlarmMode properties. No output is written when the value is null.
/// </summary>
/// <param name="writer">The JSON writer to which the serialized object is written.</param>
/// <param name="value">The object to serialize; if null, the method does nothing.</param>
/// <param name="serializer">The JSON serializer used as context for the conversion.</param>
/// <!-- aidoc-review:v1 severity=medium kind=wrong_param_role
/// "The 'serializer' parameter is documented as 'The JSON serializer used as context for the conversion', but it is never referenced anywhere in the method body (the JSON is written via JObject.FromObject and jo.WriteTo, neither of which uses this argument)." -->
public new void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value != null)
{
var jo = JObject.FromObject(value);
// Add [JsonConverter(typeof(StringEnumConverter))] attribute to specified properties
AddStringEnumConverterAttribute(value, "Event");
AddStringEnumConverterAttribute(value, "Status");
AddStringEnumConverterAttribute(value, "PumpMode");
AddStringEnumConverterAttribute(value, "InfusingStatus");
AddStringEnumConverterAttribute(value, "AlarmMode");
jo.WriteTo(writer);
}
}
/// <summary>
/// Serializes a <see cref="PumpObservation"/> instance to JSON. This override is not yet implemented and will always throw.
/// </summary>
/// <param name="writer">The JSON writer used to emit the serialized output.</param>
/// <param name="value">The <see cref="PumpObservation"/> to serialize, or <see langword="null"/> if no value is available.</param>
/// <param name="serializer">The <see cref="JsonSerializer"/> providing serialization context and options.</param>
/// <exception cref="NotImplementedException">Always thrown because the method has not been implemented.</exception>
/// <!-- aidoc:v1 sig=6f585c5 body=bfa6f2f -->
public override void WriteJson(JsonWriter writer, PumpObservation? value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
/// <summary>
/// Adds a <see cref="JsonConverterAttribute"/> of type <see cref="StringEnumConverter"/> to the specified property, ensuring that enum values are serialized as their string names rather than numeric values. If the property already has a <see cref="JsonConverterAttribute"/> applied, no changes are made.
/// </summary>
/// <param name="value">The object instance whose property will be inspected for the attribute.</param>
/// <param name="propertyName">The name of the property to which the converter attribute will be added.</param>
/// <!-- aidoc:v1 sig=02b15d7 body=a196735 -->
private static void AddStringEnumConverterAttribute(object value, string propertyName)
{
var prop = value.GetType().GetProperty(propertyName);
var attr = new JsonConverterAttribute(typeof(StringEnumConverter));
if (prop != null)
{
var attrs = prop.GetCustomAttributes(false);
// Check if the attribute is not already applied
if (Array.Find(attrs, a => a is JsonConverterAttribute) == null)
{
// Create a new array that includes the existing attributes and the new one
var newAttrs = new object[attrs.Length + 1];
Array.Copy(attrs, newAttrs, attrs.Length);
newAttrs[attrs.Length] = attr;
// Use reflection to set the new attributes array
var field = typeof(PropertyInfo).GetField("m_customAttributes",
BindingFlags.Instance | BindingFlags.NonPublic);
field?.SetValue(prop, newAttrs);
}
}
}
}
/*How to use it:
BsonSerializer.RegisterSerializer(new PatientObservationAlarmConverter());
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
Converters = { new PatientObservationAlarmConverter() }
};
*/