Mercurial > repos > IBDev-IBBoard.WarFoundry.API
view API/Factories/Xml/WarFoundryXmlFactory.cs @ 370:077e9be48438
Re #346: Add requirement schema support
* Pass unit test with a specific case for one requirement - needs extensibility
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Mon, 13 Jun 2011 15:15:04 +0000 |
parents | 1a70ca80ef41 |
children | c3b0b28bad48 |
line wrap: on
line source
// This file (WarFoundryXmlFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 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 System.Xml.XPath; using System.Collections.Generic; using System.Text; using IBBoard; using IBBoard.IO; using IBBoard.Lang; using IBBoard.Logging; using IBBoard.Xml; using IBBoard.WarFoundry.API.Objects; using ICSharpCode.SharpZipLib.Zip; using System.Text.RegularExpressions; namespace IBBoard.WarFoundry.API.Factories.Xml { /// <summary> /// The WarFoundryXmlFactory loads WarFoundry classes from the native "XML in a zip" file format. Files are validated using the schema for the file type, so structurally invalid files should be identified at initial load. /// </summary> public class WarFoundryXmlFactory : AbstractNativeWarFoundryFactory { private static WarFoundryXmlFactory factory; private WarFoundryXmlGameSystemFactory gameSystemFactory; private WarFoundryXmlRaceFactory raceFactory; private WarFoundryXmlArmyFactory armyFactory; public static WarFoundryXmlFactory GetFactory() { if (factory == null) { factory = new WarFoundryXmlFactory(); } return factory; } private WarFoundryXmlFactory() : base() { gameSystemFactory = new WarFoundryXmlGameSystemFactory(this); raceFactory = new WarFoundryXmlRaceFactory(this); armyFactory = new WarFoundryXmlArmyFactory(); } public WarFoundryXmlGameSystemFactory GetSystemFactory() { return gameSystemFactory; } public WarFoundryXmlRaceFactory GetRaceFactory() { return raceFactory; } public WarFoundryXmlArmyFactory GetArmyFactory() { return armyFactory; } protected override bool CheckCanFindArmyFileContent(ZipFile file) { return FindEntries(file, "*.armyx").Count > 0; } protected override bool CheckCanFindSystemFileContent(ZipFile file) { return FindEntries(file, "*.systemx").Count > 0; } protected override bool CheckCanFindRaceFileContent(ZipFile file) { return FindEntries(file, "*.racex").Count > 0; } protected override ICollection<ZipEntry> GetArmyZipEntries(ZipFile file) { return FindEntries(file, "*.armyx"); } private ICollection<ZipEntry> FindEntries(ZipFile file, string wildcardPattern) { Regex re = new Regex("^" + Regex.Escape(wildcardPattern).Replace(@"\*", ".*").Replace(@"\?", ".") + "$", RegexOptions.IgnoreCase | RegexOptions.Singleline); ICollection<ZipEntry> entries = new List<ZipEntry>(); foreach (ZipEntry entry in file) { if (re.IsMatch(entry.Name)) { entries.Add(entry); } } return entries; } protected override Army CreateArmyFromStream (ZipFile file, Stream dataStream) { XmlElement elem = GetRootElementFromStream(dataStream, WarFoundryXmlElementName.ARMY_ELEMENT); return armyFactory.CreateArmyFromElement(file, elem); } private XmlElement GetRootElementFromStream(Stream stream, WarFoundryXmlElementName elementName) { XmlDocument doc = WarFoundryXmlFactoryUtils.CreateXmlDocumentFromStream(stream); XmlElement elem = (XmlElement)doc.LastChild; if (!elem.LocalName.Equals(elementName.Value)) { throw new InvalidFileException(String.Format("Root element of XML was not valid. Expected {0} but got {1}", elementName.Value, elem.Name)); } return elem; } protected override ICollection<ZipEntry> GetGameSystemZipEntries(ZipFile file) { return FindEntries(file, "*.systemx"); } protected override GameSystem CreateGameSystemFromStream (ZipFile file, Stream dataStream) { XmlElement elem = GetRootElementFromStream(dataStream, WarFoundryXmlElementName.SYSTEM_ELEMENT); LogNotifier.Debug(GetType(), "Create GameSystem"); return gameSystemFactory.CreateSystemFromElement(file, elem); } protected override ICollection<ZipEntry> GetRaceZipEntries(ZipFile file) { return FindEntries(file, "*.racex"); } protected override Race CreateRaceFromStream (ZipFile file, Stream dataStream) { XmlElement elem = GetRootElementFromStream(dataStream, WarFoundryXmlElementName.RACE_ELEMENT); LogNotifier.Debug(GetType(), "Create Race"); return raceFactory.CreateRaceFromElement(file, elem); } protected override void CleanUpFileAsSupportedType(ZipFile typedFile) { typedFile.Close(); } public override void CompleteLoading(IWarFoundryStagedLoadObject obj) { LogNotifier.DebugFormat(GetType(), "Complete loading of {0} with ID {1}", obj.GetType().Name, obj.ID); if (obj is GameSystem) { CompleteLoadingGameSystem((GameSystem) obj); } else if (obj is Race) { CompleteLoadingRace((Race) obj); } } private void CompleteLoadingRace(Race race) { try { raceFactory.CompleteLoading(race); } catch (InvalidFileException ex) { WarFoundryLoader.GetDefault().RemoveRace(race); throw; } } private void CompleteLoadingGameSystem(GameSystem system) { try { gameSystemFactory.CompleteLoading(system); } catch (InvalidFileException ex) { WarFoundryLoader.GetDefault().RemoveGameSystem(system); throw; } } } }