Mercurial > repos > IBBoard.WarFoundry.API
diff api/Factories/Xml/WarFoundryXmlFactoryUtils.cs @ 52:64ef178c18aa
Re #10 - Refactor for readability
* Break WarFoundryXMLFactory out in to GameSystem, Race and Army factories
* Create factory utils classes with methods from WarFoundryXMLFactory for getting node lists etc
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Mon, 30 Mar 2009 19:44:03 +0000 |
parents | |
children | 2f3cafb69799 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/api/Factories/Xml/WarFoundryXmlFactoryUtils.cs Mon Mar 30 19:44:03 2009 +0000 @@ -0,0 +1,144 @@ +// 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 under the GNU LGPL license, either version 3 of the License or (at your option) any later version. Please see COPYING.LGPL for more information and the full license. +// + +using System; +using System.IO; +using System.Xml; +using System.Xml.Schema; +using IBBoard.Logging; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Factories.Xml +{ + /// <summary> + /// A collection of useful utility methods for loading WarFoundry data from XML files + /// </summary> + public class WarFoundryXmlFactoryUtils + { + 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", "http://ibboard.co.uk/warfoundry/core"); + nsManager.AddNamespace("cat", "http://ibboard.co.uk/warfoundry/cats"); + nsManager.AddNamespace("race", "http://ibboard.co.uk/warfoundry/race"); + nsManager.AddNamespace("system", "http://ibboard.co.uk/warfoundry/system"); + nsManager.AddNamespace("army", "http://ibboard.co.uk/warfoundry/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.Constants.ExecutablePath + "/dtds/"; + string nsBase = "http://ibboard.co.uk/warfoundry/"; + AddSchemaToCache(cache, nsBase + "core", path + "warfoundry-core.xsd"); + AddSchemaToCache(cache, nsBase + "cats", path + "warfoundry-cats.xsd"); + AddSchemaToCache(cache, nsBase + "race", path + "race.xsd"); + AddSchemaToCache(cache, nsBase + "system", path + "system.xsd"); + AddSchemaToCache(cache, nsBase + "army", path + "army.xsd"); + settings.Schemas.Add(cache); + } + + return settings; + } + + private static void ValidationEventMethod(object sender, ValidationEventArgs e) + { + throw new InvalidDataException("Problem validating against schema for WarFoundry data: " + e.Exception.Message, e.Exception); + } + + private static void AddSchemaToCache(XmlSchemaSet cache, string xmlNamespace, string schemaLocation) + { + try + { + cache.Add(xmlNamespace, schemaLocation); + } + catch (IOException ex) + { + LogNotifier.Warn(typeof(WarFoundryXmlFactoryUtils), "Problem reading schema: " + ex.Message, ex); + } + catch (XmlSchemaException ex) + { + LogNotifier.Warn(typeof(WarFoundryXmlFactoryUtils), "Problem validating schema for WarFoundry data: " + ex.Message, ex); + } + catch (XmlException ex) + { + LogNotifier.Warn(typeof(WarFoundryXmlFactoryUtils), "Problem reading data for schema: " + ex.Message, ex); + } + } + + 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) + { + LogNotifier.DebugFormat(typeof(WarFoundryXmlFactoryUtils), "Object of type {0} with ID {1} is already fully loaded", obj.GetType().Name, obj.ID); + canLoad = false; + } + else if (obj.IsLoading) + { + LogNotifier.WarnFormat(typeof(WarFoundryXmlFactoryUtils), "Object of type {0} with ID {1} is already being loaded", obj.GetType().Name, obj.ID); + canLoad = false; + } + + return canLoad; + } + } +}