260 lines
8.6 KiB
C#
260 lines
8.6 KiB
C#
using Disco.Data.Repository;
|
|
using Disco.Models.BI.DocumentTemplates;
|
|
using Disco.Models.Repository;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Text;
|
|
using Disco.Models.BI.Expressions;
|
|
|
|
namespace Disco.BI.Expressions
|
|
{
|
|
public sealed class Expression : System.Collections.Generic.List<IExpressionPart>
|
|
{
|
|
public string Name { get; private set; }
|
|
public string Source { get; private set; }
|
|
public bool IsDynamic { get; private set; }
|
|
public int Ordinal { get; private set; }
|
|
|
|
private Expression(string Name, string Source, int Ordinal)
|
|
{
|
|
this.Name = Name;
|
|
this.Source = Source;
|
|
this.Ordinal = Ordinal;
|
|
}
|
|
|
|
public static void InitializeExpressions()
|
|
{
|
|
Spring.Core.TypeResolution.TypeRegistry.RegisterType("DataExt", typeof(Extensions.DataExt));
|
|
Spring.Core.TypeResolution.TypeRegistry.RegisterType("UserExt", typeof(Extensions.UserExt));
|
|
Spring.Core.TypeResolution.TypeRegistry.RegisterType("DeviceExt", typeof(Extensions.DeviceExt));
|
|
Spring.Core.TypeResolution.TypeRegistry.RegisterType("ImageExt", typeof(Extensions.ImageExt));
|
|
}
|
|
|
|
public T EvaluateFirst<T>(object ExpressionContext, System.Collections.IDictionary Variables)
|
|
{
|
|
T result = default(T);
|
|
if (this.Count > 0)
|
|
{
|
|
try
|
|
{
|
|
object expressionResult = this[0].Evaluate(ExpressionContext, Variables);
|
|
if (expressionResult != null)
|
|
{
|
|
if (expressionResult is T)
|
|
{
|
|
result = (T)expressionResult;
|
|
}
|
|
else
|
|
{
|
|
throw new InvalidOperationException("Expression returned an invalid type");
|
|
}
|
|
}
|
|
}
|
|
catch (System.Exception ex)
|
|
{
|
|
throw new InvalidOperationException("Expression evaluation resulted in an error", ex);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public Tuple<string, bool, object> Evaluate(object ExpressionContext, System.Collections.IDictionary Variables)
|
|
{
|
|
System.Text.StringBuilder resultValue = new System.Text.StringBuilder();
|
|
object resultObject = null;
|
|
bool resultError = false;
|
|
foreach (var expressionPart in this)
|
|
{
|
|
try
|
|
{
|
|
object partValue = expressionPart.Evaluate(ExpressionContext, Variables);
|
|
if (partValue != null)
|
|
{
|
|
// Check for Result Objects
|
|
if (partValue is IImageExpressionResult)
|
|
resultObject = partValue;
|
|
else
|
|
resultValue.Append(partValue.ToString());
|
|
}
|
|
}
|
|
catch (System.Exception ex)
|
|
{
|
|
if (!expressionPart.ErrorsAllowed)
|
|
{
|
|
resultValue.Append("## ERROR # ");
|
|
resultValue.Append(ex.Message);
|
|
resultValue.Append(" ##");
|
|
resultError = true;
|
|
}
|
|
}
|
|
}
|
|
return new Tuple<string, bool, object>(resultValue.ToString(), resultError, resultObject);
|
|
}
|
|
public static Expression TokenizeSingleDynamic(string Name, string ExpressionSource, int Ordinal)
|
|
{
|
|
Expression e = new Expression(Name, ExpressionSource, Ordinal);
|
|
if (ExpressionSource != null && !string.IsNullOrWhiteSpace(ExpressionSource))
|
|
e.Add(new EvaluateExpressionPart(ExpressionSource));
|
|
e.IsDynamic = true;
|
|
return e;
|
|
}
|
|
public static Expression Tokenize(string Name, string ExpressionSource, int Ordinal)
|
|
{
|
|
Expression e = new Expression(Name, ExpressionSource, Ordinal);
|
|
if (!ExpressionSource.Contains("{") || !ExpressionSource.Contains("}"))
|
|
{
|
|
e.Add(new TextExpressionPart(ExpressionSource));
|
|
}
|
|
else
|
|
{
|
|
System.Text.StringBuilder token = new System.Text.StringBuilder();
|
|
bool tokenEval = false;
|
|
int tokenEvalDepth = 0;
|
|
foreach (char c in ExpressionSource)
|
|
{
|
|
switch (c)
|
|
{
|
|
case '{':
|
|
{
|
|
if (!tokenEval)
|
|
{
|
|
if (token.Length > 0)
|
|
{
|
|
e.Add(new TextExpressionPart(token.ToString()));
|
|
token = new System.Text.StringBuilder();
|
|
}
|
|
tokenEval = true;
|
|
tokenEvalDepth = 0;
|
|
}
|
|
tokenEvalDepth++;
|
|
token.Append(c);
|
|
break;
|
|
}
|
|
case '}':
|
|
{
|
|
token.Append(c);
|
|
if (tokenEval)
|
|
{
|
|
tokenEvalDepth--;
|
|
if (tokenEvalDepth <= 0)
|
|
{
|
|
if (token.Length != 2 && (token.Length != 3 || token[1] != '@'))
|
|
{
|
|
e.Add(new EvaluateExpressionPart(token.ToString()));
|
|
e.IsDynamic = true;
|
|
token = new System.Text.StringBuilder();
|
|
}
|
|
tokenEval = false;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
token.Append(c);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (token.Length > 0)
|
|
{
|
|
e.Add(new TextExpressionPart(token.ToString()));
|
|
}
|
|
}
|
|
return e;
|
|
}
|
|
|
|
public static IDictionary StandardVariables(DocumentTemplate AttachmentType, DiscoDataContext DataContext, User User, System.DateTime TimeStamp, DocumentState DocumentState)
|
|
{
|
|
return new Hashtable
|
|
{
|
|
|
|
{
|
|
"DataContext",
|
|
DataContext
|
|
},
|
|
|
|
{
|
|
"User",
|
|
User
|
|
},
|
|
|
|
{
|
|
"TimeStamp",
|
|
TimeStamp
|
|
},
|
|
|
|
{
|
|
"AttachmentType",
|
|
AttachmentType
|
|
},
|
|
|
|
{
|
|
"State",
|
|
DocumentState
|
|
}
|
|
};
|
|
}
|
|
public static Dictionary<string, string> StandardVariableTypes()
|
|
{
|
|
return new Dictionary<string, string>
|
|
{
|
|
|
|
{
|
|
"#DataContext",
|
|
typeof(DiscoDataContext).AssemblyQualifiedName
|
|
},
|
|
|
|
{
|
|
"#User",
|
|
typeof(User).AssemblyQualifiedName
|
|
},
|
|
|
|
{
|
|
"#TimeStamp",
|
|
typeof(System.DateTime).AssemblyQualifiedName
|
|
},
|
|
|
|
{
|
|
"#AttachmentType",
|
|
typeof(DocumentTemplate).AssemblyQualifiedName
|
|
},
|
|
|
|
{
|
|
"#State",
|
|
typeof(DocumentState).AssemblyQualifiedName
|
|
}
|
|
};
|
|
}
|
|
public static Dictionary<string, string> ExtensionLibraryTypes()
|
|
{
|
|
return new Dictionary<string, string>
|
|
{
|
|
{
|
|
"DataExt",
|
|
typeof(Extensions.DataExt).AssemblyQualifiedName
|
|
},
|
|
|
|
{
|
|
"DeviceExt",
|
|
typeof(Extensions.DeviceExt).AssemblyQualifiedName
|
|
},
|
|
|
|
{
|
|
"ImageExt",
|
|
typeof(Extensions.ImageExt).AssemblyQualifiedName
|
|
},
|
|
|
|
{
|
|
"UserExt",
|
|
typeof(Extensions.UserExt).AssemblyQualifiedName
|
|
}
|
|
};
|
|
}
|
|
|
|
}
|
|
}
|