Mercurial > repos > IBDev-IBBoard.WarFoundry.API
diff api/Factories/Xml/WarFoundryXmlFactory.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 | b271a2252758 |
children | 3ea0ab04352b |
line wrap: on
line diff
--- a/api/Factories/Xml/WarFoundryXmlFactory.cs Sat Mar 28 21:00:35 2009 +0000 +++ b/api/Factories/Xml/WarFoundryXmlFactory.cs Mon Mar 30 19:44:03 2009 +0000 @@ -26,9 +26,9 @@ public class WarFoundryXmlFactory : AbstractNativeWarFoundryFactory { private static WarFoundryXmlFactory factory; - private XmlReaderSettings settings; - private XmlNamespaceManager nsManager; - private Dictionary<IWarFoundryObject, XmlDocument> extraData = new Dictionary<IWarFoundryObject, XmlDocument>(); + private WarFoundryXmlGameSystemFactory gameSystemFactory; + private WarFoundryXmlRaceFactory raceFactory; + private WarFoundryXmlArmyFactory armyFactory; public static AbstractNativeWarFoundryFactory GetFactory() { @@ -42,7 +42,9 @@ private WarFoundryXmlFactory() : base() { - //Hide constructor + gameSystemFactory = new WarFoundryXmlGameSystemFactory(this); + raceFactory = new WarFoundryXmlRaceFactory(this); + armyFactory = new WarFoundryXmlArmyFactory(); } protected override bool CheckCanFindArmyFileContent(ZipFile file) @@ -68,12 +70,12 @@ protected override Army CreateArmyFromStream (ZipFile file, Stream dataStream) { XmlElement elem = GetRootElementFromStream(dataStream, WarFoundryXmlElementName.ARMY_ELEMENT); - return CreateArmyFromElement(file, elem); + return armyFactory.CreateArmyFromElement(file, elem); } private XmlElement GetRootElementFromStream(Stream stream, WarFoundryXmlElementName elementName) { - XmlDocument doc = CreateXmlDocumentFromStream(stream); + XmlDocument doc = WarFoundryXmlFactoryUtils.CreateXmlDocumentFromStream(stream); XmlElement elem = (XmlElement)doc.LastChild; if (!elem.LocalName.Equals(elementName.Value)) @@ -83,91 +85,6 @@ return elem; } - - private 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; - } - - /// <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> - private 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 void ValidationEventMethod(object sender, ValidationEventArgs e) - { - throw new InvalidDataException("Problem validating against schema for WarFoundry data: " + e.Exception.Message, e.Exception); - } - - private void AddSchemaToCache(XmlSchemaSet cache, string xmlNamespace, string schemaLocation) - { - try - { - cache.Add(xmlNamespace, schemaLocation); - } - catch (IOException ex) - { - LogNotifier.Warn(GetType(), "Problem reading schema: " + ex.Message, ex); - } - catch (XmlSchemaException ex) - { - LogNotifier.Warn(GetType(), "Problem validating schema for WarFoundry data: " + ex.Message, ex); - } - catch (XmlException ex) - { - LogNotifier.Warn(GetType(), "Problem reading data for schema: " + ex.Message, ex); - } - } - - private Army CreateArmyFromElement(ZipFile file, XmlElement elem) - { - string name = elem.GetAttribute("name"); - string systemID = elem.GetAttribute("gameSystem"); - GameSystem system = WarFoundryLoader.GetDefault().GetGameSystem(systemID); - string raceID = elem.GetAttribute("race"); - Race race = WarFoundryLoader.GetDefault().GetRace(system, raceID); - int points = XmlTools.GetIntValueFromAttribute(elem, "maxPoints"); - Army army = new Army(race, name, points, file); - //TODO: Complete loading of army - return army; - } protected override Stream GetGameSystemDataStream (ZipFile file) { @@ -178,21 +95,7 @@ { XmlElement elem = GetRootElementFromStream(dataStream, WarFoundryXmlElementName.SYSTEM_ELEMENT); LogNotifier.Debug(GetType(), "Create GameSystem"); - return CreateSystemFromElement(file, elem); - } - - private GameSystem CreateSystemFromElement(ZipFile file, XmlElement elem) - { - string id = elem.GetAttribute("id"); - string name = elem.GetAttribute("name"); - GameSystem system = new GameSystem(id, name, this); - StoreExtraData(system, elem); - return system; - } - - private void StoreExtraData(WarFoundryStagedLoadingObject wfObject, XmlElement elem) - { - extraData[wfObject] = elem.OwnerDocument; + return gameSystemFactory.CreateSystemFromElement(file, elem); } protected override Stream GetRaceDataStream (ZipFile file) @@ -204,56 +107,7 @@ { XmlElement elem = GetRootElementFromStream(dataStream, WarFoundryXmlElementName.RACE_ELEMENT); LogNotifier.Debug(GetType(), "Create Race"); - return CreateRaceFromElement(file, elem); - } - - private Race CreateRaceFromElement(ZipFile file, XmlElement elem) - { - string id = elem.GetAttribute("id"); - string subid = elem.GetAttribute("subid"); - string systemID = elem.GetAttribute("system"); - string name = elem.GetAttribute("name"); - Race race = new Race(id, subid, name, systemID, this); - StoreExtraData(race, elem); - return race; - } - - public XmlDocument GetExtraData(IWarFoundryObject obj) - { - XmlDocument extra = null; - extraData.TryGetValue(obj, out extra); - return extra; - } - - private 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; - } - - private XmlNodeList SelectNodes(XmlNode element, string xpathQuery) - { - return element.SelectNodes(xpathQuery, GetNamespaceManager()); - } - - private XmlNode SelectSingleNode(XmlNode element, string xpathQuery) - { - return element.SelectSingleNode(xpathQuery, GetNamespaceManager()); - } - - private XmlElement SelectSingleElement(XmlNode element, string xpathQuery) - { - XmlNode node = SelectSingleNode(element, xpathQuery); - return (node is XmlElement) ? (XmlElement) node : null; + return raceFactory.CreateRaceFromElement(file, elem); } public override void CompleteLoading(IWarFoundryStagedLoadObject obj) @@ -262,237 +116,12 @@ if (obj is GameSystem) { - CompleteLoading((GameSystem)obj); + gameSystemFactory.CompleteLoading((GameSystem)obj); } else if (obj is Race) { - CompleteLoading((Race)obj); - } - } - - public void CompleteLoading(GameSystem system) - { - if (!CanCompleteLoading(system)) - { - return; - } - - system.SetAsLoading(); - XmlDocument extraData = GetExtraData(system); - LoadCategoriesForSystem(system, extraData); - XmlElement statsElem = SelectSingleElement(extraData, "/system:system/system:sysStatsList"); - string defaultStatsID = statsElem.GetAttribute("defaultStats"); - LoadSystemStatsForSystem(system, extraData); - system.StandardSystemStatsID = defaultStatsID; - XmlElement systemElement = SelectSingleElement(extraData, "/system:system"); - system.WarnOnError = XmlTools.GetBoolValueFromAttribute(systemElement, "warn"); - system.AllowAllies = XmlTools.GetBoolValueFromAttribute(systemElement, "allowAllies"); - LogNotifier.DebugFormat(GetType(), "Completed loading of GameSystem with ID {0}", system.ID); - LogNotifier.DebugFormat(GetType(), "GameSystem with ID {0} default stats: {1}", system.ID, system.StandardSystemStatsID); - system.SetAsFullyLoaded(); - } - - private bool CanCompleteLoading(IWarFoundryStagedLoadObject obj) - { - bool canLoad = true; - - if (obj.IsFullyLoaded) - { - LogNotifier.DebugFormat(GetType(), "Object of type {0} with ID {1} is already fully loaded", obj.GetType().Name, obj.ID); - canLoad = false; - } - else if (obj.IsLoading) - { - LogNotifier.WarnFormat(GetType(), "Object of type {0} with ID {1} is already being loaded", obj.GetType().Name, obj.ID); - canLoad = false; - } - - return canLoad; - } - - private void LoadCategoriesForSystem(GameSystem system, XmlNode elem) - { - foreach (XmlElement cat in SelectNodes(elem, "/system:system/system:categories/cat:cat")) - { - system.AddCategory(CreateCategoryFromElement(cat)); - } - } - - private Category CreateCategoryFromElement(XmlElement elem) - { - string id = elem.GetAttribute("id"); - string name = elem.GetAttribute("name"); - Category cat = new Category(id, name); - cat.MaximumPercentage = XmlTools.GetIntValueFromAttribute(elem, "maxPercentage"); - cat.MinimumPercentage = XmlTools.GetIntValueFromAttribute(elem, "minPercentage"); - cat.MaximumPoints = XmlTools.GetIntValueFromAttribute(elem, "maxPoints"); - cat.MinimumPoints = XmlTools.GetIntValueFromAttribute(elem, "minPoints"); - return cat; - } - - private void LoadSystemStatsForSystem(GameSystem system, XmlNode elem) - { - foreach (XmlElement stats in SelectNodes(elem, "/system:system/system:sysStatsList/system:sysStats")) - { - SystemStats sysStats = CreateSystemStatsFromElement(stats); - system.AddSystemStats(sysStats); - } - } - - private SystemStats CreateSystemStatsFromElement(XmlElement elem) - { - List<StatSlot> slots = new List<StatSlot>(); - string id = elem.GetAttribute("id"); - - foreach (XmlElement slot in elem.ChildNodes) - { - StatSlot statSlot = new StatSlot(slot.GetAttribute("name")); - slots.Add(statSlot); - } - - return new SystemStats(id, slots.ToArray()); - } - - public void CompleteLoading(Race race) - { - if (!CanCompleteLoading(race)) - { - return; - } - - race.SetAsLoading(); - XmlDocument extraData = GetExtraData(race); - - foreach (XmlElement node in SelectNodes(extraData, "/race:race/race:units/race:unit")) - { - UnitType type = CreateUnitTypeFromElement(node, race, race.GameSystem); - race.AddUnitType(type); - } - - foreach (XmlElement node in SelectNodes(extraData, "/race:race/race:categories/cat:cat")) - { - race.AddCategory(CreateCategoryFromElement(node)); - } - - foreach (XmlElement node in SelectNodes(extraData, "/race:race/race:equipment/cat:equipmentItem")) - { - EquipmentItem item = CreateEquipmentItemFromElement(node, race); - race.AddEquipmentItem(item); + raceFactory.CompleteLoading((Race)obj); } - - foreach (XmlElement node in SelectNodes(extraData, "/race:race/race:abilities/cat:ability")) - { - Ability ability = CreateAbilityFromElement(node, race); - race.AddAbility(ability); - } - - race.SetAsFullyLoaded(); - LogNotifier.DebugFormat(GetType(), "Completed loading of Race with ID {0}", race.ID); - } - - private UnitType CreateUnitTypeFromElement(XmlElement elem, Race parentRace, GameSystem system) - { - string id = elem.GetAttribute("id"); - string name = elem.GetAttribute("typeName"); - UnitType type = new UnitType(id, name, parentRace); - type.MaxNumber = XmlTools.GetIntValueFromAttribute(elem, "maxNum"); - type.MinNumber = XmlTools.GetIntValueFromAttribute(elem, "minNum"); - type.MaxSize = XmlTools.GetIntValueFromAttribute(elem, "maxSize"); - type.MinSize = XmlTools.GetIntValueFromAttribute(elem, "minSize"); - type.BaseSize = XmlTools.GetIntValueFromAttribute(elem, "baseSize"); - type.CostPerTrooper = XmlTools.GetIntValueFromAttribute(elem, "points"); - type.BaseUnitCost = XmlTools.GetIntValueFromAttribute(elem, "unitPoints"); - string mainCatID = elem.GetAttribute("cat"); - Category cat = parentRace.GetCategory(mainCatID); - - if (cat == null) - { - throw new InvalidDataException(String.Format("Attribute 'cat' of UnitType {0} (value: {1}) did not reference a valid category", id, mainCatID)); - } - - type.MainCategory = cat; - XmlElement statsElement = SelectSingleElement(elem, "/race:race/race:units/race:unit/race:stats"); - type.UnitStats = ParseUnitStats(statsElement, system); - //TODO: Add unit requirements - LogNotifier.Debug(GetType(), "Loaded "+type.Name); - return type; - } - - private Stats ParseUnitStats(XmlElement elem, GameSystem system) - { - List<Stat> statsList = new List<Stat>(); - String statsID = elem.GetAttribute("statSet"); - SystemStats statsSet; - - if (statsID == "") - { - statsSet = system.StandardSystemStats; - } - else - { - statsSet = system.GetSystemStatsForID(statsID); - } - - Stats stats = new Stats(statsSet); - - foreach (XmlElement stat in elem.ChildNodes) - { - String statID = stat.GetAttribute("name"); - StatSlot slot = statsSet[statID]; - - if (slot!=null) - { - statsList.Add(new Stat(slot, stat.InnerText)); - } - else - { - throw new InvalidFileException("The stat "+statID+" was not found in stats set "+statsID); - } - } - - stats.SetStats(statsList); - - return stats; - } - - private EquipmentItem CreateEquipmentItemFromElement(XmlElement elem, Race race) - { - string id = elem.GetAttribute("id"); - string name = elem.GetAttribute("name"); - double cost = 0, min = 0, max = 0; - ArmourType armourType; - - try - { - cost = XmlTools.GetDoubleValueFromAttribute(elem, "cost"); - } - catch(FormatException ex) - { - throw new InvalidFileException("Attribute 'cost' of equipment item "+id+" was not a valid number", ex); - } - - try - { - armourType = (ArmourType)Enum.Parse(typeof(ArmourType), elem.GetAttribute("armourType")); - } - catch(ArgumentException ex) - { - throw new InvalidFileException("Attribute 'armourType' of equipment "+id+" was not a valid value from the enumeration", ex); - } - - //TODO: Parse equipment stats if there are any - - return new EquipmentItem(id, name, cost, min, max, armourType, race); - } - - private Ability CreateAbilityFromElement(XmlElement elem, Race race) - { - string id = elem.GetAttribute("id"); - string name = elem.GetAttribute("name"); - Ability ability = new Ability(id, name); - XmlNode node = elem.SelectSingleNode("description", GetNamespaceManager()); - ability.Description = (node == null) ? "" : node.InnerText; - return ability; } } } \ No newline at end of file