Beispiel #1
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);
        }
Beispiel #2
0
        private CfgNode Process(
            INode node,
            string parent,
            ISerializer serializer,
            CfgEvents events,
            IDictionary <string, string> parameters,
            IList <ICustomizer> customizers,
            uint sequence,
            bool enabled
            )
        {
            Sequence = sequence;
            Clear();

            // preserving events, customizers, and serializer, and whether or not it's enabled
            Events      = events;
            Customizers = customizers;
            Serializer  = serializer;
            Enabled     = enabled;

            LoadProperties(node, parent, parameters, customizers);
            LoadCollections(node, parent, parameters, sequence);

            if (Enabled)
            {
                PreValidate();
                ValidateBasedOnAttributes(node, parameters);
                ValidateListsBasedOnAttributes(node.Name);
                Validate();
                PostValidate();
            }
            return(this);
        }
Beispiel #3
0
        /// <summary>
        /// Constructor for injecting anything marked with IDependency
        /// </summary>
        /// <param name="dependencies"></param>
        protected CfgNode(params IDependency[] dependencies) {
            if (dependencies != null) {
                foreach (var dependency in dependencies.Where(dependency => dependency != null)) {
                    if (dependency is IReader) {
                        Reader = dependency as IReader;
                    } else if (dependency is IParser) {
                        Parser = dependency as IParser;
                    } else if (dependency is ISerializer) {
                        Serializer = dependency as ISerializer;
                    } else if (dependency is ILogger) {
                        var composite = new DefaultLogger(new MemoryLogger(), dependency as ILogger);
                        if (Events == null) {
                            Events = new CfgEvents(composite);
                        } else {
                            Events.Logger = composite;
                        }
                    } else if (dependency is IValidators) {
                        foreach (var pair in dependency as IValidators) {
                            Validators[pair.Key] = pair.Value;
                        }
                    }
                }
            }

            Type = GetType();
        }
Beispiel #4
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);
            }
        }
Beispiel #5
0
 protected CfgNode()
 {
     Events = new CfgEvents(new DefaultLogger(new MemoryLogger()));
     Clear();
     Type = GetType();
 }
Beispiel #6
0
 CfgNode Load(
     INode node,
     string parent,
     ISerializer serializer,
     CfgEvents events,
     IDictionary<string, IValidator> validators,
     ShorthandRoot shorthand,
     Dictionary<string, string> parameters
 ) {
     this.Clear(events);
     Shorthand = shorthand;
     Validators = validators;
     Serializer = serializer;
     LoadProperties(node, parent, parameters);
     LoadCollections(node, parent, parameters);
     PreValidate();
     ValidateBasedOnAttributes();
     ValidateListsBasedOnAttributes(node.Name);
     Validate();
     PostValidate();
     return this;
 }