Beispiel #1
0
        private static object?ParseInternal(Type type, string?value, ICustomPropertyConfigurationProvider propertyConfigurator)
        {
            var configuration = propertyConfigurator.TryGetConfiguration(type);
            var parsedObject  = ObjectParser.Parse(configuration?.ResolvedType ?? type, value);

            return(configuration == null ? parsedObject : configuration.ApiToStored(parsedObject));
        }
 public SchemaRegistryProvider(ISchemaConfiguration[] schemaConfigurations, ICustomPropertyConfigurationProvider customPropertyConfigurationProvider)
 {
     schemaRegistry = new SchemaRegistry();
     foreach (var schemaConfiguration in schemaConfigurations.OrderBy(x => x.Description.SchemaName))
     {
         schemaRegistry.Add(schemaConfiguration.GetSchema(customPropertyConfigurationProvider));
     }
 }
        private static Property ResolveProperty(object @object, PropertyInfo propertyInfo, IPropertyDescriptionBuilder propertyDescriptionBuilder,
                                                ICustomPropertyConfigurationProvider customPropertyConfigurationProvider)
        {
            var configuration = @object == null
                                    ? customPropertyConfigurationProvider?.TryGetConfiguration(propertyInfo)
                                    : customPropertyConfigurationProvider?.TryGetConfiguration(@object, propertyInfo);

            var typeInfo = ResolveType(null, configuration?.ResolvedType ?? propertyInfo.PropertyType,
                                       propertyDescriptionBuilder, customPropertyConfigurationProvider);

            return(new Property
            {
                TypeInfo = typeInfo,
                Description = propertyDescriptionBuilder.Build(propertyInfo, configuration?.ResolvedType ?? propertyInfo.PropertyType),
            });
        }
Beispiel #4
0
        public static void BuildGettersForProperties(Type type, string currentName, Func<object?, object?> currentGetter,
                                                     List<string> properties, List<Func<object?, object?>> getters,
                                                     ICustomPropertyConfigurationProvider propertyConfigurationProvider,
                                                     Type[]? usedTypes = null)
        {
            usedTypes = (usedTypes ?? new Type[0]).ToArray();
            if (usedTypes.Contains(type) || typeof(IEnumerable).IsAssignableFrom(type))
            {
                properties.Add(currentName);
                getters.Add(currentGetter);
                return;
            }

            usedTypes = usedTypes.Concat(new[] {type}).ToArray();
            foreach (var propertyInfo in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                var propertyConfiguration = propertyConfigurationProvider.TryGetConfiguration(propertyInfo);
                var propertyType = propertyConfiguration?.ResolvedType ?? propertyInfo.PropertyType;
                var propertyName = propertyInfo.Name;
                var propertyGetter = propertyInfo.GetGetMethod();

                var name = string.IsNullOrEmpty(currentName) ? propertyName : $"{currentName}.{propertyName}";
                Func<object?, object?> getter = x =>
                    {
                        var o = currentGetter(x);
                        if (o == null)
                            return null;

                        var propertyValue = propertyGetter.Invoke(o, new object[0]);
                        return propertyConfiguration == null ? propertyValue : propertyConfiguration.StoredToApi(propertyValue);
                    };

                if (IsSimpleType(propertyType))
                {
                    properties.Add(name);
                    getters.Add(getter);
                    continue;
                }

                BuildGettersForProperties(propertyType, name, getter, properties, getters, propertyConfigurationProvider, usedTypes);
            }
        }
Beispiel #5
0
        private static TypeMetaInformation BuildTypeMetaInformation(object @object, [NotNull] Type type, IPropertyDescriptionBuilder propertyDescriptionBuilder,
                                                                    ICustomPropertyConfigurationProvider propertyConfigurationProvider,
                                                                    [CanBeNull][ItemNotNull] Type[] usedTypes = null)
        {
            usedTypes = (usedTypes ?? new Type[0]).ToArray();
            if (usedTypes.Contains(type))
            {
                return(null);
            }
            usedTypes = usedTypes.Concat(new[] { type }).ToArray();
            if (type.IsArray || type.HasElementType)
            {
                return(new TypeMetaInformation
                {
                    TypeName = type.Name,
                    IsArray = true,
                    ItemType = BuildTypeMetaInformation(type.GetElementType(), propertyDescriptionBuilder, propertyConfigurationProvider, usedTypes),
                });
            }

            if (type.IsGenericType)
            {
                return(new TypeMetaInformation
                {
                    TypeName = new Regex(@"`.*").Replace(type.GetGenericTypeDefinition().Name, ""),
                    IsArray = true,
                    GenericTypeArguments = type.GetGenericArguments()
                                           .Select(x => BuildTypeMetaInformation(x, propertyDescriptionBuilder, propertyConfigurationProvider, usedTypes))
                                           .ToArray(),
                });
            }

            return(new TypeMetaInformation
            {
                TypeName = type.Name,
                Properties = IsSimpleType(type)
                                     ? null
                                     : type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                             .Select(x => BuildPropertyInfo(@object, x, propertyDescriptionBuilder, propertyConfigurationProvider, usedTypes))
                             .ToArray(),
            });
        }
Beispiel #6
0
        private static PropertyMetaInformation BuildPropertyInfo(object @object, [NotNull] PropertyInfo propertyInfo,
                                                                 IPropertyDescriptionBuilder propertyDescriptionBuilder,
                                                                 ICustomPropertyConfigurationProvider propertyConfigurationProvider,
                                                                 [NotNull, ItemNotNull] Type[] types)
        {
            var customConfiguration = @object == null
                                          ? propertyConfigurationProvider.TryGetConfiguration(propertyInfo)
                                          : propertyConfigurationProvider.TryGetConfiguration(@object, propertyInfo);

            var propertyType        = customConfiguration?.ResolvedType ?? propertyInfo.PropertyType;
            var propertyDescription = propertyDescriptionBuilder.Build(propertyInfo, propertyType);

            return(new PropertyMetaInformation
            {
                Name = propertyInfo.Name,
                AvailableFilters = propertyDescription.AvailableFilters,
                IsIdentity = propertyDescription.IsIdentity,
                IsRequired = propertyDescription.IsRequired,
                IsSearchable = propertyDescription.IsSearchable,
                IsSortable = propertyDescription.IsSortable,
                Type = BuildTypeMetaInformation(propertyType, propertyDescriptionBuilder, propertyConfigurationProvider, types),
            });
        }
Beispiel #7
0
        public static object StoredToApi(TypeInfo typeInfo, Type type, object o, ICustomPropertyConfigurationProvider customPropertyConfigurationProvider)
        {
            if (o == null)
            {
                return(null);
            }
            if (!(typeInfo is ClassTypeInfo classTypeInfo))
            {
                return(o);
            }

            var result = new Dictionary <string, object>();

            foreach (var property in classTypeInfo.Properties)
            {
                var propertyInfo  = type.GetProperty(property.Description.Name);
                var propertyValue = propertyInfo.GetValue(o);
                var customPropertyConfiguration = customPropertyConfigurationProvider?.TryGetConfiguration(o, propertyInfo);
                if (customPropertyConfiguration != null)
                {
                    result[property.Description.Name] = StoredToApi(property.TypeInfo,
                                                                    customPropertyConfiguration.ResolvedType,
                                                                    customPropertyConfiguration.StoredToApi(propertyValue),
                                                                    customPropertyConfigurationProvider);
                }
                else
                {
                    result[property.Description.Name] = StoredToApi(property.TypeInfo,
                                                                    propertyInfo.PropertyType,
                                                                    propertyValue,
                                                                    customPropertyConfigurationProvider);
                }
            }

            return(result);
        }
Beispiel #8
0
        public static object ApiToStored(TypeInfo typeInfo, Type type, object o, ICustomPropertyConfigurationProvider customPropertyConfigurationProvider)
        {
            var jObject = (JToken)o;

            if (jObject == null || jObject.ToString() == "")
            {
                return(null);
            }
            if (!(typeInfo is ClassTypeInfo classTypeInfo))
            {
                return(jObject.ToObject(type));
            }

            var result = Activator.CreateInstance(type);

            foreach (var property in classTypeInfo.Properties)
            {
                var propertyInfo = type.GetProperty(property.Description.Name);
                var customPropertyConfiguration = customPropertyConfigurationProvider?.TryGetConfiguration(o, propertyInfo);
                var value = ApiToStored(property.TypeInfo,
                                        customPropertyConfiguration?.ResolvedType ?? propertyInfo.PropertyType,
                                        jObject.SelectToken(property.Description.Name),
                                        customPropertyConfigurationProvider);
                if (customPropertyConfiguration != null)
                {
                    value = customPropertyConfiguration.ApiToStored(value);
                }

                if (propertyInfo.SetMethod != null)
                {
                    propertyInfo.SetValue(result, value);
                }
            }

            return(result);
        }
        private static TypeInfo ResolveType(object @object, Type type, IPropertyDescriptionBuilder propertyDescriptionBuilder,
                                            ICustomPropertyConfigurationProvider customPropertyConfigurationProvider)
        {
            var realType  = Nullable.GetUnderlyingType(type) ?? type;
            var canBeNull = Nullable.GetUnderlyingType(type) != null;

            if (realType == typeof(string) || realType == typeof(Guid))
            {
                return(new StringTypeInfo());
            }
            if (realType == typeof(char))
            {
                return(new CharTypeInfo(canBeNull));
            }
            if (realType == typeof(byte))
            {
                return(new ByteTypeInfo(canBeNull));
            }
            if (realType == typeof(sbyte))
            {
                return(new SByteTypeInfo(canBeNull));
            }
            if (realType == typeof(int))
            {
                return(new IntTypeInfo(canBeNull));
            }
            if (realType == typeof(DateTime) || realType == typeof(DateTimeOffset))
            {
                return(new DateTimeTypeInfo(canBeNull));
            }
            if (realType == typeof(long))
            {
                return(new LongTypeInfo(canBeNull));
            }
            if (realType == typeof(short))
            {
                return(new ShortTypeInfo(canBeNull));
            }
            if (realType == typeof(bool))
            {
                return(new BoolTypeInfo(canBeNull));
            }
            if (realType == typeof(byte[]))
            {
                return(new ByteArrayTypeInfo());
            }
            if (realType == typeof(decimal) || realType == typeof(double))
            {
                return(new DecimalTypeInfo(canBeNull));
            }
            if (realType.IsEnum)
            {
                return(new EnumTypeInfo(canBeNull, Enum.GetNames(realType)));
            }
            if (realType.IsArray)
            {
                return(new EnumerableTypeInfo(ResolveType(null, realType.GetElementType(), propertyDescriptionBuilder, customPropertyConfigurationProvider)));
            }
            if (realType.IsGenericType && realType.GetGenericTypeDefinition() == typeof(List <>))
            {
                return(new EnumerableTypeInfo(ResolveType(null, realType.GetGenericArguments()[0], propertyDescriptionBuilder, customPropertyConfigurationProvider)));
            }
            if (realType.IsGenericType && realType.GetGenericTypeDefinition() == typeof(Dictionary <,>))
            {
                return(new DictionaryTypeInfo(
                           ResolveType(null, realType.GetGenericArguments()[0], propertyDescriptionBuilder, customPropertyConfigurationProvider),
                           ResolveType(null, realType.GetGenericArguments()[1], propertyDescriptionBuilder, customPropertyConfigurationProvider)));
            }
            if (realType.IsGenericType && realType.GetGenericTypeDefinition() == typeof(HashSet <>))
            {
                return(new HashSetTypeInfo(ResolveType(null, realType.GetGenericArguments()[0], propertyDescriptionBuilder, customPropertyConfigurationProvider)));
            }
            if (realType.IsClass)
            {
                return new ClassTypeInfo
                       {
                           Properties = realType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                                        .Select(p => ResolveProperty(@object, p, propertyDescriptionBuilder, customPropertyConfigurationProvider))
                                        .ToArray(),
                       }
            }
            ;

            throw new NotSupportedException($"{type.FullName} не поддерживается");
        }
Beispiel #10
0
 public static TypeInfo Extract(object @object, Type type, IPropertyDescriptionBuilder propertyDescriptionBuilder,
                                ICustomPropertyConfigurationProvider customPropertyConfigurationProvider)
 {
     return(ResolveType(@object, type, propertyDescriptionBuilder, customPropertyConfigurationProvider));
 }
Beispiel #11
0
 public static TypeInfo Extract(Type type, IPropertyDescriptionBuilder propertyDescriptionBuilder,
                                ICustomPropertyConfigurationProvider customPropertyConfigurationProvider)
 {
     return(typeInfos.GetOrAdd(type, t => ResolveType(null, t, propertyDescriptionBuilder, customPropertyConfigurationProvider)));
 }
Beispiel #12
0
        public DownloadFileStream(Type type, object?[] objects, string[] excludedFields, ICustomPropertyConfigurationProvider customPropertyConfigurationProvider, int downloadLimit)
        {
            var properties = new List <string>();
            var getters    = new List <Func <object?, object?> >();

            PropertyHelpers.BuildGettersForProperties(type, "", x => x, properties, getters, customPropertyConfigurationProvider);

            var excludedIndices = properties.Select((x, i) => (x, i)).Where(x => excludedFields.Contains(x.x)).Select(x => x.i).ToArray();

            formatter = new CsvFormatter(
                objects,
                properties.Where((x, i) => !excludedIndices.Contains(i)).ToArray(),
                getters.Where((x, i) => !excludedIndices.Contains(i)).ToArray()
                );
        }
Beispiel #13
0
        public static object SetValue(object obj, string[] path, string?value, ICustomPropertyConfigurationProvider propertyConfigurator)
        {
            var objectType = obj.GetType();

            if (obj is IList list)
            {
                var type     = objectType.HasElementType ? objectType.GetElementType() : objectType.GetGenericArguments()[0];
                var index    = int.Parse(path[0]);
                var newValue = path.Length == 1
                                   ? ParseInternal(type, value, propertyConfigurator)
                                   : SetValue(list[index], path.Skip(1).ToArray(), value, propertyConfigurator);
                list[index] = newValue;
                return(obj);
            }

            if (obj is IDictionary dictionary)
            {
                var args     = objectType.GetGenericArguments();
                var key      = ParseInternal(args[0], path[0], propertyConfigurator);
                var newValue = path.Length == 1
                                   ? ParseInternal(args[1], value, propertyConfigurator)
                                   : SetValue(dictionary[key], path.Skip(1).ToArray(), value, propertyConfigurator);
                dictionary[key] = newValue;
                return(obj);
            }

            var property = objectType.GetProperty(path[0]);

            if (property == null)
            {
                throw new InvalidOperationException($"Expected type {objectType} to have property {path[0]}");
            }

            var propertyConfiguration = propertyConfigurator.TryGetConfiguration(obj, property);

            if (propertyConfiguration != null)
            {
                if (path.Length == 1)
                {
                    property.SetValue(obj, propertyConfiguration.ApiToStored(ObjectParser.Parse(propertyConfiguration.ResolvedType, value)));
                    return(obj);
                }

                var oldValue = propertyConfiguration.StoredToApi(property.GetValue(obj));
                if (oldValue == null)
                {
                    throw new InvalidOperationException($"Unable to set inner value for property {property.Name} of type {propertyConfiguration.ResolvedType}");
                }
                var intermediateValue = SetValue(oldValue, path.Skip(1).ToArray(), value, propertyConfigurator);
                var newValue          = propertyConfiguration.ApiToStored(intermediateValue);
                property.SetValue(obj, newValue);
                return(obj);
            }

            var newPropertyValue = path.Length == 1
                                       ? ObjectParser.Parse(property.PropertyType, value)
                                       : SetValue(property.GetValue(obj), path.Skip(1).ToArray(), value, propertyConfigurator);

            property.SetValue(obj, newPropertyValue);
            return(obj);
        }
        public static Schema GetSchema(this ISchemaConfiguration schemaConfiguration, ICustomPropertyConfigurationProvider customPropertyConfigurationProvider)
        {
            var description = schemaConfiguration.Description;

            if (description.CountLimit == 0)
            {
                description.CountLimit = 1000;
            }

            if (description.CountLimitForSuperUser == 0)
            {
                description.CountLimitForSuperUser = description.CountLimit;
            }

            if (description.DownloadLimit == 0)
            {
                description.DownloadLimit = 10000;
            }

            if (description.DownloadLimitForSuperUser == 0)
            {
                description.DownloadLimitForSuperUser = description.DownloadLimit;
            }

            return(new Schema
            {
                Description = description,
                Types = schemaConfiguration.Types,
                ConnectorsFactory = schemaConfiguration.ConnectorsFactory,
                CustomPropertyConfigurationProvider = customPropertyConfigurationProvider,
                PropertyDescriptionBuilder = schemaConfiguration.PropertyDescriptionBuilder,
            });
        }
Beispiel #15
0
 public static TypeMetaInformation BuildTypeMetaInformation([NotNull] Type type, IPropertyDescriptionBuilder propertyDescriptionBuilder,
                                                            ICustomPropertyConfigurationProvider propertyConfigurationProvider,
                                                            [CanBeNull][ItemNotNull] Type[] usedTypes = null)
 {
     return(BuildTypeMetaInformation(@object: null, type, propertyDescriptionBuilder, propertyConfigurationProvider, usedTypes));
 }