view API/Factories/Xml/WarFoundryXmlFactoryUtils.cs @ 481:81f32062c9fa

Re #419: Remove assumptions of a file-based install * Convert schemas to resources and load them from there * Remove use of "data" folder relative to exe location from default "Hacks" (GTK/WinForms GUIs can re-add it locally)
author IBBoard <dev@ibboard.co.uk>
date Mon, 25 Jun 2012 21:04:02 +0100
parents 71fceea2725b
children
line wrap: on
line source

//  This file (WarFoundryXmlFactoryUtils.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 IBBoard
// 
// The file and the library/program it is in are licensed and distributed, without warranty, under the GNU Affero GPL license, either version 3 of the License or (at your option) any later version. Please see COPYING for more information and the full license.

using System;
using System.IO;
using System.Xml;
using System.Xml.Schema;
using IBBoard.WarFoundry.API.Objects;
using IBBoard.IO;
using IBBoard.Xml;
using System.Reflection;

namespace IBBoard.WarFoundry.API.Factories.Xml
{
		/// <summary>
		/// A collection of useful utility methods for loading WarFoundry data from XML files
		/// </summary>
		public class WarFoundryXmlFactoryUtils
		{
				public static readonly string NS_BASE = "http://ibboard.co.uk/warfoundry/";
				private static XmlReaderSettings settings;
				private static XmlNamespaceManager nsManager;
		
				public static XmlNodeList SelectNodes(XmlNode element, string xpathQuery)
				{
						return element.SelectNodes(xpathQuery, GetNamespaceManager());
				}
		
				public static XmlNode SelectSingleNode(XmlNode element, string xpathQuery)
				{
						return element.SelectSingleNode(xpathQuery, GetNamespaceManager());
				}
		
				public static XmlElement SelectSingleElement(XmlNode element, string xpathQuery)
				{
						XmlNode node = SelectSingleNode(element, xpathQuery);
						return (node is XmlElement) ? (XmlElement)node : null;
				}
				
				public static XmlNamespaceManager GetNamespaceManager()
				{
						if (nsManager == null)
						{
								nsManager = new XmlNamespaceManager(new NameTable());
								nsManager.AddNamespace("core", NS_BASE + "core");
								nsManager.AddNamespace("cat", NS_BASE + "cats");
								nsManager.AddNamespace("race", NS_BASE + "race");
								nsManager.AddNamespace("system", NS_BASE + "system");
								nsManager.AddNamespace("army", NS_BASE + "army");
						}
			
						return nsManager;
				}
		
				/// <summary>
				/// Lazy-getter for XML reader settings. May throw a <see cref="InvalidDataException"/> if there is a problem with the translation schema.
				/// </summary>
				/// <returns>
				/// A <see cref="XmlReaderSettings"/> with the default values for validating the translation document against the translation schema
				/// </returns>
				public static XmlReaderSettings GetReaderSettings()
				{
						if (settings == null)
						{
								settings = new XmlReaderSettings();
								settings.ValidationType = ValidationType.Schema;
								//settings.ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings;
								settings.ProhibitDtd = true;
								settings.ValidationEventHandler += new ValidationEventHandler(ValidationEventMethod);
								XmlSchemaSet cache = new XmlSchemaSet();
								string path = "IBBoard.WarFoundry.schemas.";
								Assembly assm = Assembly.GetExecutingAssembly();
								XmlTools.AddSchemaToSetFromResource(cache, NS_BASE + "core", assm, path + "warfoundry-core.xsd");
								XmlTools.AddSchemaToSetFromResource(cache, NS_BASE + "cats", assm, path + "warfoundry-cats.xsd");
								XmlTools.AddSchemaToSetFromResource(cache, NS_BASE + "race", assm, path + "race.xsd");
								XmlTools.AddSchemaToSetFromResource(cache, NS_BASE + "system", assm, path + "system.xsd");
								XmlTools.AddSchemaToSetFromResource(cache, NS_BASE + "army", assm, path + "army.xsd");
								settings.Schemas.Add(cache);
								settings.Schemas.CompilationSettings.EnableUpaCheck = false;
						}
			
						return settings;
				}
		
				private static void ValidationEventMethod(object sender, ValidationEventArgs e)
				{
						if (e.Severity == XmlSeverityType.Error)
						{
								throw new InvalidFileException("Problem validating against schema for WarFoundry data: " + e.Message, e.Exception);
						} else
						{
								//TODO: Fire some kind of warning event
						}
				}
		
				public static XmlDocument CreateXmlDocumentFromStream(Stream stream)
				{
						XmlDocument doc = new XmlDocument();
						XmlReader reader = XmlReader.Create(stream, GetReaderSettings());
			
						try
						{
								doc.Load(reader);
						}
			//Don't catch XMLSchemaExceptions - let them get thrown out
			finally
						{
								reader.Close();
						}

						return doc;
				}
		
				public static bool CanCompleteLoading(IWarFoundryStagedLoadObject obj)
				{
						bool canLoad = true;			
			
						if (obj.IsFullyLoaded)
						{
								canLoad = false;
						} else if (obj.IsLoading)
						{
								canLoad = false;
						}
			
						return canLoad;
				}
		}
}