/// <summary>
        /// Sets values of this class with values from given XML file.
        /// </summary>
        /// <param name="ConfigurationXmlPath">The path to the file with values.</param>
        private static void LoadDataFromFile(string ConfigurationXmlPath)
        {
            XmlDocument         ConfigDocument = new XmlDocument();
            XmlNamespaceManager NS             = new XmlNamespaceManager(ConfigDocument.NameTable);

            NS.AddNamespace("ns", "https://www.unrealengine.com/BuildConfiguration");
            XmlReaderSettings ReaderSettings = new XmlReaderSettings();

            ReaderSettings.ValidationEventHandler += (object Sender, System.Xml.Schema.ValidationEventArgs EventArgs) =>
            {
                throw new BuildException("XmlConfigLoader: Reading config XML failed:\n{0}({1}): {2}",
                                         ConfigurationXmlPath, EventArgs.Exception.LineNumber,
                                         EventArgs.Message);
            };
            ReaderSettings.ValidationType = ValidationType.Schema;
            ReaderSettings.Schemas.Add(GetConfigSchema());

            using (StringReader SR = new StringReader(File.ReadAllText(ConfigurationXmlPath, Encoding.UTF8)))
            {
                XmlReader Reader = XmlReader.Create(SR, ReaderSettings);
                ConfigDocument.Load(Reader);
            }

            XmlNodeList XmlClasses = ConfigDocument.DocumentElement.SelectNodes("/ns:Configuration/*", NS);

            if (XmlClasses.Count == 0)
            {
                if (ConfigDocument.DocumentElement.Name == "Configuration")
                {
                    ConfigDocument.DocumentElement.SetAttribute("xmlns", "https://www.unrealengine.com/BuildConfiguration");

                    XmlDocument NSDoc = new XmlDocument();

                    NSDoc.LoadXml(ConfigDocument.OuterXml);

                    try
                    {
                        File.WriteAllText(ConfigurationXmlPath, WriteToBuffer(NSDoc));
                    }
                    catch (Exception)
                    {
                        // Ignore gently.
                    }

                    XmlClasses = NSDoc.DocumentElement.SelectNodes("/ns:Configuration/*", NS);
                }
            }

            foreach (XmlNode XmlClass in XmlClasses)
            {
                Type ClassType = Type.GetType("UnrealBuildTool." + XmlClass.Name);

                if (ClassType == null)
                {
                    Log.TraceVerbose("XmlConfig Loading: class '{0}' doesn't exist.", XmlClass.Name);
                    continue;
                }

                if (!IsConfigurableClass(ClassType))
                {
                    Log.TraceVerbose("XmlConfig Loading: class '{0}' is not allowed to be configured using XML system.", XmlClass.Name);
                    continue;
                }

                XmlConfigLoaderClassData ClassData;

                if (!Data.TryGetValue(ClassType, out ClassData))
                {
                    ClassData = new XmlConfigLoaderClassData();
                    Data.Add(ClassType, ClassData);
                }

                XmlNodeList XmlFields = XmlClass.SelectNodes("*");

                foreach (XmlNode XmlField in XmlFields)
                {
                    FieldInfo Field = ClassType.GetField(XmlField.Name);

                    // allow settings in the .xml that don't exist, as another branch may have it, and can share this file from Documents
                    if (Field == null)
                    {
                        PropertyInfo Property = ClassType.GetProperty(XmlField.Name);
                        if (Property != null)
                        {
                            if (!IsConfigurable(Property))
                            {
                                throw new BuildException("BuildConfiguration Loading: property '{0}' is either non-public, non-static or not-xml-configurable.", XmlField.Name);
                            }

                            ClassData.SetValue(Property, ParseFieldData(Property.PropertyType, XmlField.InnerText));
                        }

                        continue;
                    }

                    if (!IsConfigurableField(Field))
                    {
                        throw new BuildException("BuildConfiguration Loading: field '{0}' is either non-public, non-static or not-xml-configurable.", XmlField.Name);
                    }

                    if (Field.FieldType.IsArray)
                    {
                        // If the type is an array type get items for it.
                        XmlNodeList XmlItems = XmlField.SelectNodes("ns:Item", NS);

                        // Get the C# type of the array.
                        Type ItemType = Field.FieldType.GetElementType();

                        // Create the array according to the ItemType.
                        Array OutputArray = Array.CreateInstance(ItemType, XmlItems.Count);

                        int Id = 0;
                        foreach (XmlNode XmlItem in XmlItems)
                        {
                            // Append values to the OutputArray.
                            OutputArray.SetValue(ParseFieldData(ItemType, XmlItem.InnerText), Id++);
                        }

                        ClassData.SetValue(Field, OutputArray);
                    }
                    else
                    {
                        ClassData.SetValue(Field, ParseFieldData(Field.FieldType, XmlField.InnerText));
                    }
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Sets values of this class with values from given XML file.
        /// </summary>
        /// <param name="ConfigurationXmlPath">The path to the file with values.</param>
        private static void Load(string ConfigurationXmlPath)
        {
            var ConfigDocument = new XmlDocument();
            var NS             = new XmlNamespaceManager(ConfigDocument.NameTable);

            NS.AddNamespace("ns", "https://www.unrealengine.com/BuildConfiguration");
            ConfigDocument.Load(ConfigurationXmlPath);

            var XmlClasses = ConfigDocument.DocumentElement.SelectNodes("/ns:Configuration/*", NS);

            if (XmlClasses.Count == 0)
            {
                if (ConfigDocument.DocumentElement.Name == "Configuration")
                {
                    ConfigDocument.DocumentElement.SetAttribute("xmlns", "https://www.unrealengine.com/BuildConfiguration");

                    var NSDoc = new XmlDocument();

                    NSDoc.LoadXml(ConfigDocument.OuterXml);

                    try
                    {
                        File.WriteAllText(ConfigurationXmlPath, WriteToBuffer(NSDoc));
                    }
                    catch (Exception)
                    {
                        // Ignore gently.
                    }

                    XmlClasses = NSDoc.DocumentElement.SelectNodes("/ns:Configuration/*", NS);
                }
            }

            foreach (XmlNode XmlClass in XmlClasses)
            {
                var ClassType = Type.GetType("UnrealBuildTool." + XmlClass.Name);

                if (ClassType == null)
                {
                    Log.TraceVerbose("XmlConfig Loading: class '{0}' doesn't exist.", XmlClass.Name);
                    continue;
                }

                if (!IsConfigurableClass(ClassType))
                {
                    Log.TraceVerbose("XmlConfig Loading: class '{0}' is not allowed to be configured using XML system.", XmlClass.Name);
                    continue;
                }

                XmlConfigLoaderClassData ClassData;

                if (!Data.TryGetValue(ClassType, out ClassData))
                {
                    ClassData = new XmlConfigLoaderClassData(ClassType);
                    Data.Add(ClassType, ClassData);
                }

                var XmlFields = XmlClass.SelectNodes("*");

                foreach (XmlNode XmlField in XmlFields)
                {
                    FieldInfo Field = ClassType.GetField(XmlField.Name);

                    // allow settings in the .xml that don't exist, as another branch may have it, and can share this file from Documents
                    if (Field == null)
                    {
                        continue;
                    }

                    if (!IsConfigurableField(Field))
                    {
                        throw new BuildException("BuildConfiguration Loading: field '{0}' is either non-public, non-static or not-xml-configurable.", XmlField.Name);
                    }

                    if (Field.FieldType.IsArray)
                    {
                        // If the type is an array type get items for it.
                        var XmlItems = XmlField.SelectNodes("ns:Item", NS);

                        // Get the C# type of the array.
                        var ItemType = Field.FieldType.GetElementType();

                        // Create the array according to the ItemType.
                        var OutputArray = Array.CreateInstance(ItemType, XmlItems.Count);

                        int Id = 0;
                        foreach (XmlNode XmlItem in XmlItems)
                        {
                            // Append values to the OutputArray.
                            OutputArray.SetValue(ParseFieldData(ItemType, XmlItem.InnerText), Id++);
                        }

                        ClassData.SetValue(Field, OutputArray);
                    }
                    else
                    {
                        ClassData.SetValue(Field, ParseFieldData(Field.FieldType, XmlField.InnerText));
                    }
                }
            }
        }