Beispiel #1
0
        public void Check()
        {
            Events.Clear(_modelErrors);
            var name = CfgMetadataCache.NormalizeName(Type, Type.Name);
            var node = new ObjectNode(this, name);

            Process(node, name, Serializer, Events, new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase), Customizers, 0, Enabled);
        }
Beispiel #2
0
        private void LoadProperties(INode node, string parentName, IDictionary <string, string> parameters, IList <ICustomizer> customizers)
        {
            var metadata = CfgMetadataCache.GetMetadata(Type);
            var keys     = CfgMetadataCache.PropertyNames(Type).ToArray();

            if (!keys.Any())
            {
                return;
            }

            var keyHits      = new HashSet <string>();
            var nullWarnings = new HashSet <string>();

            // first pass, set default values and report invalid attributes
            foreach (var attribute in node.Attributes)
            {
                var attributeKey = CfgMetadataCache.NormalizeName(Type, attribute.Name);
                if (metadata.ContainsKey(attributeKey))
                {
                    var item = metadata[attributeKey];

                    if (attribute.Value != null)
                    {
                        continue;
                    }

                    // if attribute is null, use the getter
                    var maybe = item.Getter(this);
                    if (maybe == null)
                    {
                        if (nullWarnings.Add(attribute.Name))
                        {
                            Events.Warning($"'{attribute.Name}' in '{parentName}' is susceptible to nulls.");
                        }
                        continue;
                    }
                    attribute.Value = maybe;
                }
                else
                {
                    if (attributeKey != "sequence")
                    {
                        Events.InvalidAttribute(parentName, node.Name, attribute.Name, string.Join(", ", keys));
                    }
                }
            }

            foreach (var customizer in customizers)
            {
                try {
                    customizer.Customize(parentName, node, parameters, Events.Logger);
                } catch (Exception ex) {
                    Events.Error($"{customizer.GetType().Name} error: {ex.Message}");
                }
            }

            // second pass, after customizers, adjust case and trim, set property value
            foreach (var attribute in node.Attributes)
            {
                var attributeKey = CfgMetadataCache.NormalizeName(Type, attribute.Name);
                if (metadata.ContainsKey(attributeKey))
                {
                    var item = metadata[attributeKey];

                    if (item.PropertyInfo.PropertyType == typeof(string))
                    {
                        if (attribute.Value == null)  // user has not provided a default
                        {
                            continue;
                        }

                        var stringValue = attribute.Value.ToString();

                        if (Enabled)
                        {
                            if (item.Attribute.toLower)
                            {
                                stringValue = stringValue.ToLower();
                            }
                            else if (item.Attribute.toUpper)
                            {
                                stringValue = stringValue.ToUpper();
                            }

                            if (item.Attribute.trim || item.Attribute.trimStart && item.Attribute.trimEnd)
                            {
                                stringValue = stringValue.Trim();
                            }
                            else
                            {
                                if (item.Attribute.trimStart)
                                {
                                    stringValue = stringValue.TrimStart();
                                }
                                if (item.Attribute.trimEnd)
                                {
                                    stringValue = stringValue.TrimEnd();
                                }
                            }
                        }

                        attribute.Value = stringValue;
                        item.Setter(this, attribute.Value);
                        keyHits.Add(attributeKey);
                    }
                    else
                    {
                        try {
                            item.Setter(this, CfgConstants.Converter[item.PropertyInfo.PropertyType](attribute.Value));
                            keyHits.Add(attributeKey);
                        } catch (Exception ex) {
                            Events.SettingValue(attribute.Name, attribute.Value, parentName, node.Name, ex.Message);
                        }
                    }
                }
            }

            // missing any required attributes?
            if (Enabled)
            {
                foreach (var key in keys.Except(keyHits))
                {
                    var item = metadata[key];
                    if (item.Attribute.required)
                    {
                        Events.MissingAttribute(parentName, node.Name, key);
                    }
                }
            }
        }
Beispiel #3
0
        void LoadCollections(INode node, string parentName, IDictionary <string, string> parameters, uint sequence)
        {
            var metadata     = CfgMetadataCache.GetMetadata(Type);
            var elementNames = CfgMetadataCache.ElementNames(Type).ToList();
            var elements     = new Dictionary <string, IList>();
            var elementHits  = new HashSet <string>();
            var addHits      = new HashSet <string>();

            //initialize all the lists
            for (var i = 0; i < elementNames.Count; i++)
            {
                var key = elementNames[i];
                elements.Add(key, (IList)metadata[key].Getter(this));
            }

            for (var i = 0; i < node.SubNodes.Count; i++)
            {
                var subNode    = node.SubNodes[i];
                var subNodeKey = CfgMetadataCache.NormalizeName(Type, subNode.Name);
                if (metadata.ContainsKey(subNodeKey))
                {
                    elementHits.Add(subNodeKey);
                    var item = metadata[subNodeKey];

                    for (var j = 0; j < subNode.SubNodes.Count; j++)
                    {
                        var add = subNode.SubNodes[j];
                        if (add.Name.Equals("add", StringComparison.Ordinal))
                        {
                            var addKey = CfgMetadataCache.NormalizeName(Type, subNode.Name);
                            addHits.Add(addKey);
                            if (item.Loader == null)
                            {
                                if (item.ImplementsProperties)
                                {
                                    object obj = null;

                                    //todo: these activator.createinstances should be cached
                                    foreach (var cp in item.Constructors)
                                    {
                                        if (!cp.Any())
                                        {
                                            obj = Activator.CreateInstance(item.ListType);
                                            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 (obj == null)
                                    {
                                        Events.ConstructorNotFound(parentName, subNode.Name);
                                    }
                                    else
                                    {
                                        var properties = (IProperties)obj;
                                        for (var k = 0; k < add.Attributes.Count; k++)
                                        {
                                            foreach (var c in Customizers)
                                            {
                                                c.Customize(string.Empty, add, parameters, Events.Logger);
                                            }
                                            var attribute = add.Attributes[k];
                                            properties[attribute.Name] = attribute.Value;
                                        }
                                        elements[addKey].Add(obj);
                                    }
                                }
                            }
                            else
                            {
                                elements[addKey].Add(item.Loader().Process(add, subNode.Name, Serializer, Events, parameters, Customizers, ++sequence, Enabled));
                            }
                        }
                        else
                        {
                            Events.UnexpectedElement(add.Name, subNode.Name);
                        }
                    }
                }
                else
                {
                    Events.InvalidElement(parentName, node.Name, subNode.Name);
                }
            }
        }