fix: invoke journal service compatibly across 26.1 patches
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
<M42ExtensionId>6673a25d-33d6-4072-91d9-abed4be1a966</M42ExtensionId>
|
||||
<M42AssemblyPattern>C4ITF4SD*.*</M42AssemblyPattern>
|
||||
<M42PackageVersion>1.4.0.23</M42PackageVersion>
|
||||
<M42PackageVersion>1.4.0.24</M42PackageVersion>
|
||||
<M42BuildPackage>true</M42BuildPackage>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -1408,15 +1408,15 @@ namespace C4IT.F4SD
|
||||
{
|
||||
await Task.Delay(0);
|
||||
List<cTicketJournalItem> journalEntries = new List<cTicketJournalItem>();
|
||||
var entries = F4SDM42WebApiController.defaultInstance.GetJournalService().GetJournalList(activityEOID, false, 0, 50, "<a href=\"#\" class=\"mx-object-journal--link {0} {1}\">{2}</a>", 120);
|
||||
LogEntry($"{entries.Length} Journal entries found for ObjectID={activityEOID}", LogLevels.Debug);
|
||||
for (int i = 0; i < entries.Length; i++)
|
||||
var entries = LoadJournalEntries(activityEOID);
|
||||
LogEntry($"{entries.Count} Journal entries found for ObjectID={activityEOID}", LogLevels.Debug);
|
||||
for (int i = 0; i < entries.Count; i++)
|
||||
{
|
||||
Matrix42.Contracts.Platform.Data.JournalEntryInfo item = entries[i];
|
||||
var text = item.Text ?? string.Empty;
|
||||
var createdDate = item.CreatedDate ?? DateTime.MinValue;
|
||||
|
||||
LogEntry($"Journal entry {i + 1}/{entries.Length}: ID={item.Id}, CreatedDate={createdDate}, CreatedBy={item.Creator}, Header={item.Header}", LogLevels.Debug);
|
||||
LogEntry($"Journal entry {i + 1}/{entries.Count}: ID={item.Id}, CreatedDate={createdDate}, CreatedBy={item.Creator}, Header={item.Header}", LogLevels.Debug);
|
||||
journalEntries.Add(new cTicketJournalItem()
|
||||
{
|
||||
JournalId = item.Id,
|
||||
@@ -1446,6 +1446,125 @@ namespace C4IT.F4SD
|
||||
}
|
||||
}
|
||||
|
||||
private static IReadOnlyList<Matrix42.Contracts.Platform.Data.JournalEntryInfo> LoadJournalEntries(Guid activityEOID)
|
||||
{
|
||||
var journalService = F4SDM42WebApiController.defaultInstance.GetJournalService();
|
||||
var serviceType = journalService.GetType();
|
||||
var objectLinkTemplate = "<a href=\"#\" class=\"mx-object-journal--link {0} {1}\">{2}</a>";
|
||||
var methods = serviceType
|
||||
.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
|
||||
.Where(IsJournalReaderMethod)
|
||||
.OrderByDescending(method => method.GetParameters().Length)
|
||||
.ToList();
|
||||
|
||||
foreach (var method in methods)
|
||||
{
|
||||
if (!TryBuildJournalListArguments(method, activityEOID, objectLinkTemplate, out var arguments))
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
var result = method.Invoke(journalService, arguments);
|
||||
if (result is Matrix42.Contracts.Platform.Data.JournalEntryInfo[] arrayResult)
|
||||
return arrayResult;
|
||||
|
||||
if (result is IEnumerable<Matrix42.Contracts.Platform.Data.JournalEntryInfo> enumerableResult)
|
||||
return enumerableResult.ToList();
|
||||
|
||||
throw new MissingMethodException($"IJournalService.GetJournalList returned unsupported type '{result?.GetType().FullName ?? "<null>"}'.");
|
||||
}
|
||||
catch (TargetInvocationException ex) when (ex.InnerException != null)
|
||||
{
|
||||
throw ex.InnerException;
|
||||
}
|
||||
}
|
||||
|
||||
throw new MissingMethodException($"No compatible IJournalService.GetJournalList overload was found on '{serviceType.FullName}'. Available overloads: {string.Join("; ", methods.Select(FormatMethodSignature))}");
|
||||
}
|
||||
|
||||
private static bool IsJournalReaderMethod(MethodInfo method)
|
||||
{
|
||||
var methodName = method.Name;
|
||||
if (methodName.Contains("."))
|
||||
methodName = methodName.Substring(methodName.LastIndexOf(".", StringComparison.Ordinal) + 1);
|
||||
|
||||
if (!(methodName.StartsWith("Get", StringComparison.OrdinalIgnoreCase) || methodName.StartsWith("Load", StringComparison.OrdinalIgnoreCase)))
|
||||
return false;
|
||||
|
||||
if (!methodName.Contains("Journal", StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
|
||||
if (!method.GetParameters().Any(parameter => parameter.ParameterType == typeof(Guid)))
|
||||
return false;
|
||||
|
||||
var returnType = method.ReturnType;
|
||||
if (returnType.IsArray)
|
||||
return returnType.GetElementType()?.FullName == typeof(Matrix42.Contracts.Platform.Data.JournalEntryInfo).FullName;
|
||||
|
||||
if (returnType.FullName == typeof(Matrix42.Contracts.Platform.Data.JournalEntryInfo).FullName)
|
||||
return true;
|
||||
|
||||
return returnType.GetInterfaces()
|
||||
.Where(type => type.IsGenericType)
|
||||
.Select(type => type.GetGenericArguments().FirstOrDefault())
|
||||
.Any(type => type?.FullName == typeof(Matrix42.Contracts.Platform.Data.JournalEntryInfo).FullName);
|
||||
}
|
||||
|
||||
private static bool TryBuildJournalListArguments(MethodInfo method, Guid activityEOID, string objectLinkTemplate, out object[] arguments)
|
||||
{
|
||||
var parameters = method.GetParameters();
|
||||
arguments = new object[parameters.Length];
|
||||
|
||||
for (int i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
var parameter = parameters[i];
|
||||
var parameterType = parameter.ParameterType;
|
||||
var parameterName = parameter.Name ?? string.Empty;
|
||||
var lowerName = parameterName.ToLowerInvariant();
|
||||
|
||||
if (parameterType == typeof(Guid))
|
||||
{
|
||||
arguments[i] = activityEOID;
|
||||
}
|
||||
else if (parameterType == typeof(bool))
|
||||
{
|
||||
arguments[i] = false;
|
||||
}
|
||||
else if (parameterType == typeof(int))
|
||||
{
|
||||
if (lowerName.Contains("time"))
|
||||
arguments[i] = 120;
|
||||
else if (lowerName.Contains("count") || lowerName.Contains("take") || lowerName.Contains("limit") || lowerName.Contains("size"))
|
||||
arguments[i] = 50;
|
||||
else
|
||||
arguments[i] = 0;
|
||||
}
|
||||
else if (parameterType == typeof(string))
|
||||
{
|
||||
arguments[i] = lowerName.Contains("template") || lowerName.Contains("link") ? objectLinkTemplate : null;
|
||||
}
|
||||
else if (parameterType == typeof(string[]))
|
||||
{
|
||||
arguments[i] = null;
|
||||
}
|
||||
else if (parameter.HasDefaultValue)
|
||||
{
|
||||
arguments[i] = parameter.DefaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static string FormatMethodSignature(MethodInfo method)
|
||||
{
|
||||
return $"{method.ReturnType.FullName} {method.Name}({string.Join(", ", method.GetParameters().Select(parameter => $"{parameter.ParameterType.FullName} {parameter.Name}"))})";
|
||||
}
|
||||
|
||||
internal async Task<bool> updateActivitySolution(Guid objectId, string solutionHtml)
|
||||
{
|
||||
|
||||
|
||||
Reference in New Issue
Block a user