Mercurial > repos > IBBoard.WarFoundry.API
view api/Factories/Xml/WarFoundryXmlFactoryUtils.cs @ 150:b36cc4af435b
Re #176: Bug when saving recently edited army
* Try to make sure that we clear up more of our open streams
Bug seems to be state related in some way since I can only trigger it when loading the file as the first action, but doesn't seem to be related to file loading of other data files since a diagnostic hard-coded "LoadFiles()" call in the FrmMain constructor doesn't change the behaviour
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sat, 26 Sep 2009 10:43:28 +0000 |
parents | 0b32cc40d82f |
children | c1caf467dd40 |
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.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 { 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.Constants.ExecutablePath + "/dtds/"; AddSchemaToCache(cache, NS_BASE + "core", path + "warfoundry-core.xsd"); AddSchemaToCache(cache, NS_BASE + "cats", path + "warfoundry-cats.xsd"); AddSchemaToCache(cache, NS_BASE + "race", path + "race.xsd"); AddSchemaToCache(cache, NS_BASE + "system", path + "system.xsd"); AddSchemaToCache(cache, NS_BASE + "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.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; } } }