Files
win8phoneApp/CampusAppWP8/CampusAppWP8/Model/MainModel.cs
Christian Fiedler 74224a4fc5 #118
2013-07-22 11:46:22 +02:00

434 lines
12 KiB
C#

//-----------------------------------------------------------------------------
// <copyright file="MainModel.cs" company="BTU/IIT">
// Company copyright tag.
// </copyright>
// <author>fiedlchr</author>
// <sience>05.07.2013</sience>
//-----------------------------------------------------------------------------
namespace CampusAppWP8
{
using System;
using System.IO;
using System.Net;
using System.Text;
using CampusAppWP8.Utility;
/// <summary>
/// Base model io handling class.
/// </summary>
/// <typeparam name="T">model type</typeparam>
public abstract class MainModel<T> : IDisposable
{
/// <summary>
/// Model io type.
/// </summary>
private ModelType modelType;
/// <summary>
/// Model object.
/// </summary>
private T model = default(T);
/// <summary>
/// File object.
/// </summary>
private CampusAppWP8.Utility.File file = null;
/// <summary>
/// Web object.
/// </summary>
private HttpRequest api = null;
/// <summary>
/// Filename of saved data.
/// </summary>
private string fileName = string.Empty;
/// <summary>
/// Url of the feed data.
/// </summary>
private Uri httpApiUri = null;
/// <summary>
/// Initializes a new instance of the <see cref="MainModel{T}" /> class.
/// </summary>
/// <param name="modelType">Model IO type</param>
/// <param name="fileName">name of the file</param>
/// <param name="url">url of the feed</param>
public MainModel(ModelType modelType, string fileName, string url)
{
this.modelType = modelType;
if ((url != null) && (url.Equals(string.Empty) == false))
{
this.httpApiUri = new Uri(url, UriKind.Absolute);
}
this.fileName = fileName;
if ((this.IsFile() == true)
&& (fileName.Equals(string.Empty) == false))
{
this.InitFile(CampusAppWP8.Utility.File.IOTypeRead.ReadSync, CampusAppWP8.Utility.File.IOTypeWrite.WriteAsync);
}
if ((this.IsHttpApi() == true)
&& (url.Equals(string.Empty) == false))
{
this.InitHttpApi();
}
}
/// <summary>
/// Finalizes an instance of the <see cref="MainModel{T}" /> class.
/// </summary>
~MainModel()
{
this.SaveData();
}
/// <summary>
/// Delegate of the OnLoading callback function.
/// </summary>
public delegate void OnLoading();
/// <summary>
/// Delegate of the OnLoaded callback function.
/// </summary>
public delegate void OnLoaded();
/// <summary>
/// Delegate of the OnSaving callback function.
/// </summary>
public delegate void OnSaving();
/// <summary>
/// Delegate of the OnSaved callback function.
/// </summary>
public delegate void OnSaved();
/// <summary>
/// Delegate of the IsModelUpToDate callback function.
/// </summary>
/// <param name="model">data model</param>
/// <returns>true, model is up to date</returns>
public delegate bool IsModelUpToDate(T model);
/// <summary>
/// Delegate of the IsFileUpToDate callback function.
/// </summary>
/// <param name="model">data model</param>
/// <param name="fileInfo">info of the file</param>
/// <returns>true, is file is up to date</returns>
public delegate bool IsFileUpToDate(T model, FileInfo fileInfo);
/// <summary>
/// Callback pointer, called before loading.
/// </summary>
public event OnLoading onLoading = null;
/// <summary>
/// Callback pointer, called after loading.
/// </summary>
public event OnLoaded onLoaded = null;
/// <summary>
/// Callback pointer, called before saving.
/// </summary>
public event OnSaving onSaving = null;
/// <summary>
/// Callback pointer, called after saving.
/// </summary>
public event OnSaved onSaved = null;
/// <summary>
/// Callback pointer, for checking if file is up to date at loading.
/// </summary>
public event IsFileUpToDate isFileUpToDateOnLoad = null;
/// <summary>
/// Callback pointer, for checking if file is up to date at saving.
/// </summary>
public event IsFileUpToDate isFileUpToDateOnSave = null;
/// <summary>
/// Callback pointer, for checking if model is up to date at loading.
/// </summary>
public event IsModelUpToDate isModelUpToDateOnLoad = null;
/// <summary>
/// Callback pointer, for checking if model is up to date at saving.
/// (currently unused)
/// </summary>
public event IsModelUpToDate isModelUpToDateOnSave = null;
/// <summary>
/// Specifies the I/O type of the model.
/// </summary>
public enum ModelType
{
/// <summary>
/// Invalid/unset state.
/// </summary>
INVALID = 0,
/// <summary>
/// File only (01).
/// </summary>
File = 1,
/// <summary>
/// Feed only (10).
/// </summary>
Feed = 2,
/// <summary>
/// File and feed (11).
/// </summary>
FileAndFeed = 3
}
/// <summary>
/// Gets or sets the Model.
/// </summary>
public T Model
{
get
{
return this.model;
}
set
{
this.model = value;
}
}
/// <summary>
/// Called before finalizing. Can maybe be removed.
/// </summary>
public void Dispose()
{
this.SaveData();
}
/// <summary>
/// Forces a update from web.
/// </summary>
public void ForceWebUpdate()
{
if (this.api != null)
{
if (this.onLoading != null)
{
this.onLoading();
}
this.api.HttpGet(this.httpApiUri, this.OnLoadDataComplete);
}
}
/// <summary>
/// Load the data if necessary, from web or from file, regarding if
/// the file data is up to date.
/// </summary>
public void LoadData()
{
bool loadFromFile = true;
if (this.onLoading != null)
{
this.onLoading();
}
if (((this.isModelUpToDateOnLoad == null)
|| (this.isModelUpToDateOnLoad(this.model) == false))
&& ((this.file != null) || this.api != null))
{
if (this.file != null)
{
if ((this.file.Exist() == false)
|| (this.file.GetFileInfo().Length == 0))
{
loadFromFile = false;
}
if (((this.isFileUpToDateOnLoad != null) && (this.isFileUpToDateOnLoad(this.model, this.file.GetFileInfo()) == false))
|| (this.isFileUpToDateOnLoad == null))
{
loadFromFile = false;
}
}
else
{
loadFromFile = false;
}
if (this.api == null)
{
loadFromFile = true;
}
if (loadFromFile == false)
{
this.api.HttpGet(this.httpApiUri, this.OnLoadDataComplete);
}
else
{
string data = this.file.ReadFile();
if (data != null && !data.Equals(string.Empty))
{
this.DeserializeModel(Encoding.UTF8.GetBytes(data));
}
}
}
if (loadFromFile == true)
{
if (this.onLoaded != null)
{
this.onLoaded();
}
}
}
/// <summary>
/// Save the model data if necessary.
/// </summary>
public void SaveData()
{
if ((this.file != null)
&& ((this.isFileUpToDateOnSave == null) || (this.isFileUpToDateOnSave(this.model, this.file.GetFileInfo()) == false)))
{
if (this.onSaving != null)
{
this.onSaving();
}
byte[] data = this.SerializeModel();
this.file.WriteFile(data);
if (this.onSaved != null)
{
this.onSaved();
}
}
}
/// <summary>
/// Return the model io type.
/// </summary>
/// <returns>model io type</returns>
public ModelType GetModelType()
{
return this.modelType;
}
/// <summary>
/// Return the model.
/// </summary>
/// <returns>model object</returns>
public T GetModel()
{
return this.model;
}
/// <summary>
/// Abstract declaration of the model deserialize function.
/// </summary>
/// <param name="modelData">model data as byte array</param>
/// <returns>true, is succeeded</returns>
protected abstract bool DeserializeModel(byte[] modelData);
/// <summary>
/// Abstract declaration of the model serialize function.
/// </summary>
/// <returns>model data as byte array</returns>
protected abstract byte[] SerializeModel();
/// <summary>
/// Check if the model io type is file.
/// </summary>
/// <returns>true, if the model io type has file.</returns>
protected bool IsFile()
{
bool retValue = false;
if ((this.modelType & ModelType.File) != 0)
{
retValue = true;
}
return retValue;
}
/// <summary>
/// Check if the model io type is feed.
/// </summary>
/// <returns>true if the model io type has feed.</returns>
protected bool IsHttpApi()
{
bool retValue = false;
if ((this.modelType & ModelType.Feed) != 0)
{
retValue = true;
}
return retValue;
}
/// <summary>
/// Initializes the file object.
/// </summary>
/// <param name="readType">read io type (Default: sync)</param>
/// <param name="writeType">write io type (Default: async)</param>
private void InitFile(CampusAppWP8.Utility.File.IOTypeRead readType = CampusAppWP8.Utility.File.IOTypeRead.ReadSync, CampusAppWP8.Utility.File.IOTypeWrite writeType = CampusAppWP8.Utility.File.IOTypeWrite.WriteAsync)
{
if ((this.IsFile() == true)
&& (this.file == null))
{
this.file = new CampusAppWP8.Utility.File(this.fileName, readType, writeType);
}
}
/// <summary>
/// Initializes the web object.
/// </summary>
private void InitHttpApi()
{
if ((this.IsHttpApi() == true)
&& (this.api == null))
{
this.api = new HttpRequest();
}
}
/// <summary>
/// Is called after the loading from web is complete.
/// </summary>
/// <param name="sender">sending object</param>
/// <param name="e">event args</param>
private void OnLoadDataComplete(object sender, DownloadStringCompletedEventArgs e)
{
Exception downloadError = e.Error;
if (downloadError != null)
{
return;
}
string downloadResult = e.Result;
if (downloadResult != null && !downloadResult.Equals(string.Empty))
{
this.DeserializeModel(Encoding.UTF8.GetBytes(downloadResult));
}
if (this.onLoaded != null)
{
this.onLoaded();
}
}
}
}