示例#1
0
        /// <inheritdoc />
        /// <remarks>The function uses Convert class functionality to convert from XmlValue of child nodes into the target type.</remarks>
        public object ProcessElements(XmlElement _parent_element, Type _target_type, X2OConfig _config)
        {
            if (!_target_type.IsValueType && !_target_type.Equals(typeof(string)))
            {
                return(null);
            }

            var xval         = _parent_element.ChildNodes[0].Value;
            var tgt_type_val = Convert.ChangeType(xval, _target_type);

            return(tgt_type_val);
        }
示例#2
0
        /// <inheritdoc />
        /// <remarks>
        /// The function looks for the fromFile attribute, and if found, and there are no children it uses the X2OReader to
        /// read this file and desrialize its content, which is then returned as the value of this element.
        /// </remarks>
        public object ProcessElements(XmlElement _parent_element, Type _target_type, X2OConfig _config)
        {
            var external_config_attr = _parent_element.Attributes["fromFile"];

            if (external_config_attr != null && !_parent_element.HasChildNodes)
            {
                foreach (var possible_file in FindExistingFiles(external_config_attr.Value, _config))
                {
                    try
                    {
                        var result = X2OReader.ReadFromFile(possible_file, _config);
                        if (result != null)
                        {
                            return(result);
                        }
                    }
                    catch { }
                }
            }

            return(null);
        }
示例#3
0
        /// <summary>
        /// Based on the filename in the attribute for loading the external file, it finds the files, which exists
        /// and could be loaded to be read.
        /// It uses the ExternalConfigSearchPaths property of the X2OConfig, after it is not found in the application current directory.
        /// </summary>
        private IEnumerable <string> FindExistingFiles(string _filename, X2OConfig _config)
        {
            var fi = new System.IO.FileInfo(_filename);

            if (fi.Exists)
            {
                yield return(fi.FullName);
            }

            if (_config?.ExternalConfigSearchPaths != null)
            {
                foreach (var search_path in _config.ExternalConfigSearchPaths)
                {
                    var pathname = System.IO.Path.Combine(search_path, _filename);
                    fi = new System.IO.FileInfo(pathname);
                    if (fi.Exists)
                    {
                        yield return(fi.FullName);
                    }
                }
            }

            yield break;
        }
示例#4
0
        /// <summary>
        /// This function tries to create the instance of the target type according to the information in _declared_type and _parent_element.
        /// In this implementation, it is able to create only the List&lt;object&gt; or List&lt;T&gt; types, according to the _declared_type and
        /// only in cases, that the _declared_type is convertible into these Lists.
        /// </summary>
        public virtual EnumerableInfo?CreateEnumerable(XmlElement _parent_element, Type _target_type, X2OConfig _config)
        {
            Action <IEnumerable, object> add_action = (l, i) => l.GetType().GetMethod("Add").Invoke(l, new[] { i });

            // find if it is generic, find the generic type, create list of that type, and try if it can convert into declared type
            if (_target_type.IsGenericType && _target_type.GenericTypeArguments.Length == 1)
            {
                // it is generic type, like List<T> or IEnumerable<T>
                var item_type = _target_type.GenericTypeArguments[0];
                var tgt_type  = typeof(List <>).MakeGenericType(item_type);
                if (_target_type.IsAssignableFrom(tgt_type))
                {
                    try
                    {
                        return(new EnumerableInfo()
                        {
                            Enumerable = Activator.CreateInstance(tgt_type) as IEnumerable,
                            DeclaredItemType = item_type,
                            AddAction = add_action
                        });
                    }
                    catch { }
                }
            }
            else
            {
                if (_target_type.IsAssignableFrom(typeof(List <object>)))
                {
                    try
                    {
                        return(new EnumerableInfo()
                        {
                            Enumerable = new List <object>(),
                            DeclaredItemType = typeof(object),
                            AddAction = add_action
                        });
                    }
                    catch { }
                }
            }

            return(null);
        }
示例#5
0
        /// <inheritdoc />
        /// <remarks>
        /// This function firstly check, if the type will be IEnumerable.
        /// Then it tries to create the instance and get information about the enumerable by calling function CreateEnumerable.
        /// If successful, it goes through all the child nodes of _parent_element and deserializes the objects, which are than add
        /// using the AddAction.
        /// </remarks>
        public virtual object                                                           ProcessElements(XmlElement _parent_element, Type _target_type, X2OConfig _config)
        {
            // if the declared type is not the IEnumerable, we cannot help here
            if (!typeof(IEnumerable).IsAssignableFrom(_target_type))
            {
                return(null);
            }

            var enumerable_info = CreateEnumerable(_parent_element, _target_type, _config);

            if (!enumerable_info.HasValue)
            {
                return(null);
            }

            foreach (XmlElement element in _parent_element.ChildNodes)
            {
                var item = _config.Processor.ProcessElements(element, enumerable_info.Value.DeclaredItemType, _config);
                enumerable_info.Value.AddAction(enumerable_info.Value.Enumerable, item);
            }

            return(enumerable_info.Value.Enumerable);
        }
示例#6
0
        /// <summary></summary>
        public virtual DictionaryInfo?CreateDictionary(XmlElement _parent_element, Type _target_type, X2OConfig _config)
        {
            if (_target_type.IsGenericType && _target_type.GenericTypeArguments.Length == 2)
            {
                // generic dictionary like Dictionary<T1, T2>
                var key_type   = _target_type.GenericTypeArguments[0];
                var value_type = _target_type.GenericTypeArguments[1];
                var dict_type  = typeof(Dictionary <,>).MakeGenericType(key_type, value_type);
                if (dict_type.IsAssignableFrom(_target_type))
                {
                    try
                    {
                        var dict = Activator.CreateInstance(_target_type) as IDictionary;
                        // declared type is derived from Dictionary<T1,T2> and we guessed the type parameters correctly
                        var dict_info = new DictionaryInfo()
                        {
                            Dictionary = dict,
                            KeyType    = key_type,
                            ValueType  = value_type
                        };
                        return(dict_info);
                    }
                    catch { }
                }
            }

            // in any other cases, we cannot guess the key and value types without traversing the object hierarchy
            // for these cases, it is better to return without guessing
            // user can override this function to get the correct types

            return(null);
        }
示例#7
0
        /// <inheritdoc />
        /// <remarks>
        /// </remarks>
        public virtual object                                                           ProcessElements(XmlElement _parent_element, Type _target_type, X2OConfig _config)
        {
            // if the declared type is not the IDictionary, we cannot help here
            if (!typeof(IDictionary).IsAssignableFrom(_target_type))
            {
                return(null);
            }

            var dictionary_info = CreateDictionary(_parent_element, _target_type, _config);

            if (!dictionary_info.HasValue)
            {
                return(null);
            }

            foreach (XmlElement element in _parent_element.ChildNodes)
            {
                if (element.Name == "Item")
                {
                    XmlElement key_node = null, value_node = null;
                    foreach (XmlElement item_element in element.ChildNodes)
                    {
                        if (item_element.Name == "Key")
                        {
                            key_node = item_element;
                        }
                        if (item_element.Name == "Value")
                        {
                            value_node = item_element;
                        }
                    }
                    if (key_node != null)
                    {
                        var    key   = _config.Processor.ProcessElements(key_node, dictionary_info.Value.KeyType, _config);
                        object value = null;
                        if (value_node != null)
                        {
                            value = _config.Processor.ProcessElements(value_node, dictionary_info.Value.ValueType, _config);
                        }

                        if (key != null)
                        {
                            dictionary_info.Value.Dictionary.Add(key, value);
                        }
                    }
                }
            }
            return(dictionary_info.Value.Dictionary);
        }
示例#8
0
        /// <summary>
        /// Based on the _declared_type and XmlElement settings of _parent_element it creates the target object, where the values from the
        /// child nodes are to be read.
        /// </summary>
        /// <returns>The instance of the target object or null, if the processor doesn't know how to read such type of object.</returns>
        public virtual object                                                           CreateInstance(XmlElement _parent_element, Type _target_type, X2OConfig _config)
        {
            // try the declared type
            try
            {
                return(Activator.CreateInstance(_target_type));
            }
            catch { }

            // or in some cases it may happen, that the node has the name of the type
            {
                var type = _config.Processor.GetTypeByName(_parent_element.Name, _config);
                try
                {
                    return(Activator.CreateInstance(type));
                }
                catch { }
            }
            return(null);
        }
示例#9
0
        /// <inheritdoc />
        public virtual object                                                           ProcessElements(XmlElement _parent_element, Type _target_type, X2OConfig _config)
        {
            var inst = CreateInstance(_parent_element, _target_type, _config);

            if (inst == null)
            {
                return(null);
            }

            foreach (XmlElement element in _parent_element.ChildNodes)
            {
                var member_info = inst.GetType().GetMembers().Single(m => m.Name == element.Name);
                var member_type = member_info.GetTypeOfMember();
                var val         = _config.Processor.ProcessElements(element, member_type, _config);
                member_info.SetMemberValue(inst, val);
            }

            return(inst);
        }