2023-04-03 11:04:31 +08:00

178 lines
6.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace ThinkingAnalytics.Utils
{
public class TD_PropertiesChecker
{
private static readonly Regex keyPattern = new Regex(@"^[a-zA-Z][a-zA-Z\d_#]{0,49}$");
public static bool IsNumeric(object obj)
{
return obj is sbyte
|| obj is byte
|| obj is short
|| obj is ushort
|| obj is int
|| obj is uint
|| obj is long
|| obj is ulong
|| obj is double
|| obj is decimal
|| obj is float;
}
public static bool IsString(object obj)
{
if (obj == null)
return false;
return obj is string;
}
public static bool IsDictionary(object obj)
{
if (obj == null)
return false;
return (obj.GetType().IsGenericType && obj.GetType().GetGenericTypeDefinition() == typeof(Dictionary<,>));
}
public static bool IsList(object obj)
{
if (obj == null)
return false;
return (obj.GetType().IsGenericType && obj.GetType().GetGenericTypeDefinition() == typeof(List<>)) || obj is Array;
}
// 检测属性是否合法
public static bool CheckProperties<V>(Dictionary<string, V> properties)
{
if (properties == null)
{
return true;
}
foreach(KeyValuePair<string, V> kv in properties)
{
if (!CheckString(kv.Key))
{
return false;
}
if (!(kv.Value is string || kv.Value is DateTime || kv.Value is bool || IsNumeric(kv.Value) || IsList(kv.Value) || IsDictionary(kv.Value)))
{
TD_Log.w("TA.PropertiesChecker - property values must be one of: string, numberic, Boolean, DateTime, Array, Row");
return false;
}
if (IsString(kv.Value))
{
return CheckProperties(kv.Value as string);
}
if (IsNumeric(kv.Value)) {
double number = Convert.ToDouble(kv.Value);
return CheckProperties(number);
}
if (IsList(kv.Value)) {
return CheckProperties(kv.Value as List<object>);
}
if (IsDictionary(kv.Value))
{
return CheckProperties(kv.Value as Dictionary<string, object>);
}
}
return true;
}
// 检测属性是否合法 - Array(Row)
public static bool CheckProperties(List<object> properties)
{
if (properties == null)
{
return true;
}
foreach(object value in properties)
{
if (!(value is string || value is DateTime || value is bool || IsNumeric(value) || IsDictionary(value)))
{
TD_Log.w("TA.PropertiesChecker - property values in list must be one of: string, numberic, Boolean, DateTime, Row");
return false;
}
if (IsString(value))
{
return CheckProperties(value as string);
}
if (IsNumeric(value)) {
double number = Convert.ToDouble(value);
return CheckProperties(number);
}
if (IsDictionary(value))
{
return CheckProperties(value as Dictionary<string, object>);
}
}
return true;
}
// 检测属性是否合法 - Array
public static bool CheckProperties(List<string> properties)
{
if (properties == null)
{
return true;
}
foreach(string value in properties)
{
if (!CheckString(value))
{
return false;
}
}
return true;
}
// 检测属性是否合法 - String
public static bool CheckProperties(string properties)
{
if (properties is string && System.Text.Encoding.UTF8.GetBytes(Convert.ToString(properties)).Length > 2048) {
TD_Log.w("TA.PropertiesChecker - the string is too long: " + (string)(object)properties);
return false;
}
return true;
}
// 检测属性是否合法 - Number
public static bool CheckProperties(double properties)
{
if (properties > 9999999999999.999 || properties < -9999999999999.999)
{
TD_Log.w("TA.PropertiesChecker - number value is invalid: " + properties + ", 数据范围是-9E15至9E15小数点最多保留3位");
return false;
}
return true;
}
public static bool CheckString(string eventName)
{
if (string.IsNullOrEmpty(eventName))
{
TD_Log.w("TA.PropertiesChecker - the string is null");
return false;
}
if (keyPattern.IsMatch(eventName))
{
return true;
}
else
{
TD_Log.w("TA.PropertiesChecker - the string is invalid for TA: " + eventName + ", " + "事件名和属性名规则: 必须以字母开头只能包含数字字母忽略大小写和下划线“_”长度最大为50个字符。请注意配置时不要带有空格。");
return false;
}
}
public static void MergeProperties(Dictionary<string, object> source, Dictionary<string, object> dest)
{
if (null == source) return;
foreach (KeyValuePair<string, object> kv in source)
{
if (dest.ContainsKey(kv.Key))
{
dest[kv.Key] = kv.Value;
} else
{
dest.Add(kv.Key, kv.Value);
}
}
}
}
}