/// <summary> /// 计算表达式字典 /// </summary> /// <param name="strFuncName"></param> /// <param name="arrParams"></param> /// <param name="calcContext"></param> /// <returns></returns> private static object CalculateExpressionDictionary(string strFuncName, ParamObjectCollection arrParams, CalculateContext calcContext) { ExpressionDictionaryCollection dictionaries = (ExpressionDictionaryCollection)ObjectContextCache.Instance.GetOrAddNewValue( "ExpressionDictionaries", (cache, key) => { ExpressionDictionaryCollection expDicts = new ExpressionDictionaryCollection(); expDicts.InitFromConfiguration(ExpressionDictionarySettings.GetConfig()); cache.Add("ExpressionDictionaries", expDicts); return(expDicts); }); ExpressionDictionary dictionary = dictionaries[strFuncName]; object oValue = null; if (dictionary != null) { ExpressionDictionaryCalculatorContext context = new ExpressionDictionaryCalculatorContext(dictionary, calcContext.CallerContxt); string key = string.Empty; if (arrParams.Count > 0 && arrParams[0].Value != null) { key = arrParams[0].Value.ToString(); } oValue = dictionary.Calculator.Calculate(strFuncName, key, context); } return(oValue); }
private object[] PrepareParameters(IList <ParameterInfo> methodParams, ParamObjectCollection arrParams, object callerContext) { object[] result = new object[methodParams.Count]; for (int i = 0; i < arrParams.Count; i++) { ParameterInfo pi = methodParams[i]; try { result[i] = DataConverter.ChangeType(arrParams[i].Value, pi.ParameterType); } catch (System.Exception ex) { throw new InvalidCastException(string.Format("内置函数{0}参数{1}类型转换错误。{2}", this.FunctionName, pi.Name, ex.Message), ex); } } //如果方法的参数比表达式的参数多一个,则将调用上下文作为最后一个参数 if (result.Length == arrParams.Count + 1) { result[arrParams.Count] = callerContext; } return(result); }
/// <summary> /// 执行方法 /// </summary> /// <param name="target"></param> /// <param name="arrParams"></param> /// <param name="callerContext"></param> /// <returns></returns> public object ExecuteFunction(object target, ParamObjectCollection arrParams, object callerContext) { ParameterInfo[] methodParams = this.MethodInfo.GetParameters(); CheckParametersCount(methodParams, arrParams); return(this.MethodInfo.Invoke(target, PrepareParameters(methodParams, arrParams, callerContext))); }
/// <summary> /// 执行静态函数 /// </summary> /// <param name="funcName"></param> /// <param name="type"></param> /// <param name="arrParams"></param> /// <param name="callerContext"></param> /// <returns></returns> public static object ExecuteFunction(string funcName, Type type, ParamObjectCollection arrParams, object callerContext) { type.NullCheck("type"); BuiltInFunctionInfoCollection funcsInfo = GetBuiltInFunctionsInfo(type); object result = null; if (funcsInfo.Contains(funcName)) { result = funcsInfo[funcName].ExecuteFunction(null, arrParams, callerContext); } return(result); }
/// <summary> /// 执行函数 /// </summary> /// <param name="funcName"></param> /// <param name="target"></param> /// <param name="arrParams"></param> /// <param name="callerContext"></param> /// <returns></returns> public static object ExecuteFunction(string funcName, object target, ParamObjectCollection arrParams, object callerContext) { target.NullCheck("target"); BuiltInFunctionInfoCollection funcsInfo = GetBuiltInFunctionsInfo(target.GetType()); object result = null; if (funcsInfo.Contains(funcName)) { result = funcsInfo[funcName].ExecuteFunction(target, arrParams, callerContext); } return(result); }
public object GetUserFunctionValue(string strFuncName, ParamObjectCollection arrParams) { object oValue = null; if (this.CalculateUserFunction != null) { oValue = this.CalculateUserFunction(strFuncName, arrParams, this.CallerContxt); } else if (this.BuiltInFunctionsWrapper != null) { oValue = BuiltInFunctionHelper.ExecuteFunction(strFuncName, this.BuiltInFunctionsWrapper, arrParams, this.CallerContxt); } return(oValue); }
private static object DoDateDiff(ParamObjectCollection arrParams) { arrParams.CheckParamsLength(3); arrParams[0].CheckParameterType <string>(); arrParams[1].CheckParameterType <DateTime>(); arrParams[2].CheckParameterType <DateTime>(); DateTime startTime = (DateTime)arrParams[1].Value; DateTime endTime = (DateTime)arrParams[2].Value; TimeSpan ts = endTime - startTime; double result = 0; string intervalType = arrParams[0].Value.ToString().ToLower(); switch (intervalType) { case "d": result = ts.TotalDays; break; case "h": result = ts.TotalHours; break; case "n": result = ts.TotalMinutes; break; case "s": result = ts.TotalSeconds; break; case "ms": result = ts.TotalMilliseconds; break; default: throw new SystemSupportException(string.Format(ExpressionParserRes.InvalidDateDiffType, intervalType)); } return(Math.Ceiling(Convert.ToDecimal(result))); }
private static object DoInFunction(ParamObjectCollection arrParams, CalculateContext calcContext) { bool result = false; if (arrParams.Count > 0) { object sourceData = arrParams[0].Value; for (int i = 1; i < arrParams.Count; i++) { if ((bool)CompareEqualOP(sourceData, arrParams[i].Value, 0)) { result = true; break; } } } return(result); }
private object VExp(ExpTreeNode node, CalculateContext calcContext) { object oValue = null; if (node != null) { try { switch (node.OperationID) { case Operation_IDs.OI_NUMBER: case Operation_IDs.OI_STRING: case Operation_IDs.OI_NEG: case Operation_IDs.OI_BOOLEAN: case Operation_IDs.OI_DATETIME: oValue = node.Value; break; case Operation_IDs.OI_ADD: oValue = AddOP(VExp(node.Left, calcContext), VExp(node.Right, calcContext), node.Position); break; case Operation_IDs.OI_MINUS: { object p1 = VExp(node.Left, calcContext); object p2 = VExp(node.Right, calcContext); CheckOperandNull(p1, p2, node.Position); oValue = NToD(p1) - NToD(p2); } break; case Operation_IDs.OI_MUL: { object p1 = VExp(node.Left, calcContext); object p2 = VExp(node.Right, calcContext); CheckOperandNull(p1, p2, node.Position); oValue = NToD(p1) * NToD(p2); } break; case Operation_IDs.OI_DIV: { object p1 = VExp(node.Left, calcContext); object p2 = VExp(node.Right, calcContext); CheckOperandNull(p1, p2, node.Position); if (NToD(p2) == 0.0M) { throw ParsingException.NewParsingException(ParseError.peFloatOverflow, node.Position); } oValue = NToD(p1) / NToD(p2); } break; case Operation_IDs.OI_LOGICAL_OR: { oValue = (bool)VExp(node.Left, calcContext); object oRight = (bool)false; if ((bool)oValue == false) { oRight = VExp(node.Right, calcContext); } CheckOperandNull(oValue, oRight, node.Position); oValue = (bool)oValue || (bool)oRight; } break; case Operation_IDs.OI_LOGICAL_AND: { oValue = (bool)VExp(node.Left, calcContext); object oRight = (bool)true; if ((bool)oValue == true) { oRight = VExp(node.Right, calcContext); } CheckOperandNull(oValue, oRight, node.Position); oValue = (bool)oValue && (bool)oRight; } break; case Operation_IDs.OI_NOT: oValue = VExp(node.Right, calcContext); CheckOperandNull(oValue, node.Position); oValue = !(bool)oValue; break; case Operation_IDs.OI_GREAT: oValue = CompareGreatOP(VExp(node.Left, calcContext), VExp(node.Right, calcContext), node.Position); break; case Operation_IDs.OI_GREATEQUAL: oValue = CompareGreatEqualOP(VExp(node.Left, calcContext), VExp(node.Right, calcContext), node.Position); break; case Operation_IDs.OI_LESS: oValue = CompareLessOP(VExp(node.Left, calcContext), VExp(node.Right, calcContext), node.Position); break; case Operation_IDs.OI_LESSEQUAL: oValue = CompareLessEqualOP(VExp(node.Left, calcContext), VExp(node.Right, calcContext), node.Position); break; case Operation_IDs.OI_NOT_EQUAL: oValue = CompareNotEqualOP(VExp(node.Left, calcContext), VExp(node.Right, calcContext), node.Position); break; case Operation_IDs.OI_EQUAL: oValue = CompareEqualOP(VExp(node.Left, calcContext), VExp(node.Right, calcContext), node.Position); break; case Operation_IDs.OI_USERDEFINE: { oValue = CalculateFunction(node, node.Params, calcContext); if (oValue == null) { ParamObjectCollection funcParams = GetParams(node.Params, calcContext); oValue = CalculateFunctionWithParameters(node.FunctionName, funcParams, calcContext); if (oValue == null) { oValue = calcContext.GetUserFunctionValue(node.FunctionName, funcParams); } if (oValue == null) { oValue = CalculateExpressionDictionary(node.FunctionName, funcParams, calcContext); } } } break; default: throw ParsingException.NewParsingException( ParseError.peInvalidOperator, node.Position, EnumItemDescriptionAttribute.GetAttribute(node.OperationID).ShortName); } } catch (System.InvalidCastException) { throw ParsingException.NewParsingException(ParseError.peTypeMismatch, node.Position); } } return(oValue); }
/// <summary> /// 计算所有参数都已经准备好了的函数 /// </summary> /// <param name="strFuncName"></param> /// <param name="arrParams"></param> /// <param name="calcContext"></param> /// <returns></returns> private static object CalculateFunctionWithParameters(string strFuncName, ParamObjectCollection arrParams, CalculateContext calcContext) { object oValue = null; try { switch (strFuncName.ToLower()) { case "now": oValue = DateTime.Now; break; case "today": oValue = DateTime.Today; break; case "dateinterval.day": oValue = "d"; break; case "dateinterval.hour": oValue = "h"; break; case "dateinterval.minute": oValue = "n"; break; case "dateinterval.second": oValue = "s"; break; case "dateinterval.millisecond": oValue = "ms"; break; case "datediff": oValue = DoDateDiff(arrParams); break; case "mindate": oValue = DateTime.MinValue; break; case "maxdate": oValue = DateTime.MaxValue; break; //default: // { // if (calcContext.CalculateUserFunction != null) // oValue = calcContext.CalculateUserFunction(strFuncName, arrParams, calcContext.CallerContxt); // break; // } } return(oValue); } catch (ParsingException) { throw; } catch (System.Exception ex) { throw new SystemSupportException(string.Format(ExpressionParserRes.FunctionError, strFuncName, ex.Message)); } }
private static void CheckParametersCount(ParameterInfo[] methodParams, ParamObjectCollection arrParams) { (methodParams.Length == arrParams.Count || methodParams.Length == arrParams.Count + 1).FalseThrow <ArgumentOutOfRangeException>( "内置的表达式方法的参数是{0}个,而调用参数是{1}个,不匹配", methodParams.Length, arrParams.Count); }