Example #1
0
        void CheckValueMatchesRegex(CfgMetadata metaData, string name, string value)
        {
            if (!metaData.Attribute.RegexIsSet || metaData.Regex == null)
            {
                return;
            }

            if (!metaData.Regex.IsMatch(value))
            {
                Events.ValueDoesNotMatchRegex(name, value, metaData.Attribute.regex);
            }
        }
Example #2
0
        void ValidateUniqueAndRequiredProperties(
            string parent,
            string listName,
            CfgMetadata listMetadata,
            ICollection list
            )
        {
            //if more than one then uniqueness comes into question
            if (list.Count > 1)
            {
                lock (Locker) {
                    if (listMetadata.UniquePropertiesInList == null)
                    {
                        listMetadata.UniquePropertiesInList = CfgMetadataCache.GetMetadata(listMetadata.ListType)
                                                              .Where(p => p.Value.Attribute.unique)
                                                              .Select(p => p.Key)
                                                              .ToArray();
                    }
                }

                if (listMetadata.UniquePropertiesInList.Length <= 0)
                {
                    return;
                }

                for (var j = 0; j < listMetadata.UniquePropertiesInList.Length; j++)
                {
                    var unique     = listMetadata.UniquePropertiesInList[j];
                    var duplicates = list
                                     .Cast <CfgNode>()
                                     .Where(n => n.UniqueProperties.ContainsKey(unique))
                                     .Select(n => n.UniqueProperties[unique])
                                     .GroupBy(n => n)
                                     .Where(group => @group.Count() > 1)
                                     .Select(group => @group.Key)
                                     .ToArray();

                    for (var l = 0; l < duplicates.Length; l++)
                    {
                        Events.DuplicateSet(unique, duplicates[l], listName);
                    }
                }
            }
            else if (list.Count == 0 && listMetadata.Attribute.required)
            {
                Events.MissingRequiredAdd(parent, listName);
            }
        }
Example #3
0
        internal static Dictionary <string, CfgMetadata> GetMetadata(Type type)
        {
            Dictionary <string, CfgMetadata> metadata;

            if (MetadataCache.TryGetValue(type, out metadata))
            {
                return(metadata);
            }

            lock (Locker) {
                NameCache[type] = new Dictionary <string, string>();

                var keyCache  = new List <string>();
                var listCache = new List <string>();

#if NETS
                var propertyInfos = type.GetRuntimeProperties().ToArray();
#else
                var propertyInfos = type.GetProperties();
#endif

                metadata = new Dictionary <string, CfgMetadata>(StringComparer.Ordinal);
                foreach (var propertyInfo in propertyInfos)
                {
                    if (!propertyInfo.CanRead)
                    {
                        continue;
                    }
                    if (!propertyInfo.CanWrite)
                    {
                        continue;
                    }

#if NETS
                    var attribute = (CfgAttribute)propertyInfo.GetCustomAttribute(typeof(CfgAttribute), true);
#else
                    var attribute = (CfgAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(CfgAttribute), true);
#endif

                    if (attribute == null)
                    {
                        continue;
                    }

                    var key  = NormalizeName(type, propertyInfo.Name);
                    var item = new CfgMetadata(propertyInfo, attribute)
                    {
                        TypeDefault = GetDefaultValue(propertyInfo.PropertyType)
                    };

                    // regex
                    try {
                        if (attribute.RegexIsSet)
                        {
#if NETS
                            item.Regex = attribute.ignoreCase ? new Regex(attribute.regex, RegexOptions.IgnoreCase) : new Regex(attribute.regex);
#else
                            item.Regex = attribute.ignoreCase ? new Regex(attribute.regex, RegexOptions.Compiled | RegexOptions.IgnoreCase) : new Regex(attribute.regex, RegexOptions.Compiled);
#endif
                        }
                    } catch (ArgumentException ex) {
                        item.Errors.Add(CfgEvents.InvalidRegex(key, attribute.regex, ex));
                    }

                    // check default value for type mismatch
                    if (attribute.ValueIsSet)
                    {
                        if (attribute.value.GetType() != propertyInfo.PropertyType)
                        {
                            var value = attribute.value;
                            if (TryConvertValue(ref value, propertyInfo.PropertyType))
                            {
                                attribute.value = value;
                            }
                            else
                            {
                                item.TypeMismatch = true;
                                item.Errors.Add(CfgEvents.TypeMismatch(key, value, propertyInfo.PropertyType));
                            }
                        }
                    }

                    // type safety for value, min value, and max value
                    var defaultValue = attribute.value;
                    if (ResolveType(() => attribute.ValueIsSet, ref defaultValue, key, item))
                    {
                        attribute.value = defaultValue;
                    }

                    var minValue = attribute.minValue;
                    if (ResolveType(() => attribute.MinValueSet, ref minValue, key, item))
                    {
                        attribute.minValue = minValue;
                    }

                    var maxValue = attribute.maxValue;
                    if (ResolveType(() => attribute.MaxValueSet, ref maxValue, key, item))
                    {
                        attribute.maxValue = maxValue;
                    }


                    //foreach (var cp in constructors) {
                    //    if (!cp.Any()) {
                    //        obj = item.ListActivator();
                    //        break;
                    //    }

                    //    if (cp.Count() == 1) {
                    //        if (cp.First().ParameterType == typeof(int)) {
                    //            obj = Activator.CreateInstance(item.ListType, add.Attributes.Count);
                    //            break;
                    //        }

                    //        if (cp.First().ParameterType == typeof(string[])) {
                    //            var names = add.Attributes.Select(a => a.Name).ToArray();
                    //            obj = Activator.CreateInstance(item.ListType, new object[] { names });
                    //            break;
                    //        }
                    //    }
                    //}

#if NETS
                    var propertyTypeInfo = propertyInfo.PropertyType.GetTypeInfo();
                    if (propertyTypeInfo.IsGenericType)
                    {
                        listCache.Add(key);
                        item.ListType = propertyTypeInfo.GenericTypeArguments[0];
                        var listTypeInfo = item.ListType.GetTypeInfo();
                        item.ImplementsProperties = typeof(IProperties).GetTypeInfo().IsAssignableFrom(listTypeInfo);
                        item.Constructors         = propertyTypeInfo.DeclaredConstructors.Select(c => c.GetParameters());
                        item.ListActivator        = () => Activator.CreateInstance(propertyInfo.PropertyType);
                        if (listTypeInfo.IsSubclassOf(typeof(CfgNode)))
                        {
                            item.Loader = () => (CfgNode)Activator.CreateInstance(item.ListType);
                        }
                    }
                    else
                    {
                        keyCache.Add(key);
                    }
#else
                    if (propertyInfo.PropertyType.IsGenericType)
                    {
                        listCache.Add(key);
                        item.ListType             = propertyInfo.PropertyType.GetGenericArguments()[0];
                        item.ImplementsProperties = typeof(IProperties).IsAssignableFrom(item.ListType);
                        item.Constructors         = item.ListType.GetConstructors().Select(c => c.GetParameters());
                        item.ListActivator        = () => Activator.CreateInstance(propertyInfo.PropertyType);
                        if (item.ListType.IsSubclassOf(typeof(CfgNode)))
                        {
                            item.Loader = () => (CfgNode)Activator.CreateInstance(item.ListType);
                        }
                    }
                    else
                    {
                        keyCache.Add(key);
                    }
#endif

                    if (string.IsNullOrEmpty(attribute.name))
                    {
                        attribute.name = key;
                    }

                    item.Setter = CfgReflectionHelper.CreateSetter(propertyInfo);
                    item.Getter = CfgReflectionHelper.CreateGetter(propertyInfo);

                    metadata[key] = item;
                }

                PropertyCache[type] = keyCache;
                ElementCache[type]  = listCache;
                MetadataCache[type] = metadata;

                return(metadata);
            }
        }
Example #4
0
        private static bool ResolveType(Func <bool> isSet, ref object input, string key, CfgMetadata metadata)
        {
            if (!isSet())
            {
                return(true);
            }

            var type = metadata.PropertyInfo.PropertyType;

            if (input.GetType() == type)
            {
                return(true);
            }

            var value = input;

            if (TryConvertValue(ref value, type))
            {
                input = value;
                return(true);
            }

            metadata.TypeMismatch = true;
            metadata.Errors.Add(CfgEvents.TypeMismatch(key, value, type));
            return(false);
        }
Example #5
0
        void CheckValidators(CfgMetadata item, string name, object value) {
            if (!item.Attribute.ValidatorsSet)
                return;

            foreach (var validator in item.Validators()) {
                if (Validators.ContainsKey(validator)) {
                    try {
                        var result = Validators[validator].Validate(name, value);
                        if (result.Valid)
                            continue;

                        if (result.Warnings != null) {
                            foreach (var warning in result.Warnings) {
                                Warn(warning);
                            }
                        }
                        if (result.Errors != null) {
                            foreach (var error in result.Errors) {
                                Error(error);
                            }
                        }
                    } catch (Exception ex) {
                        Events.ValidatorException(validator, ex, value);
                    }
                } else {
                    Events.MissingValidator(name, validator);
                }
            }
        }
Example #6
0
        void ValidateUniqueAndRequiredProperties(
            string parent,
            string listName,
            CfgMetadata listMetadata,
            ICollection list
        ) {

            //if more than one then uniqueness comes into question
            if (list.Count > 1) {
                lock (Locker) {
                    if (listMetadata.UniquePropertiesInList == null) {
                        listMetadata.UniquePropertiesInList = CfgMetadataCache.GetMetadata(listMetadata.ListType, Events)
                            .Where(p => p.Value.Attribute.unique)
                            .Select(p => p.Key)
                            .ToArray();
                    }
                }

                if (listMetadata.UniquePropertiesInList.Length <= 0)
                    return;

                for (var j = 0; j < listMetadata.UniquePropertiesInList.Length; j++) {
                    var unique = listMetadata.UniquePropertiesInList[j];
                    var duplicates = list
                        .Cast<CfgNode>()
                        .Where(n => n.UniqueProperties.ContainsKey(unique))
                        .Select(n => n.UniqueProperties[unique])
                        .GroupBy(n => n)
                        .Where(group => @group.Count() > 1)
                        .Select(group => @group.Key)
                        .ToArray();

                    for (var l = 0; l < duplicates.Length; l++) {
                        Events.DuplicateSet(unique, duplicates[l], listName);
                    }
                }
            } else if (list.Count == 0 && listMetadata.Attribute.required) {
                Events.MissingRequiredAdd(parent, listName);
            }
        }