add girIgnore
This commit is contained in:
Executable
+197
@@ -0,0 +1,197 @@
|
||||
using audit.Model;
|
||||
|
||||
namespace audit_logs.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MongoDB.Bson;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Utils;
|
||||
|
||||
public class JsonComparer
|
||||
{
|
||||
public List<AuditRecord.Change> GetDifferences(object? originalJson, object? modifiedJson)
|
||||
{
|
||||
var changes = new List<AuditRecord.Change>();
|
||||
|
||||
// Convertir los objetos a cadenas JSON; usar "{}" si el objeto es null
|
||||
var originalJsonString = originalJson != null
|
||||
? JsonConverter.ConvertObjectToJson(originalJson)
|
||||
: "{}";
|
||||
var modifiedJsonString = modifiedJson != null
|
||||
? JsonConverter.ConvertObjectToJson(modifiedJson)
|
||||
: "{}";
|
||||
|
||||
// Intentar parsear a JObject solo si el JSON es un objeto
|
||||
var originalObj = ParseAsJObject(originalJsonString);
|
||||
var modifiedObj = ParseAsJObject(modifiedJsonString);
|
||||
//eliminamos aquellas claves que contengan null, por ejemplo "allergies": [
|
||||
// {
|
||||
// "optionType": null,
|
||||
// "name": "Sí",
|
||||
// "iconDefault": "icCheck",
|
||||
// "iconLight": null,
|
||||
// "iconDark": null,
|
||||
// "color": null,
|
||||
// "bgColor": null,
|
||||
// "description": null,
|
||||
// "initDate": null,
|
||||
// "endDate": null
|
||||
// }
|
||||
// ]
|
||||
|
||||
if (originalObj != null)
|
||||
{
|
||||
originalObj = JsonClean.CleanJObject(originalObj);
|
||||
}
|
||||
if (modifiedObj != null)
|
||||
{
|
||||
modifiedObj = JsonClean.CleanJObject(modifiedObj);
|
||||
}
|
||||
// Comparar los objetos JSON
|
||||
CompareJTokens(originalObj, modifiedObj, changes, string.Empty);
|
||||
return changes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Intenta parsear una cadena JSON como JObject. Devuelve null si no es un objeto.
|
||||
/// </summary>
|
||||
/// <param name="json">La cadena JSON a validar.</param>
|
||||
/// <returns>Un JObject si es válido, de lo contrario null.</returns>
|
||||
private static JObject? ParseAsJObject(string json)
|
||||
{
|
||||
try
|
||||
{
|
||||
var token = JToken.Parse(json);
|
||||
return token as JObject; // Devuelve null si no es un JObject
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null; // Si ocurre un error, no es un JSON válido
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void CompareJTokens(JToken original, JToken modified, List<AuditRecord.Change> changes, string path)
|
||||
{
|
||||
foreach (var property in modified.Children<JProperty>())
|
||||
{
|
||||
var fieldPath = string.IsNullOrEmpty(path) ? property.Name : $"{path}.{property.Name}";
|
||||
var originalValue = original[property.Name];
|
||||
var modifiedValue = property.Value;
|
||||
// Ignorar campos donde ambos valores son null
|
||||
if (originalValue == null && modifiedValue.Type == JTokenType.Null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (originalValue == null)
|
||||
{
|
||||
// Campo nuevo
|
||||
changes.Add(new AuditRecord.Change
|
||||
{
|
||||
Field = fieldPath,
|
||||
OldValue = BsonNull.Value,
|
||||
NewValue = ConvertToBsonValue(modifiedValue),
|
||||
ValueType = GetBsonType(modifiedValue)
|
||||
});
|
||||
}
|
||||
else if (!JToken.DeepEquals(originalValue, modifiedValue))
|
||||
{
|
||||
if (originalValue.Type == JTokenType.Object && modifiedValue.Type == JTokenType.Object)
|
||||
{
|
||||
// Comparar objetos anidados
|
||||
CompareJTokens(originalValue, modifiedValue, changes, fieldPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Campo modificado
|
||||
changes.Add(new AuditRecord.Change
|
||||
{
|
||||
Field = fieldPath,
|
||||
OldValue = ConvertToBsonValue(originalValue),
|
||||
NewValue = ConvertToBsonValue(modifiedValue),
|
||||
ValueType = GetBsonType(modifiedValue)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Campos eliminados
|
||||
foreach (var property in original.Children<JProperty>())
|
||||
{
|
||||
var fieldPath = string.IsNullOrEmpty(path) ? property.Name : $"{path}.{property.Name}";
|
||||
if (modified[property.Name] == null)
|
||||
{
|
||||
changes.Add(new AuditRecord.Change
|
||||
{
|
||||
Field = fieldPath,
|
||||
OldValue = ConvertToBsonValue(property.Value),
|
||||
NewValue = BsonNull.Value,
|
||||
ValueType = GetBsonType(property.Value)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*private BsonValue ConvertToBsonValue(JToken token)
|
||||
{
|
||||
return token.Type switch
|
||||
{
|
||||
JTokenType.String => new BsonString(token.ToString()),
|
||||
JTokenType.Integer => new BsonInt32(token.ToObject<int>()),
|
||||
JTokenType.Float => new BsonDouble(token.ToObject<double>()),
|
||||
JTokenType.Boolean => new BsonBoolean(token.ToObject<bool>()),
|
||||
JTokenType.Date => new BsonDateTime(token.ToObject<DateTime>()),
|
||||
JTokenType.Null => BsonNull.Value,
|
||||
JTokenType.Object => BsonDocument.Parse(token.ToString()),
|
||||
JTokenType.Array => new BsonArray(token.ToObject<List<BsonValue>>()),
|
||||
_ => new BsonString(token.ToString())
|
||||
};
|
||||
}*/
|
||||
private BsonValue ConvertToBsonValue(JToken token)
|
||||
{
|
||||
switch (token.Type)
|
||||
{
|
||||
case JTokenType.String:
|
||||
return new BsonString(token.ToString());
|
||||
case JTokenType.Integer:
|
||||
return BsonValue.Create(token.ToObject<int>());
|
||||
case JTokenType.Float:
|
||||
return BsonValue.Create(token.ToObject<double>());
|
||||
case JTokenType.Boolean:
|
||||
return new BsonBoolean(token.ToObject<bool>());
|
||||
case JTokenType.Date:
|
||||
return new BsonDateTime(token.ToObject<DateTime>());
|
||||
case JTokenType.Null:
|
||||
return BsonNull.Value;
|
||||
case JTokenType.Object:
|
||||
return BsonDocument.Parse(token.ToString());
|
||||
case JTokenType.Array:
|
||||
var array = new BsonArray();
|
||||
foreach (var item in token.Children())
|
||||
{
|
||||
array.Add(ConvertToBsonValue(item));
|
||||
}
|
||||
return array;
|
||||
default:
|
||||
return new BsonString(token.ToString()); // Trata cualquier otro tipo como string
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private string GetBsonType(JToken token)
|
||||
{
|
||||
return token.Type switch
|
||||
{
|
||||
JTokenType.String => "string",
|
||||
JTokenType.Integer => "int",
|
||||
JTokenType.Float => "double",
|
||||
JTokenType.Boolean => "bool",
|
||||
JTokenType.Date => "date",
|
||||
JTokenType.Null => "null",
|
||||
JTokenType.Object => "object",
|
||||
JTokenType.Array => "array",
|
||||
_ => "unknown"
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user