using System;
using System.IO;
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
namespace DotNetExpansions.IO
{
/// <summary>
/// Vereinfacht das Laden, Validieren und Speichern von XML-Dateien.
/// </summary>
/// <remarks>
/// The first example uses a simple business object.
/// The second example uses a complex business object with nested object.
/// The third example shows the use of XmlIo with a dictionary
/// which holds values of different types.
/// Note: The use of such a configuration technique is not recommended
/// but XmlIo is able to handle even that.
/// The fourth example shows the usage of XSD validation with the same simple business object
/// from the first sample.
/// </remarks>
/// <example>
/// This demo shows the use of XmlIo with a very simple business object.
/// <code>
/// <![CDATA[
/// namespace SimpleConfigDemo
/// {
/// public class SimpleConfig
/// {
/// public byte Dimensions { get; set; }
/// public int HyperspaceEntrySection { get; set; }
/// public string NanobotsEmitterName { get; set; }
/// public string PicobotControllerIP { get; set; }
/// public float WarpFactor { get; set; }
/// }
/// }
/// ]]>
/// </code>
/// </example>
///
/// <example>
/// <code>
/// <![CDATA[
/// using System;
/// using System.Windows.Forms;
/// using DotNetExpansions;
///
/// namespace SimpleConfigDemo
/// {
/// class Program
/// {
/// static void Main()
/// {
/// var configManager = new XmlIo(Path.Combine(Environment.CurrentDirectory, "DemoConfig.xml"));
/// SimpleConfig config = CreateConfig();
/// Console.WriteLine("Saving Configuration...");
/// configManager.Save(config);
/// Console.WriteLine("Press any key to load the configuration."
/// + Environment.NewLine);
/// Console.ReadKey();
///
/// // Destroy the previously instantiated data transfer object for demonstration purposes.
/// config = null;
/// Console.WriteLine("Now loading the configuration..."
/// + Environment.NewLine);
/// config = configManager.Load<SimpleConfig>();
/// ShowConfig(config);
///
/// // Verhindert das selbsttätige Schließen des Konsolenfensters.
/// Console.WriteLine("\nPress any key to terminate the program.");
/// Console.ReadKey();
/// }
///
/// private static SimpleConfig CreateConfig()
/// {
/// var config = new SimpleConfig();
/// config.Dimensions = 7;
/// config.HyperspaceEntrySection = 1;
/// config.NanobotsEmitterName = "MyNanobotsEmitter";
/// config.PicobotControllerIP = "127.0.0.1";
/// config.WarpFactor = 10.0f;
/// return config;
/// }
///
/// private static void ShowConfig(SimpleConfig config)
/// {
/// Console.WriteLine("Nanobots EmitterName: {0}", config.NanobotsEmitterName);
/// Console.WriteLine("Picobot Controller IP: {0}", config.PicobotControllerIP);
/// Console.WriteLine("Dimensions: {0}", config.Dimensions);
/// Console.WriteLine("Hyperspace Entry Section: {0}", config.HyperspaceEntrySection);
/// Console.WriteLine("Warp Factor: {0}", config.WarpFactor);
/// }
/// }
/// }
///
/// /* Output:
/// Saving Configuration...
/// Press any key to load the configuration.
///
/// Now loading the configuration...
///
/// Nanobots EmitterName: MyNanobotsEmitter
/// Picobot Controller IP: 127.0.0.1
/// Dimensions: 7
/// Hyperspace Entry Section: 1
/// Warp Factor: 10
///
/// Press any key to terminate the program.
/// */
/// ]]>
/// </code>
/// </example>
/// This demo generates te following XML file.
/// <example>
/// <code>
/// <![CDATA[
/// <SimpleConfig xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/SimpleConfigDemo">
/// <Dimensions>7</Dimensions>
/// <HyperspaceEntrySection>1</HyperspaceEntrySection>
/// <NanobotsEmitterName>MyNanobotsEmitter</NanobotsEmitterName>
/// <PicobotControllerIP>127.0.0.1</PicobotControllerIP>
/// <WarpFactor>10</WarpFactor>
/// </SimpleConfig>
/// ]]>
/// </code>
/// </example>
/// <example>
/// This demo shows the use of XmlIo with a complex business object which contains nested objects.
/// <code>
/// <![CDATA[
/// using System.Drawing;
///
/// namespace NestedConfigDemo
/// {
/// public class NestedConfig
/// {
/// public string MachineName { get; set; }
/// public UiConfig UiSettings { get; set; }
/// public UserConfig UserSettings { get; set; }
/// public DalConfig DalSettings { get; set; }
///
/// public class UiConfig
/// {
/// public Size WindowSize { get; set; }
/// public Point WindowLocation { get; set; }
/// public Color BackgroundColor { get; set; }
/// public Color TextColor { get; set; }
/// }
///
/// public class UserConfig
/// {
/// public string FirstName { get; set; }
/// public string LastName { get; set; }
/// public string Email { get; set; }
/// }
///
/// public class DalConfig
/// {
/// public string ConnectionString { get; set; }
/// }
/// }
/// }
/// ]]>
/// </code>
/// </example>
///
/// <example>
/// <code>
/// <![CDATA[
/// using DotNetExpansions;
///
/// namespace NestedConfigDemo
/// {
/// using System;
/// using System.Drawing;
/// using System.Windows.Forms;
///
/// class Program
/// {
/// static void Main()
/// {
/// var configManager =
/// new XmlIo(Path.Combine(Environment.CurrentDirectory, "DemoConfig.xml");
/// NestedConfig config = CreateConfig();
/// configManager.Save(config);
/// config = null;
///
/// try
/// {
/// config = configManager.Load<NestedConfig>();
/// ShowConfig(config);
/// }
/// catch(InvalidOperationException problem)
/// {
/// Console.WriteLine(problem.Message);
/// Console.WriteLine(problem.Data);
/// }
///
/// // Verhindert das selbsttätige Schließen des Konsolenfensters.
/// Console.WriteLine("\nPress any key to terminate the program.");
/// Console.ReadKey();
/// }
///
/// private static NestedConfig CreateConfig()
/// {
/// var config = new NestedConfig();
/// config.DalSettings = new NestedConfig.DalConfig
/// {
/// ConnectionString = "Some Connection string"
/// };
/// config.MachineName = "MyComputer";
/// config.UiSettings = new NestedConfig.UiConfig
/// {
/// BackgroundColor = Color.White,
/// TextColor = Color.FromArgb(128, 0, 255),
/// WindowLocation = new Point(200, 100),
/// WindowSize = new Size(640, 480)
/// };
/// config.UserSettings = new NestedConfig.UserConfig
/// {
/// Email = "none@yourbusiness.com",
/// FirstName = "Santa",
/// LastName = "Claus"
/// };
/// return config;
/// }
///
/// private static void ShowConfig(NestedConfig config)
/// {
/// Console.WriteLine("Connection string: {0}", config.DalSettings.ConnectionString);
/// Console.WriteLine("Machine name: {0}", config.MachineName);
/// Console.WriteLine("Background color: {0}", config.UiSettings.BackgroundColor);
/// Console.WriteLine("Text color: {0}", config.UiSettings.TextColor);
/// Console.WriteLine("Window location: {0}", config.UiSettings.WindowLocation);
/// Console.WriteLine("Window size: {0}", config.UiSettings.WindowSize);
/// Console.WriteLine("First name: {0}", config.UserSettings.FirstName);
/// Console.WriteLine("Last name: {0}", config.UserSettings.LastName);
/// Console.WriteLine("Email address: {0}", config.UserSettings.Email);
/// }
/// }
/// }
/// /* Output
/// Connection string: Some Connection string
/// Machine name: MyComputer
/// Background color: Color [White]
/// Text color: Color [A=255, R=128, G=0, B=255]
/// Window location: {X=200,Y=100}
/// Window size: {Width=640, Height=480}
/// First name: Santa
/// Last name: Claus
/// Email address: none@yourbusiness.com
///
/// Press any key to terminate the program.
/// */
/// ]]>
/// </code>
/// </example>
/// <example>
/// This demo creates the following XML file.
/// <code>
/// <![CDATA[
/// <NestedConfig xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/NestedConfigDemo">
/// <DalSettings>
/// <ConnectionString>Some Connection string</ConnectionString>
/// </DalSettings>
/// <MachineName>MyComputer</MachineName>
/// <UiSettings>
/// <BackgroundColor xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Drawing">
/// <d3p1:knownColor>164</d3p1:knownColor>
/// <d3p1:name i:nil="true" />
/// <d3p1:state>1</d3p1:state>
/// <d3p1:value>0</d3p1:value>
/// </BackgroundColor>
/// <TextColor xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Drawing">
/// <d3p1:knownColor>0</d3p1:knownColor>
/// <d3p1:name i:nil="true" />
/// <d3p1:state>2</d3p1:state>
/// <d3p1:value>4286578943</d3p1:value>
/// </TextColor>
/// <WindowLocation xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Drawing">
/// <d3p1:x>200</d3p1:x>
/// <d3p1:y>100</d3p1:y>
/// </WindowLocation>
/// <WindowSize xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Drawing">
/// <d3p1:height>480</d3p1:height>
/// <d3p1:width>640</d3p1:width>
/// </WindowSize>
/// </UiSettings>
/// <UserSettings>
/// <Email>none@yourbusiness.com</Email>
/// <FirstName>Santa</FirstName>
/// <LastName>Claus</LastName>
/// </UserSettings>
/// </NestedConfig>
/// ]]>
/// </code>
/// </example>
/// <example>
/// This demo shows the use of XmlIo with a dictionary which holds values of different types. Note: The use of such a configuration technique is not recommended but XmlIo is able to handle even that.
/// <code>
/// <![CDATA[
/// // In case someone uses this kind of configuration storage (which is not recommended).
/// using System.Collections.Generic;
/// using System.Drawing;
/// using System.Runtime.Serialization;
///
/// namespace ConfigListDemo
/// {
/// [KnownType(typeof(Point))]
/// [KnownType(typeof(Size))]
/// [KnownType(typeof(Color))]
/// public class ConfigDictionary
/// {
/// public ConfigDictionary()
/// {
/// if(Configuration == null)
/// Configuration = new Dictionary<string, object>();
/// }
///
/// public Dictionary<string, object> Configuration { get; set; }
/// }
/// }
/// ]]>
/// </code>
/// </example>
///
/// <example>
/// <code>
/// <![CDATA[
/// using System;
/// using System.Drawing;
/// using System.Windows.Forms;
/// using DotNetExpansions;
///
/// namespace ConfigListDemo
/// {
/// class Program
/// {
/// static void Main()
/// {
/// var yourConfig = CreateConfig();
/// var xmlIo = new XmlIo(Path.Combine(Environment.CurrentDirectory, "YourConfig.xml");
/// Console.WriteLine("Saving configuration");
/// xmlIo.Save(yourConfig);
/// yourConfig = null;
/// try
/// {
/// Console.WriteLine("Trying to load your config data...");
/// yourConfig = xmlIo.Load<ConfigDictionary>();
/// ShowConfig(yourConfig);
/// }
/// catch(InvalidOperationException problem)
/// {
/// Console.WriteLine(problem.Message);
/// Console.WriteLine(problem.Data);
/// }
///
/// // Verhindert das selbsttätige Schließen des Konsolenfensters.
/// Console.WriteLine("\nPress any key to terminate the program.");
/// Console.ReadKey();
/// }
///
/// private static ConfigDictionary CreateConfig()
/// {
/// var config = new ConfigDictionary();
/// config.Configuration.Add("Integer", 1);
/// config.Configuration.Add("Double", 3.141592654);
/// config.Configuration.Add("String", "Hello world");
/// config.Configuration.Add("Point", new Point(100, 200));
/// config.Configuration.Add("Size", new Size(1024, 768));
/// config.Configuration.Add("RGB-color", Color.FromArgb(128, 0, 255));
/// config.Configuration.Add("named color", Color.Fuchsia);
/// return config;
/// }
///
/// private static void ShowConfig(ConfigDictionary configDictionary)
/// {
/// foreach(var keyValuePair in configDictionary.Configuration)
/// {
/// Console.WriteLine("Your {0}: {1}", keyValuePair.Key, keyValuePair.Value);
/// }
/// }
/// }
/// }
/// /* Output:
/// Saving configuration
/// Trying to load your config data...
/// Your Integer: 1
/// Your Double: 3,141592654
/// Your String: Hello world
/// Your Point: {X=100,Y=200}
/// Your Size: {Width=1024, Height=768}
/// Your RGB-color: Color [A=255, R=128, G=0, B=255]
/// Your named color: Color [Fuchsia]
///
/// Press any key to terminate the program.
/// */
/// ]]>
/// </code>
/// </example>
/// <example>
/// This demo creates the following XML file.
/// <code>
/// <![CDATA[
/// <ConfigDictionary xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ConfigListDemo">
/// <Configuration xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
/// <d2p1:KeyValueOfstringanyType>
/// <d2p1:Key>Integer</d2p1:Key>
/// <d2p1:Value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:int">1</d2p1:Value>
/// </d2p1:KeyValueOfstringanyType>
/// <d2p1:KeyValueOfstringanyType>
/// <d2p1:Key>Double</d2p1:Key>
/// <d2p1:Value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:double">3.141592654</d2p1:Value>
/// </d2p1:KeyValueOfstringanyType>
/// <d2p1:KeyValueOfstringanyType>
/// <d2p1:Key>String</d2p1:Key>
/// <d2p1:Value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:string">Hello world</d2p1:Value>
/// </d2p1:KeyValueOfstringanyType>
/// <d2p1:KeyValueOfstringanyType>
/// <d2p1:Key>Point</d2p1:Key>
/// <d2p1:Value xmlns:d4p1="http://schemas.datacontract.org/2004/07/System.Drawing" i:type="d4p1:Point">
/// <d4p1:x>100</d4p1:x>
/// <d4p1:y>200</d4p1:y>
/// </d2p1:Value>
/// </d2p1:KeyValueOfstringanyType>
/// <d2p1:KeyValueOfstringanyType>
/// <d2p1:Key>Size</d2p1:Key>
/// <d2p1:Value xmlns:d4p1="http://schemas.datacontract.org/2004/07/System.Drawing" i:type="d4p1:Size">
/// <d4p1:height>768</d4p1:height>
/// <d4p1:width>1024</d4p1:width>
/// </d2p1:Value>
/// </d2p1:KeyValueOfstringanyType>
/// <d2p1:KeyValueOfstringanyType>
/// <d2p1:Key>RGB-color</d2p1:Key>
/// <d2p1:Value xmlns:d4p1="http://schemas.datacontract.org/2004/07/System.Drawing" i:type="d4p1:Color">
/// <d4p1:knownColor>0</d4p1:knownColor>
/// <d4p1:name i:nil="true" />
/// <d4p1:state>2</d4p1:state>
/// <d4p1:value>4286578943</d4p1:value>
/// </d2p1:Value>
/// </d2p1:KeyValueOfstringanyType>
/// <d2p1:KeyValueOfstringanyType>
/// <d2p1:Key>named color</d2p1:Key>
/// <d2p1:Value xmlns:d4p1="http://schemas.datacontract.org/2004/07/System.Drawing" i:type="d4p1:Color">
/// <d4p1:knownColor>73</d4p1:knownColor>
/// <d4p1:name i:nil="true" />
/// <d4p1:state>1</d4p1:state>
/// <d4p1:value>0</d4p1:value>
/// </d2p1:Value>
/// </d2p1:KeyValueOfstringanyType>
/// </Configuration>
/// </ConfigDictionary>
/// ]]>
/// </code>
/// </example>
/// <example>
/// This last example shows the usage of the XSD validation with the same simple business object from the first sample.
/// <code>
/// <![CDATA[
/// using System;
/// using System.Windows.Forms;
/// using DotNetExpansions;
///
/// namespace SchemaValidationDemo
/// {
/// class Program
/// {
/// static void Main()
/// {
/// var configManager =
/// new XmlIo(Path.Combine(Environment.CurrentDirectory, "DemoConfig.xml");
///
/// var config = new SimpleConfig();
/// config.Dimensions = 7;
/// config.HyperspaceEntrySection = 1;
/// config.NanobotsEmitterName = "MyNanobotsEmitter";
/// config.PicobotControllerIP = "127.0.0.1";
/// config.WarpFactor = 3.141592654;
///
/// // Save config =========================================================
///
/// Console.WriteLine("Saving Configuration...");
/// configManager.Save(config);
/// Console.WriteLine("Press any key to validate the configuration."
/// + Environment.NewLine);
/// Console.ReadKey();
///
/// // Validaion ===========================================================
///
/// configManager.ValidationEvent += ConfigManagerValidationEvent;
/// ValidateConfig(configManager);
/// Console.WriteLine("Press any key to load the configuration."
/// + Environment.NewLine);
/// Console.ReadKey();
///
/// // Load config =========================================================
///
/// // Destroy the previously instantiated data transfer object for demonstration purposes.
/// config = null;
/// Console.WriteLine("Now loading the configuration..."
/// + Environment.NewLine);
/// try
/// {
/// config = configManager.Load<SimpleConfig>();
/// ShowConfig(config);
/// }
/// catch(InvalidOperationException problem)
/// {
/// Console.WriteLine(problem.Message);
/// Console.WriteLine(problem.Data);
/// }
///
/// // Verhindert das selbsttätige Schließen des Konsolenfensters.
/// Console.WriteLine("\nPress any key to terminate the program.");
/// Console.ReadKey();
/// }
///
/// private static void ValidateConfig(XmlIo configManager)
/// {
/// bool isValid = configManager.FileIsValidWith("DemoConfig.xsd");
/// if(isValid)
/// Console.WriteLine("XML-File is valid.");
/// else
/// Console.WriteLine("XML-File is invalid.");
/// return;
/// }
///
/// static void ConfigManagerValidationEvent(object sender, System.Xml.Schema.ValidationEventArgs e)
/// {
/// Console.WriteLine(e.Severity + ": " + e.Message);
/// }
///
/// private static void ShowConfig(SimpleConfig config)
/// {
/// Console.WriteLine("Nanobots EmitterName: {0}", config.NanobotsEmitterName);
/// Console.WriteLine("Picobot Controller IP: {0}", config.PicobotControllerIP);
/// Console.WriteLine("Dimensions: {0}", config.Dimensions);
/// Console.WriteLine("Hyperspace Entry Section: {0}", config.HyperspaceEntrySection);
/// Console.WriteLine("Warp Factor: {0}", config.WarpFactor);
/// }
/// }
/// }
///
/// ]]>
/// </code>
/// </example>
///
/// <example>
/// This is the XSD file content for validation.
/// <code>
/// <![CDATA[
/// <?xml version="1.0" encoding="utf-8"?>
/// <xs:schema xmlns:i="http://www.w3.org/2001/XMLSchema-instance" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/SchemaValidationDemo" xmlns:xs="http://www.w3.org/2001/XMLSchema">
/// <xs:element name="SimpleConfig">
/// <xs:complexType>
/// <xs:sequence>
/// <xs:element name="Dimensions" type="xs:unsignedByte" />
/// <xs:element name="HyperspaceEntrySection" type="xs:unsignedInt" />
/// <xs:element name="NanobotsEmitterName" type="xs:string" />
/// <xs:element name="PicobotControllerIP" type="xs:string" />
/// <xs:element name="WarpFactor" type="xs:double" />
/// </xs:sequence>
/// </xs:complexType>
/// </xs:element>
/// </xs:schema>
/// ]]>
/// </code>
/// </example>
/// <seealso cref="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.knowntypeattribute.aspx"/>
/// <seealso cref="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx"/>
public class XmlIo
{
#region Fields
private static bool fileIsValid = true;
private string fullFilename;
#endregion Fields
#region Events
/// <summary>
/// Tritt bei einem Validationsfehler ein.
/// </summary>
public event ValidationEventHandler ValidationEvent;
#endregion Events
#region Constructors
/// <summary>
/// Initialisiert eine neue Instanz der <see cref="XmlIo"/> Klasse.
/// </summary>
/// <param name="fullFilename">Der voll qualifizierte Dateiname (Pfad mit Dateiname und Extension)</param>
public XmlIo(string fullFilename)
{
if(IsValidFullFilename(fullFilename))
this.fullFilename = fullFilename;
else
throw new ArgumentException("fullFilename is invalid");
}
/// <summary>
/// Initialisiert eine neue Instanz der <see cref="XmlIo"/> Klasse.
/// </summary>
/// <param name="filepath">Der Dateipfad, unter dem die XML-Datei abgelegt werden soll.</param>
/// <param name="filename">Der Name der XML-Datei inklusive Extension.</param>
[Obsolete("Dieser Konstruktor existiert nur noch für die Abwärtskompatibilität.", false)]
public XmlIo(string filepath, string filename)
{
Filepath = ValidateFilepath(filepath);
Filename = ValidateFilename(filename);
fullFilename = Path.Combine(filepath, filename);
}
#endregion Constructors
#region Properties
/// <summary>
/// Gibt den Pfad zur XML-Datei zurück.
/// </summary>
public string Filepath { get; private set; }
/// <summary>
/// Gibt den Namen der XML-Datei zurück.
/// </summary>
public string Filename { get; private set; }
#endregion
#region Public Methods
/// <summary>
/// Lädt eine XML-Datei für ein beliebiges business object.
/// </summary>
/// <typeparam name="T">Der Typ des Business-Objekts.</typeparam>
/// <returns>Das Business-Objekt</returns>
public T Load<T>() where T : class
{
var filePermissions = new FileIOPermission(
FileIOPermissionAccess.Read, fullFilename);
filePermissions.Assert();
var fs = new FileStream(fullFilename, FileMode.Open, FileAccess.Read);
var reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
var ser = new DataContractSerializer(typeof(T));
var config = ser.ReadObject(reader);
fs.Close();
return config as T;
}
/// <summary>
/// Speichert eine XML-Datei für ein beliebiges Business Object.
/// </summary>
/// <typeparam name="T">Der Typ des Business Objects (die Angabe ist optional).</typeparam>
/// <param name="businessObject">Das Business Object</param>
public void Save<T>(T businessObject) where T : class
{
var filePermissions = new FileIOPermission(
FileIOPermissionAccess.Write, fullFilename);
filePermissions.Assert();
var writer = new XmlTextWriter(fullFilename, Encoding.UTF8);
if(writer == null)
throw new NullReferenceException();
writer.Formatting = Formatting.Indented;
var ser = new DataContractSerializer(businessObject.GetType());
ser.WriteObject(writer, businessObject);
writer.Close();
}
/// <summary>
/// Validiert eine XML-Datei mittels der angegebenen XSD-Datei.
/// </summary>
/// <param name="validationSchemaFilename">Die XSD-Datei</param>
/// <returns><c>true</c> wenn die XML-Datei gültig ist, anderenfalls <c>false</c>.</returns>
public bool FileIsValidWith(string validationSchemaFilename)
{
var filePermissions = new FileIOPermission(
FileIOPermissionAccess.Read, fullFilename);
filePermissions.Assert();
var xmlReaderSettings = new XmlReaderSettings();
xmlReaderSettings.Schemas.Add(
null, Path.Combine(Path.GetDirectoryName(fullFilename), validationSchemaFilename));
xmlReaderSettings.ValidationType = ValidationType.Schema;
xmlReaderSettings.ValidationEventHandler += XmlValidationEventHandler;
var config = XmlReader.Create(fullFilename, xmlReaderSettings);
while(config.Read()) { }
xmlReaderSettings.CloseInput = true;
return fileIsValid;
}
#endregion Public Methods
#region Private Methods
private static bool IsValidFullFilename(string fullFilename)
{
return !string.IsNullOrEmpty(fullFilename) && Directory.Exists(Path.GetDirectoryName(fullFilename));
}
private string ValidateFilename(string filename)
{
if(!IsValidEntry(filename))
throw new ArgumentException();
if(!filename.EndsWith(".xml"))
throw new ArgumentException("Filename-extension is either missing or wrong. It must be .xml");
this.Filename = filename;
return filename;
}
private string ValidateFilepath(string filepath)
{
if(!IsValidPath(filepath))
throw new DirectoryNotFoundException();
if(filepath.EndsWith(@"\"))
filepath = filepath.Substring(0, filepath.Length - 1);
this.Filepath = filepath;
return filepath;
}
private static bool IsValidEntry(string entry)
{
return !string.IsNullOrEmpty(entry);
}
private static bool IsValidPath(string path)
{
return Directory.Exists(path);
}
// Bubbling up the Event.
private void XmlValidationEventHandler(object sender, ValidationEventArgs e)
{
fileIsValid = false;
if(ValidationEvent != null)
ValidationEvent(this, e);
}
#endregion Private Methods
}
}