示例#1
0
        // public InfoPlusUser workflowOperator { get; set; }
        // public DateTime ? operateTime { get; set; }

        /// <summary>
        /// Convert InfoPlusEvent FormData to strongly-typed entity
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="e"></param>
        /// <returns></returns>
        public static T Convert <T>(InfoPlusEvent e)
        {
            if (null == e)
            {
                return(default(T));
            }

            // 1. FormData
            T o = InfoPlusEntity.Convert <T>(e.FormData, e.Fields, false);

            // 2.InfoPlusEntity Related
            InfoPlusEntity en = o as InfoPlusEntity;

            if (null != en && null != e.Step)
            {
                // RenderUri
                try { en.RenderUri = e.Step.RenderUri; }
                catch (Exception) { }

                // Instance
                if (null != e.Step.Instance)
                {
                    en.InstanceId = e.Step.Instance.InstanceId;
                    en.BusinessId = e.Step.Instance.BusinessId;
                    if (null != e.Step.Instance.Creator)
                    {
                        en.InstanceOwner = e.Step.Instance.Creator.Account;
                    }
                }
            }
            return(o);
        }
示例#2
0
        static bool TryParse <T>(string s, out T o)
        {
            object x;
            var    result = InfoPlusEntity.TryParse(s, out x, typeof(T));

            o = (T)x;
            return(result);
        }
示例#3
0
        /// <summary>
        /// Convert data recursively, from weakly-typed(transfer presentation map) to strongly-typed entity.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data"></param>
        /// <param name="fields"></param>
        /// <param name="withIndex">true if data are from other sources including api. externData with set all EntityIndex to -1</param>
        /// <returns></returns>
        public static T Convert <T>(IDictionary <string, object> data, IList <FormField> fields, bool external)
        {
            if (null == data)
            {
                return(default(T));
            }
            Type   type = typeof(T);
            object x    = default(T);

            return((T)InfoPlusEntity.Convert(data, fields, ref x, 0, type, 0, string.Empty, external));
        }
示例#4
0
        public TSplitEntity LocateSplitObject <TSplitEntity>(InfoPlusEntity entity) where TSplitEntity : class
        {
            string splitIdentifier = this.Step.SplitIdentifier;

            string[] paths = splitIdentifier.Split(new char[] { ',' }, StringSplitOptions.None);
            if (paths.Length == 1 || string.IsNullOrEmpty(paths[2]))
            {
                return(entity as TSplitEntity);
            }
            return(InfoPlusEntity.Locate <TSplitEntity>(entity, paths[2]));
        }
示例#5
0
        /// <summary>
        /// Convert strong-typed entity to map presentation for transfer
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="o"></param>
        /// <param name="fields"></param>
        /// <returns></returns>
        public static IDictionary <string, object> Convert <T>(T o, IList <FormField> fields)
        {
            IDictionary <string, object> data = null;

            if (null == fields)
            {
                return(data);
            }
            int min = fields.Select(f => InfoPlusEntity.CalculateGroupDepth(f.GroupName)).Min();
            var g0  = fields.Where(f => InfoPlusEntity.CalculateGroupDepth(f.GroupName) == min)
                      .Select(f => f.GroupName).First();

            InfoPlusEntity.Convert(o, fields, g0, null, 0, ref data);
            return(data);
        }
示例#6
0
        // where, can be found in this.Step.RenderUri.

        public TChangedEntity LocateChangedObject <TChangedEntity>(InfoPlusEntity entity) where TChangedEntity : class
        {
            FormField eventField = this.EventField;

            string[] objNames;

            if (eventField == null)
            {
                if (this.Group == null)
                {
                    return(default(TChangedEntity));
                }
                FormField fakeField = new FormField {
                    GroupName = this.Group
                };
                objNames = fakeField.GroupObjectNames;
            }
            else
            {
                objNames = eventField.GroupObjectNames;
            }
            if (entity is TChangedEntity)
            {
                return(entity as TChangedEntity);
            }


            string[] paths  = this.FieldPath.Split('_');
            int      i      = 1;
            Object   result = entity;

            foreach (var objName in objNames)
            {
                Type         type     = result.GetType();
                PropertyInfo property = type.GetProperty(objName);
                result = ((IList)property.GetValue(result, null))[int.Parse(paths[i++])];
                if (result is TChangedEntity)
                {
                    return((TChangedEntity)result);
                }
            }

            return(default(TChangedEntity));
        }
示例#7
0
        /// <summary>
        /// Assign key, key_Name & key_Attr
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val"></param>
        /// <param name="data"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        static bool FormDataAssign(string key, object val, IDictionary <string, object> data, string path)
        {
            if (string.IsNullOrEmpty(key) || null == data)
            {
                return(false);
            }

            string[] splits = null;

            if (false == string.IsNullOrEmpty(path))
            {
                splits = path.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
            }

            string name;
            string attr;

            val = InfoPlusEntity.DecodeValue(val, out name, out attr);
            // Save name too.
            if (null != name)
            {
                FormDataAssign(key + FIELD_SUFFIX_NAME, name, data, path);
            }
            if (null != attr)
            {
                FormDataAssign(key + FIELD_SUFFIX_ATTR, attr, data, path);
            }


            if (null == splits || 0 == splits.Length)
            {
                data[key] = val;
                return(true);
            }

            try
            {
                int      index = int.Parse(splits[0]);
                object[] o     = null;
                if (false == data.ContainsKey(key))
                {
                    o = new object[index + 1];
                    data.Add(key, o);
                }
                else
                {
                    o = data[key] as object[];
                    if (null == o)
                    {
                        data[key] = new object[index + 1];
                        o         = data[key] as object[];
                    }
                    else if (o.Length <= index)
                    {
                        var x = new object[index + 1];
                        for (int i = 0; i < o.Length; i++)
                        {
                            x[i] = o[i];
                        }
                        data[key] = x;
                        o         = x;
                    }
                }

                object[] a    = o;
                int      prev = index;
                int      next = index;
                for (int i = 0; i < splits.Length - 1; i++)
                {
                    prev = int.Parse(splits[i]);
                    next = int.Parse(splits[i + 1]);

                    a = o[prev] as object[];
                    if (null == a)
                    {
                        o[prev] = new object[next + 1];
                        a       = o[prev] as object[];
                    }
                    else if (a.Length <= next)
                    {
                        var x = new object[next + 1];
                        for (int j = 0; j < a.Length; j++)
                        {
                            x[j] = a[j];
                        }
                        o[prev] = x;
                        a       = x;
                    }
                    // move pointer to next.
                    o = a;
                }

                o[next] = val;
                return(true);
            }
            catch (Exception)
            {
                return(false);
            }
        }
示例#8
0
        static void Convert(object o, IList <FormField> fields, string groupPath, string dataPath, int depth, ref IDictionary <string, object> data)
        {
            if (null == o)
            {
                return;
            }
            if (null == dataPath)
            {
                dataPath = string.Empty;
            }
            Type type = o.GetType();

            if (null == data)
            {
                data = new Dictionary <string, object>();
            }

            // current level, read property directly.
            // should always be equal, Only, except the initial call.
            string[] groups = groupPath.Split(new string[] { "//" }, StringSplitOptions.RemoveEmptyEntries);
            if (groups.Length > depth + 1)
            {
                string       gn       = InfoPlusEntity.ParseGroupName(groups[depth + 1]);
                PropertyInfo property = type.GetProperty(gn);
                if (null == property)
                {
                    return;
                }
                object deeps = property.GetValue(o, null);
                Array  arr   = InfoPlusEntity.ObjectToArray(deeps);
                if (null == arr)
                {
                    return;
                }
                for (int n = 0; n < arr.Length; n++)
                {
                    object deep = arr.GetValue(n);
                    InfoPlusEntity.Convert(deep, fields, groupPath, dataPath + "/" + n, depth + 1, ref data);
                }
            }
            else
            {
                var currentFields = fields.Where(f => f.GroupName == groupPath);
                foreach (FormField field in currentFields)
                {
                    string propertyName, fieldName;
                    InfoPlusEntity.ParsePropertyName(field.Name, out propertyName, out fieldName);
                    PropertyInfo property = type.GetProperty(propertyName);
                    if (null == property)
                    {
                        continue;
                    }

                    object val = property.GetValue(o, null);
                    InfoPlusEntity.FormDataAssign(fieldName, val, data, dataPath);
                }

                var deepers = from f in fields
                              where InfoPlusEntity.CalculateGroupDepth(f.GroupName) > depth && f.GroupName.Contains(groupPath)
                              select f;

                if (deepers.Count() > 0)
                {
                    int min        = deepers.Select(f => InfoPlusEntity.CalculateGroupDepth(f.GroupName)).Min();
                    var groupNames = deepers.Where(f => InfoPlusEntity.CalculateGroupDepth(f.GroupName) == min)
                                     .Select(f => f.GroupName).Distinct().ToList();

                    foreach (string groupName in groupNames)
                    {
                        string[] gns = groupName.Split(new string[] { "//" }, StringSplitOptions.RemoveEmptyEntries);

                        if (depth < gns.Length - 1)
                        {
                            string       gn       = InfoPlusEntity.ParseGroupName(gns[depth + 1]);
                            PropertyInfo property = type.GetProperty(gn);
                            if (null == property)
                            {
                                continue;
                            }
                            object deeps = property.GetValue(o, null);
                            Array  arr   = InfoPlusEntity.ObjectToArray(deeps);
                            if (null == arr)
                            {
                                continue;
                            }
                            // assign inner field to array in case of empty.
                            if (0 == arr.Length)
                            {
                                var groupFields = deepers.Where(f => f.GroupName == groupName);
                                foreach (var field in groupFields)
                                {
                                    InfoPlusEntity.FormDataAssign(field.Name, new Array[0], data, dataPath);
                                }
                            }

                            for (int n = 0; n < arr.Length; n++)
                            {
                                object deep = arr.GetValue(n);
                                InfoPlusEntity.Convert(deep, fields, groupName, dataPath + "/" + n, depth + 1, ref data);
                            }
                        }
                    }
                }
            }
        }
示例#9
0
        static bool TryParse(string s, out object o, Type type)
        {
            o = InfoPlusEntity.GetDefaultValue(type);
            try
            {
                if (type == typeof(string))
                {
                    o = s;
                    return(true);
                }

                if (type.IsPrimitive || type == typeof(decimal) || type == typeof(decimal))
                {
                    object[] args   = new object[] { s, o };
                    bool     result = (bool)type.InvokeMember("TryParse",
                                                              BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static,
                                                              null, null, args);
                    o = args[1];
                    // try parse int/long as double
                    if (false == result && (type == typeof(int) || type == typeof(long)))
                    {
                        double d;
                        result = double.TryParse(s, out d);
                        if (true == result)
                        {
                            // NOTE: don't use type == int ? (int)d : (long)d; its wrong. by marstone, 2014/03/04
                            if (type == typeof(int))
                            {
                                o = (int)d;
                            }
                            else
                            {
                                o = (long)d;
                            }
                        }
                    }
                    return(result);
                }
                else if (type == typeof(DateTime))
                {
                    long timestamp;
                    if (false == long.TryParse(s, out timestamp))
                    {
                        timestamp = (long)double.Parse(s);
                    }
                    o = UnixTime.ToDateTime(timestamp);
                    return(true);
                }
                else if (type.IsGenericType && false == type.IsGenericTypeDefinition)
                {
                    var generic = type.GetGenericTypeDefinition();
                    if (generic == typeof(Nullable <>))
                    {
                        if (s == null)
                        {
                            o = null;
                            return(true);
                        }
                        return(InfoPlusEntity.TryParse(s, out o, type.GetGenericArguments()[0]));
                    }
                }
                return(false);
            }
            catch (Exception) { return(false); }
        }
示例#10
0
        static void SetValue(object o, string key, object val)
        {
            if (null == o || string.IsNullOrEmpty(key))
            {
                return;
            }
            string fieldName, propertyName;
            bool   isName = InfoPlusEntity.ParsePropertyName(key, out propertyName, out fieldName);

            // get right property
            PropertyInfo property = o.GetType().GetProperty(propertyName);

            if (null == property || false == property.CanWrite)
            {
                return;
            }

            var    v      = val;
            Type   expect = property.PropertyType;
            string s      = null == v ? string.Empty : v.ToString();

            if (expect == typeof(CodeItem) || expect == typeof(InfoPlusUser))
            {
                if (null == val || val.GetType() == typeof(string))
                {
                    object code = property.GetValue(o, null);
                    if (null == code)
                    {
                        code = Activator.CreateInstance(expect);
                        property.SetValue(o, code, null);
                    }
                    string propertyNameOfProperty = isName ?
                                                    ((expect == typeof(CodeItem)) ? "CodeName" : "TrueName") :
                                                    ((expect == typeof(CodeItem)) ? "CodeId" : "Account");

                    PropertyInfo propertyOfProperty = expect.GetProperty(propertyNameOfProperty);
                    propertyOfProperty.SetValue(code, val, null);
                }
            }
            else if (!isName)    // bypass _Name for atom types
            {
                if (null != val)
                {
                    Type actual = val.GetType();
                    if (false == expect.Equals(actual))
                    {
                        object parsed;
                        bool   result = InfoPlusEntity.TryParse(s, out parsed, expect);
                        if (true == result)
                        {
                            v = parsed;
                        }
                        else
                        {
                            return;
                        }
                    }
                }
                // null val for value type? just do nothing.
                else if (true == expect.IsValueType)
                {
                    return;
                }
                property.SetValue(o, v, null);
            }
        }
示例#11
0
        static object Convert(IDictionary <string, object> data, IList <FormField> fields, ref object o, int depth, Type type, int index, string path, bool external)
        {
            depth++;
            // not created before? create it.
            if (null == o)
            {
                o = Activator.CreateInstance(type);
                var propIndex = type.GetProperty("EntityIndex");
                if (null != propIndex && propIndex.PropertyType == typeof(int))
                {
                    propIndex.SetValue(o, (external ? -1 : index), null);
                }
                var propPath = type.GetProperty("EntityPath");
                if (null != propPath && propPath.PropertyType == typeof(string))
                {
                    propPath.SetValue(o, path, null);
                }

                /*
                 * var fieldIndex = type.GetField("EntityIndex");
                 * if (null != fieldIndex && fieldIndex.FieldType == typeof (int))
                 * {
                 *  fieldIndex.SetValue(o, index);
                 * }
                 */
            }

            if (null == o)
            {
                throw new Exception("Activator.CreateInstance<T> failed. where T is " + type.FullName);
            }

            foreach (string key in data.Keys)
            {
                string property;
                string fieldName;
                bool   isName = InfoPlusEntity.ParsePropertyName(key, out property, out fieldName);

                object val = data[key];
                Array  arr = InfoPlusEntity.ObjectToArray(val);
                // Primitive.
                if (null == arr)
                {
                    InfoPlusEntity.SetValue(o, property, val);
                }
                else
                {
                    // If key is "_Name", find the origal fieldName and resize the Array
                    Array a0 = null;
                    if (isName)
                    {
                        if (false == data.ContainsKey(fieldName))
                        {
                            arr = new object[0];
                        }
                        else
                        {
                            object v0 = data[fieldName];
                            a0 = InfoPlusEntity.ObjectToArray(v0);
                            if (null == a0 || 0 == a0.Length)
                            {
                                arr = new object[0];
                            }
                            else if (a0.Length < arr.Length)
                            {
                                arr = arr.Cast <object>().Take(a0.Length).ToArray();
                            }
                        }
                    }

                    string groupName = null;
                    if (null != fields)
                    {
                        var field = (from f in fields where f.Name == fieldName select f).FirstOrDefault();
                        if (null != field)
                        {
                            string[] groupNames = field.GroupName.Split(new string[] { "//" },
                                                                        StringSplitOptions.RemoveEmptyEntries);
                            // valid?
                            if (groupNames.Length <= depth)
                            {
                                continue;
                            }

                            groupName = groupNames[depth];
                            groupName = ParseGroupName(groupName);
                        }
                    }
                    // groupName found, try to find/create property as an array.
                    if (null != groupName)
                    {
                        PropertyInfo group = type.GetProperty(groupName);
                        if (null == group)
                        {
                            continue;
                        }
                        Type groupType = group.PropertyType;
                        if (InfoPlusEntity.IsArray(groupType))
                        {
                            // get element type
                            Type elementType = groupType.IsGenericType ?
                                               groupType.GetGenericArguments()[0] : groupType.GetElementType();

                            for (int i = 0; i < arr.Length; i++)
                            {
                                object groupObject = group.GetValue(o, null);
                                // 1. Create
                                if (null == groupObject)
                                {
                                    // Create one.
                                    if (groupType.IsArray)
                                    {
                                        groupType   = elementType.MakeArrayType();
                                        groupObject = Activator.CreateInstance(groupType, arr.Length);
                                    }
                                    else
                                    {
                                        // Generic Interface
                                        if (true == groupType.IsInterface)
                                        {
                                            groupType = typeof(List <>).MakeGenericType(elementType);
                                        }
                                        groupObject = Activator.CreateInstance(groupType);
                                    }
                                    group.SetValue(o, groupObject, null);
                                }
                                // 2.Resize
                                if (groupType.IsArray)
                                {
                                    var groupArray = ((Array)groupObject);
                                    int oldLength  = groupArray.Length;
                                    // Resize & Clone
                                    if (oldLength < arr.Length)
                                    {
                                        MethodInfo method  = typeof(Array).GetMethod("Resize");
                                        MethodInfo generic = method.MakeGenericMethod(elementType);
                                        object[]   args    = new object[] { groupObject, arr.Length };
                                        generic.Invoke(null, args);
                                        for (int n = 0; n < oldLength; n++)
                                        {
                                            ((Array)args[0]).SetValue(groupArray.GetValue(n), n);
                                        }
                                        groupObject = args[0];
                                        group.SetValue(o, groupObject, null);
                                    }
                                }

                                groupObject = group.GetValue(o, null);
                                groupType   = groupObject.GetType();


                                Array  ga            = InfoPlusEntity.ObjectToArray(groupObject);
                                object elementObject = null;
                                // Load
                                if (i < ga.Length)
                                {
                                    elementObject = ga.GetValue(i);
                                }

                                IDictionary <string, object> d = new Dictionary <string, object>();
                                d.Add(key, arr.GetValue(i));
                                if (isName && null != a0)
                                {
                                    d.Add(fieldName, a0.GetValue(i));
                                }
                                string nextPath = path + "_" + i;
                                InfoPlusEntity.Convert(d, fields, ref elementObject, depth, elementType, i, nextPath, external);

                                // Save
                                if (groupType.IsArray)
                                {
                                    ((Array)groupObject).SetValue(elementObject, i);
                                }
                                else if (i >= ga.Length)
                                {
                                    groupType.InvokeMember("Add",
                                                           BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,
                                                           null, groupObject, new object[] { elementObject });
                                }
                            }
                        }
                    }
                }
            }
            return(o);
        }