Example #1
0
        protected internal void ValidateListsBasedOnAttributes(string parent)
        {
            var metadata     = CfgMetadataCache.GetMetadata(Type);
            var elementNames = CfgMetadataCache.ElementNames(Type).ToList();

            foreach (var listName in elementNames)
            {
                var listMetadata = metadata[listName];
                var list         = (IList)listMetadata.Getter(this);
                ValidateUniqueAndRequiredProperties(parent, listName, listMetadata, list);
            }
        }
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 void ValidateBasedOnAttributes(INode node, IDictionary <string, string> parameters)
        {
            var metadata = CfgMetadataCache.GetMetadata(Type);
            var keys     = CfgMetadataCache.PropertyNames(Type).ToArray();

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

            for (var i = 0; i < keys.Length; i++)
            {
                var key  = keys[i];
                var item = metadata[key];

                var objectValue = item.Getter(this);
                if (objectValue == null)
                {
                    continue;
                }

                var stringValue = item.PropertyInfo.PropertyType == typeof(string) ? (string)objectValue : objectValue.ToString();

                if (item.Attribute.unique)
                {
                    UniqueProperties[key] = stringValue;
                }

                if (item.Attribute.DomainSet)
                {
                    if (!item.IsInDomain(stringValue))
                    {
                        Events.ValueNotInDomain(key, stringValue, item.Attribute.domain.Replace(item.Attribute.delimiter.ToString(), ", "));
                    }
                }

                CheckValueLength(item.Attribute, key, stringValue);

                CheckValueBoundaries(item.Attribute, key, objectValue);

                CheckValueMatchesRegex(item, key, stringValue);
            }
        }
Example #4
0
        /// <summary>
        /// Clears Cfg decorated properties.
        /// </summary>
        private void Clear()
        {
            var metadata = CfgMetadataCache.GetMetadata(GetType());

            foreach (var pair in metadata)
            {
                foreach (var error in pair.Value.Errors)
                {
                    _modelErrors.Add(error);
                }
                if (pair.Value.ListType == null)
                {
                    pair.Value.Setter(this, pair.Value.TypeMismatch ? pair.Value.TypeDefault : pair.Value.Attribute.value);
                }
                else
                {
                    pair.Value.Setter(this, pair.Value.ListActivator());
                }
            }
        }
Example #5
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);
                    }
                }
            }
        }
Example #6
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);
                }
            }
        }