feature: expose custom details to expressions

custom details can now be easily retrieved from any expression
This commit is contained in:
Gary Sharp
2021-02-07 18:17:03 +11:00
parent 3e57af394d
commit 9bfeff8c42
9 changed files with 181 additions and 81 deletions
+1 -1
View File
@@ -218,7 +218,7 @@ namespace Disco.BI.Interop.Pdf
pdfStamper.FormFlattening = FlattenFields;
pdfStamper.Writer.CloseStream = false;
IDictionary expressionVariables = Expression.StandardVariables(dt, Database, CreatorUser, TimeStamp, State);
IDictionary expressionVariables = Expression.StandardVariables(dt, Database, CreatorUser, TimeStamp, State, Data);
foreach (string pdfFieldKey in pdfStamper.AcroFields.Fields.Keys)
{
+1 -1
View File
@@ -28,7 +28,7 @@ namespace Disco.Services
//return Expressions.Expression.TokenizeSingleDynamic(null, deviceProfile.Configuration(context).ComputerNameTemplate, 0);
return Expression.TokenizeSingleDynamic(null, deviceProfile.ComputerNameTemplate, 0);
});
var evaluatorVariables = Expression.StandardVariables(null, Database, UserService.CurrentUser, DateTime.Now, null);
var evaluatorVariables = Expression.StandardVariables(null, Database, UserService.CurrentUser, DateTime.Now, null, device);
string rendered;
try
{
@@ -235,7 +235,7 @@ namespace Disco.Services.Documents.AttachmentImport
{
try
{
var expressionResult = Identifier.DocumentTemplate.EvaluateOnAttachmentImportExpression(attachment, Database, creatorUser, Identifier.TimeStamp, PageIdentifiers);
var expressionResult = Identifier.DocumentTemplate.EvaluateOnAttachmentImportExpression(attachment, Identifier.Target, Database, creatorUser, Identifier.TimeStamp, PageIdentifiers);
DocumentsLog.LogImportAttachmentExpressionEvaluated(Identifier.DocumentTemplate, Identifier.Target, attachment, expressionResult);
}
catch (Exception ex)
@@ -22,12 +22,12 @@ namespace Disco.Services
ExpressionCache.InvalidateKey("DocumentTemplate_FilterExpression", dt.Id);
}
public static bool FilterExpressionMatches(this DocumentTemplate dt, object Data, DiscoDataContext Database, User User, System.DateTime TimeStamp, DocumentState State)
public static bool FilterExpressionMatches(this DocumentTemplate dt, IAttachmentTarget Data, DiscoDataContext Database, User User, System.DateTime TimeStamp, DocumentState State)
{
if (!string.IsNullOrEmpty(dt.FilterExpression))
{
var compiledExpression = dt.FilterExpressionFromCache();
var evaluatorVariables = Expression.StandardVariables(dt, Database, User, TimeStamp, State);
var evaluatorVariables = Expression.StandardVariables(dt, Database, User, TimeStamp, State, Data);
try
{
var er = compiledExpression.EvaluateFirst<object>(Data, evaluatorVariables);
@@ -59,12 +59,12 @@ namespace Disco.Services
ExpressionCache.InvalidateKey("DocumentTemplate_OnImportExpression", dt.Id);
}
public static string EvaluateOnAttachmentImportExpression(this DocumentTemplate dt, IAttachment Data, DiscoDataContext Database, User User, DateTime TimeStamp, List<DocumentUniqueIdentifier> PageIdentifiers)
public static string EvaluateOnAttachmentImportExpression(this DocumentTemplate dt, IAttachment Data, IAttachmentTarget AttachmentTarget, DiscoDataContext Database, User User, DateTime TimeStamp, List<DocumentUniqueIdentifier> PageIdentifiers)
{
if (!string.IsNullOrEmpty(dt.OnImportAttachmentExpression))
{
var compiledExpression = dt.OnImportAttachmentExpressionFromCache();
var evaluatorVariables = Expression.StandardVariables(dt, Database, User, TimeStamp, null);
var evaluatorVariables = Expression.StandardVariables(dt, Database, User, TimeStamp, null, AttachmentTarget);
evaluatorVariables.Add("PageIdentifiers", PageIdentifiers);
var result = compiledExpression.EvaluateFirst<object>(Data, evaluatorVariables);
if (result == null)
@@ -85,12 +85,12 @@ namespace Disco.Services
ExpressionCache.InvalidateKey("DocumentTemplate_OnGenerateExpression", dt.Id);
}
public static string EvaluateOnGenerateExpression(this DocumentTemplate dt, object Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State)
public static string EvaluateOnGenerateExpression(this DocumentTemplate dt, IAttachmentTarget Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State)
{
if (!string.IsNullOrEmpty(dt.OnGenerateExpression))
{
var compiledExpression = dt.OnGenerateExpressionFromCache();
var evaluatorVariables = Expression.StandardVariables(dt, Database, User, TimeStamp, State);
var evaluatorVariables = Expression.StandardVariables(dt, Database, User, TimeStamp, State, Data);
var result = compiledExpression.EvaluateFirst<object>(Data, evaluatorVariables);
return result.ToString();
@@ -81,12 +81,12 @@ namespace Disco.Services
ExpressionCache.InvalidateKey("DocumentTemplatePackage_FilterExpression", package.Id);
}
public static bool FilterExpressionMatches(this DocumentTemplatePackage package, object Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State)
public static bool FilterExpressionMatches(this DocumentTemplatePackage package, IAttachmentTarget Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State)
{
if (!string.IsNullOrEmpty(package.FilterExpression))
{
var compiledExpression = package.FilterExpressionFromCache();
var evaluatorVariables = Expression.StandardVariables(null, Database, User, TimeStamp, State);
var evaluatorVariables = Expression.StandardVariables(null, Database, User, TimeStamp, State, Data);
evaluatorVariables.Add("Package", package);
try
{
@@ -119,12 +119,12 @@ namespace Disco.Services
ExpressionCache.InvalidateKey("DocumentTemplatePackage_OnGenerateExpression", package.Id);
}
public static string EvaluateOnGenerateExpression(this DocumentTemplatePackage package, object Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State)
public static string EvaluateOnGenerateExpression(this DocumentTemplatePackage package, IAttachmentTarget Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State)
{
if (!string.IsNullOrEmpty(package.OnGenerateExpression))
{
Expression compiledExpression = package.OnGenerateExpressionFromCache();
System.Collections.IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, User, TimeStamp, State);
System.Collections.IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, User, TimeStamp, State, Data);
evaluatorVariables.Add("Package", package);
try
{
+101 -64
View File
@@ -2,11 +2,13 @@ using Disco.Data.Repository;
using Disco.Models.BI.Expressions;
using Disco.Models.Repository;
using Disco.Models.Services.Documents;
using Disco.Services.Plugins.Features.DetailsProvider;
using Spring.Core.TypeResolution;
using Spring.Expressions;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Disco.Services.Expressions
@@ -173,92 +175,127 @@ namespace Disco.Services.Expressions
return e;
}
public static IDictionary StandardVariables(DocumentTemplate AttachmentType, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState DocumentState)
public static IDictionary StandardVariables(DocumentTemplate AttachmentType, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState DocumentState, IAttachmentTarget target = null)
{
return new Hashtable
{
var detailsVariables = new Dictionary<string, object>();
var detailsService = new DetailsProviderService(Database);
if (target != null)
{
if (target is User targetUser)
{
detailsVariables.Add("UserDetails", new LazyDictionary(() => detailsService.GetDetails(targetUser).Details));
detailsVariables.Add("AssignedDeviceDetails", targetUser.CurrentDeviceUserAssignments().Select(a => new { a.Device, Details = new LazyDictionary(() => detailsService.GetDetails(targetUser).Details) }).ToDictionary(d => d.Device.SerialNumber, d => d.Details, StringComparer.OrdinalIgnoreCase));
}
else if (target is Job targetJob)
{
detailsVariables.Add("UserDetails", targetJob.User == null ? (IDictionary<string, string>)new Dictionary<string, string>() : new LazyDictionary(() => detailsService.GetDetails(targetJob.User).Details));
detailsVariables.Add("DeviceDetails", targetJob.Device == null ? (IDictionary<string, string>)new Dictionary<string, string>() : new LazyDictionary(() => detailsService.GetDetails(targetJob.Device).Details));
}
else if (target is Device targetDevice)
{
detailsVariables.Add("DeviceDetails", new LazyDictionary(() => detailsService.GetDetails(targetDevice).Details));
detailsVariables.Add("UserDetails", targetDevice.AssignedUser == null ? (IDictionary<string, string>)new Dictionary<string, string>() : new LazyDictionary(() => detailsService.GetDetails(targetDevice.AssignedUser).Details));
}
}
{
"DataContext",
Database
},
return new Hashtable(detailsVariables)
{
{
"DataContext",
Database
},
{
"User",
User
},
{
"User",
User
},
{
"TimeStamp",
TimeStamp
},
{
"TimeStamp",
TimeStamp
},
{
"AttachmentType",
AttachmentType
},
{
"AttachmentType",
AttachmentType
},
{
"State",
DocumentState
}
};
{
"State",
DocumentState
}
};
}
public static Dictionary<string, string> StandardVariableTypes()
{
return new Dictionary<string, string>
{
{
{
"#DataContext",
typeof(DiscoDataContext).AssemblyQualifiedName
},
{
"#DataContext",
typeof(DiscoDataContext).AssemblyQualifiedName
},
{
"#User",
typeof(User).AssemblyQualifiedName
},
{
"#User",
typeof(User).AssemblyQualifiedName
},
{
"#TimeStamp",
typeof(DateTime).AssemblyQualifiedName
},
{
"#TimeStamp",
typeof(DateTime).AssemblyQualifiedName
},
{
"#AttachmentType",
typeof(DocumentTemplate).AssemblyQualifiedName
},
{
"#AttachmentType",
typeof(DocumentTemplate).AssemblyQualifiedName
},
{
"#State",
typeof(DocumentState).AssemblyQualifiedName
}
};
{
"#State",
typeof(DocumentState).AssemblyQualifiedName
},
{
"#UserDetails",
typeof(Dictionary<string, string>).AssemblyQualifiedName
},
{
"#DeviceDetails",
typeof(Dictionary<string, string>).AssemblyQualifiedName
},
{
"#AssignedDeviceDetails",
typeof(Dictionary<string, Dictionary<string, string>>).AssemblyQualifiedName
},
};
}
public static Dictionary<string, string> ExtensionLibraryTypes()
{
return new Dictionary<string, string>
{
{
"DataExt",
typeof(Extensions.DataExt).AssemblyQualifiedName
},
{
{
"DataExt",
typeof(Extensions.DataExt).AssemblyQualifiedName
},
{
"DeviceExt",
typeof(Extensions.DeviceExt).AssemblyQualifiedName
},
{
"ImageExt",
typeof(Extensions.ImageExt).AssemblyQualifiedName
},
"DeviceExt",
typeof(Extensions.DeviceExt).AssemblyQualifiedName
},
{
"UserExt",
typeof(Extensions.UserExt).AssemblyQualifiedName
}
};
"ImageExt",
typeof(Extensions.ImageExt).AssemblyQualifiedName
},
{
"UserExt",
typeof(Extensions.UserExt).AssemblyQualifiedName
}
};
}
}
@@ -0,0 +1,63 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Disco.Services.Expressions
{
public class LazyDictionary : IDictionary<string, string>
{
private readonly Lazy<IDictionary<string, string>> dictionary;
public LazyDictionary(Func<IDictionary<string, string>> dictionaryFactory)
{
if (dictionaryFactory == null)
throw new ArgumentNullException(nameof(dictionaryFactory));
dictionary = new Lazy<IDictionary<string, string>>(dictionaryFactory);
}
public string this[string key]
{
get => dictionary.Value.TryGetValue(key, out var value) ? value : null;
set => throw new NotSupportedException();
}
public ICollection<string> Keys => dictionary.Value.Keys;
public ICollection<string> Values => dictionary.Value.Values;
public int Count => dictionary.Value.Count;
public bool IsReadOnly => true;
public void Add(string key, string value)
=> throw new NotSupportedException();
public void Add(KeyValuePair<string, string> item)
=> throw new NotSupportedException();
public void Clear()
=> throw new NotSupportedException();
public bool Contains(KeyValuePair<string, string> item)
=> dictionary.Value.Contains(item);
public bool ContainsKey(string key)
=> dictionary.Value.ContainsKey(key);
public void CopyTo(KeyValuePair<string, string>[] array, int arrayIndex)
=> throw new NotSupportedException();
public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
=> dictionary.Value.GetEnumerator();
public bool Remove(string key)
=> throw new NotSupportedException();
public bool Remove(KeyValuePair<string, string> item)
=> throw new NotSupportedException();
public bool TryGetValue(string key, out string value)
=> dictionary.Value.TryGetValue(key, out value);
IEnumerator IEnumerable.GetEnumerator()
=> dictionary.Value.GetEnumerator();
}
}
+2 -2
View File
@@ -397,7 +397,7 @@ namespace Disco.Services
if (!string.IsNullOrEmpty(Database.DiscoConfiguration.JobPreferences.OnCreateExpression))
{
Expression compiledExpression = Jobs.Jobs.OnCreateExpressionFromCache(Database);
IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, job.OpenedTechUser, DateTime.Now, null);
IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, job.OpenedTechUser, DateTime.Now, null, job);
object result = compiledExpression.EvaluateFirst<object>(job, evaluatorVariables);
if (result == null)
return null;
@@ -412,7 +412,7 @@ namespace Disco.Services
if (!string.IsNullOrEmpty(Database.DiscoConfiguration.JobPreferences.OnCloseExpression))
{
Expression compiledExpression = Jobs.Jobs.OnCloseExpressionFromCache(Database);
IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, job.OpenedTechUser, DateTime.Now, null);
IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, job.OpenedTechUser, DateTime.Now, null, job);
object result = compiledExpression.EvaluateFirst<object>(job, evaluatorVariables);
if (result == null)
return null;
@@ -146,7 +146,7 @@ namespace Disco.Services
if (!string.IsNullOrEmpty(ufa.UserFlag.OnAssignmentExpression))
{
Expression compiledExpression = ufa.UserFlag.OnAssignmentExpressionFromCache();
IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, AddingUser, TimeStamp, null);
IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, AddingUser, TimeStamp, null, ufa.User);
object result = compiledExpression.EvaluateFirst<object>(ufa, evaluatorVariables);
if (result == null)
return null;
@@ -171,7 +171,7 @@ namespace Disco.Services
if (!string.IsNullOrEmpty(ufa.UserFlag.OnUnassignmentExpression))
{
Expression compiledExpression = ufa.UserFlag.OnUnassignmentExpressionFromCache();
IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, RemovingUser, TimeStamp, null);
IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, RemovingUser, TimeStamp, null, ufa.User);
object result = compiledExpression.EvaluateFirst<object>(ufa, evaluatorVariables);
if (result == null)
return null;