528 lines
18 KiB
C#
528 lines
18 KiB
C#
//-----------------------------------------------------------------------
|
|
// <copyright file="AbstractMainModel.cs" company="BTU/IIT">
|
|
// The MIT License (MIT). Copyright (c) 2013 BTU/IIT.
|
|
// </copyright>
|
|
// <author>fiedlchr</author>
|
|
// <date>15.10.2013</date>
|
|
// <summary>Implements the abstract main model class</summary>
|
|
//-----------------------------------------------------------------------
|
|
namespace CampusAppWPortalLib8.Model
|
|
{
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using CampusAppWPortalLib8.Model.Utility;
|
|
using CampusAppWPortalLib8.Utility;
|
|
|
|
/// <summary> abstract Base model io handling class. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
/// <typeparam name="T"> model type. </typeparam>
|
|
public abstract class AbstractMainModel<T>
|
|
{
|
|
#region Member
|
|
|
|
/// <summary> File object. </summary>
|
|
private AbstractFile file = null;
|
|
|
|
/// <summary> Model io type. </summary>
|
|
private ModelType modelType;
|
|
|
|
/// <summary> Model object. </summary>
|
|
private T model = default(T);
|
|
|
|
/// <summary> Web object. </summary>
|
|
private AbstractHttpRequest 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> Parameterized uri of the feed. </summary>
|
|
private Uri paramizedUri = null;
|
|
|
|
#endregion
|
|
|
|
#region Constructor
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="AbstractMainModel{T}" /> class.
|
|
/// </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
/// <param name="modelType"> Model IO type. </param>
|
|
/// <param name="fileName"> name of the file. </param>
|
|
/// <param name="url"> url of the feed. </param>
|
|
public AbstractMainModel(ModelType modelType, string fileName, string url)
|
|
{
|
|
this.Init(modelType, fileName, url);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="AbstractMainModel{T}" /> class.
|
|
/// </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
/// <exception cref="NotSupportedException">
|
|
/// Thrown when the requested operation is not supported.
|
|
/// </exception>
|
|
/// <param name="modelType"> Model IO type. </param>
|
|
/// <param name="sourceName"> name of the file or the url of the feed. </param>
|
|
public AbstractMainModel(ModelType modelType, string sourceName)
|
|
{
|
|
if (modelType == ModelType.File)
|
|
{
|
|
this.Init(modelType, sourceName, string.Empty);
|
|
}
|
|
else if (modelType == ModelType.Feed)
|
|
{
|
|
this.Init(modelType, string.Empty, sourceName);
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException("Wrong constructor was called for Feed and File support.");
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Events
|
|
|
|
/// <summary> Delegate of the OnIO callback function. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
public delegate void OnIO();
|
|
|
|
/// <summary> Delegate of the OnFailed(File/Web) callback function. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
public delegate void OnFailed();
|
|
|
|
/// <summary> Delegate of the IsModelUpToDate callback function. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
/// <param name="model"> data model. </param>
|
|
/// <returns> true, model is up to date. </returns>
|
|
public delegate bool IsModelUpToDate(T model);
|
|
|
|
/// <summary> Callback pointer, called before loading. </summary>
|
|
public event OnIO OnLoading = null;
|
|
|
|
/// <summary> Callback pointer, called after loading. </summary>
|
|
public event OnIO OnLoaded = null;
|
|
|
|
/// <summary> Callback pointer, called before saving. </summary>
|
|
public event OnIO OnSaving = null;
|
|
|
|
/// <summary> Callback pointer, called after saving. </summary>
|
|
public event OnIO OnSaved = null;
|
|
|
|
/// <summary> Callback pointer, called after failed file loading. </summary>
|
|
public event OnFailed OnFailedFile = null;
|
|
|
|
/// <summary> Callback pointer, called after failed web loading. </summary>
|
|
public event OnFailed OnFailedWeb = null;
|
|
|
|
/// <summary>
|
|
/// Callback pointer, called after failed file or web loading, if there is no specialized
|
|
/// onFailed callback set.
|
|
/// </summary>
|
|
public event OnFailed OnFailedLoad = null;
|
|
|
|
/// <summary> Callback pointer, called after failed saving data to file. </summary>
|
|
public event OnFailed OnFailedSave = 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>
|
|
#pragma warning disable 0067
|
|
/// <summary> Occurs when Is Model Up To Date On Save. </summary>
|
|
public event IsModelUpToDate IsModelUpToDateOnSave = null;
|
|
|
|
#endregion
|
|
|
|
#region Property
|
|
|
|
/// <summary> Gets or sets the Model. </summary>
|
|
/// <value> The model. </value>
|
|
public T Model
|
|
{
|
|
get
|
|
{
|
|
return this.model;
|
|
}
|
|
|
|
set
|
|
{
|
|
this.model = value;
|
|
}
|
|
}
|
|
|
|
/// <summary> Gets the File. </summary>
|
|
/// <value> The file. </value>
|
|
public AbstractFile File
|
|
{
|
|
get { return this.file; }
|
|
protected set { this.file = value; }
|
|
}
|
|
|
|
/// <summary> Gets the ModelType. </summary>
|
|
/// <value> The type of the model. </value>
|
|
public ModelType ModelType
|
|
{
|
|
get { return this.modelType; }
|
|
protected set { this.modelType = value; }
|
|
}
|
|
|
|
/// <summary> Gets the Api. </summary>
|
|
/// <value> The API. </value>
|
|
public AbstractHttpRequest Api
|
|
{
|
|
get { return this.api; }
|
|
protected set { this.api = value; }
|
|
}
|
|
|
|
/// <summary> Gets the ApiUrl. </summary>
|
|
/// <value> The HTTP API URI. </value>
|
|
public Uri HttpApiUri
|
|
{
|
|
get { return this.httpApiUri; }
|
|
protected set { this.httpApiUri = value; }
|
|
}
|
|
|
|
/// <summary> Gets the FileName. </summary>
|
|
/// <value> The name of the file. </value>
|
|
public string FileName
|
|
{
|
|
get { return this.fileName; }
|
|
protected set { this.fileName = value; }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Method
|
|
|
|
#region public
|
|
|
|
/// <summary> Method Fire all Events for fail load. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
public void FireLoadFailEvents()
|
|
{
|
|
this.RunOnFailedCallback(this.OnFailedWeb, this.OnFailedLoad);
|
|
}
|
|
|
|
/// <summary> Method Fire all Events for load is complete. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
public void FireLoadCompletedEvents()
|
|
{
|
|
this.RunOnIOCallback(this.OnLoaded);
|
|
}
|
|
|
|
/// <summary> Forces a update from web. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
public void ForceWebUpdate()
|
|
{
|
|
this.LoadData(ForceType.FORCE_WEB);
|
|
}
|
|
|
|
/// <summary> Forces a update from file. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
public void ForceReadFile()
|
|
{
|
|
this.LoadData(ForceType.FORCE_FILE);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Load the data if necessary, from web or from file, regarding if the file data is up to
|
|
/// date.
|
|
/// </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
/// <param name="force">
|
|
/// (Optional) if set/not invalid/not default, force to load from web or file.
|
|
/// </param>
|
|
public void LoadData(ForceType force = ForceType.INVALID)
|
|
{
|
|
this.RunOnIOCallback(this.OnLoading);
|
|
|
|
// check which source is used for loading the data
|
|
if (force == ForceType.INVALID)
|
|
{
|
|
// if the model is not up to date
|
|
if (this.CheckIsNotUpToDate(this.IsModelUpToDateOnLoad) == true)
|
|
{
|
|
force = ForceType.FORCE_FILE;
|
|
|
|
if (this.file != null)
|
|
{
|
|
// if the file does not exist or is size of 0 or is not
|
|
// up to date, then load from web
|
|
if ((this.file.Exist() == false)
|
|
|| (this.CheckLoadFileIsNotUpToDate() == true))
|
|
{
|
|
force = ForceType.FORCE_WEB;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// if the file object does not exist, load from web
|
|
force = ForceType.FORCE_WEB;
|
|
}
|
|
|
|
// if the web object does not exist, load from file
|
|
if (this.api == null)
|
|
{
|
|
force = ForceType.FORCE_FILE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// if it is up to date, nothing has to be loaded
|
|
this.RunOnIOCallback(this.OnLoaded);
|
|
}
|
|
}
|
|
|
|
// load from web
|
|
if (force == ForceType.FORCE_WEB)
|
|
{
|
|
if (this.api != null)
|
|
{
|
|
if (this.paramizedUri != null)
|
|
{
|
|
this.SendHttpGet(this.paramizedUri);
|
|
}
|
|
else
|
|
{
|
|
this.SendHttpGet(this.httpApiUri);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// if web object does not exist, call OnFailed callbacks
|
|
this.RunOnFailedCallback(this.OnFailedWeb, this.OnFailedLoad);
|
|
}
|
|
}
|
|
|
|
// load from file
|
|
if (force == ForceType.FORCE_FILE)
|
|
{
|
|
if (this.file != null)
|
|
{
|
|
byte[] data = this.file.ReadFile();
|
|
|
|
if (data == null)
|
|
{
|
|
this.RunOnFailedCallback(this.OnFailedFile, this.OnFailedLoad);
|
|
}
|
|
else
|
|
{
|
|
if (data.Length > 0)
|
|
{
|
|
this.DeserializeModel(data);
|
|
}
|
|
|
|
this.RunOnIOCallback(this.OnLoaded);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// if file object does not exist, call OnFailed callbacks
|
|
this.RunOnFailedCallback(this.OnFailedFile, this.OnFailedLoad);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary> Save the model data if necessary. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
/// <param name="force"> (Optional) force saving. DEFAULT: false. </param>
|
|
public void SaveData(bool force = false)
|
|
{
|
|
if ((this.file != null)
|
|
&& ((this.CheckSaveFileIsNotUpToDate() == true) || (force == true)))
|
|
{
|
|
this.RunOnIOCallback(this.OnSaving);
|
|
|
|
byte[] data = this.SerializeModel();
|
|
|
|
if ((this.OnSaved != null) && (this.OnFailedSave != null))
|
|
{
|
|
this.file.WriteFile(data, delegate { this.OnSaved(); }, delegate { this.OnFailedSave(); });
|
|
}
|
|
else if (this.OnSaved != null)
|
|
{
|
|
this.file.WriteFile(data, delegate { this.OnSaved(); }, null);
|
|
}
|
|
else if (this.OnFailedSave != null)
|
|
{
|
|
this.file.WriteFile(data, null, delegate { this.OnFailedSave(); });
|
|
}
|
|
else
|
|
{
|
|
this.file.WriteFile(data, null, null);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary> Return the model io type. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
/// <returns> model io type. </returns>
|
|
public ModelType GetModelType()
|
|
{
|
|
return this.modelType;
|
|
}
|
|
|
|
/// <summary> Create the parameterized uri. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
/// <param name="parameters"> uri parameter list. </param>
|
|
public void SetUriParams(List<UrlParamModel> parameters)
|
|
{
|
|
if (this.api != null)
|
|
{
|
|
this.paramizedUri = this.api.CreateGetUrl(parameters);
|
|
}
|
|
}
|
|
|
|
/// <summary> Clear the parameterized uri. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
public void ClearUriParams()
|
|
{
|
|
this.paramizedUri = null;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region protected
|
|
|
|
/// <summary> Abstract declaration of the model deserialize function. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
/// <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>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
/// <returns> model data as byte array. </returns>
|
|
protected abstract byte[] SerializeModel();
|
|
|
|
/// <summary> Method send a HttpGet. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
/// <param name="url"> the url. </param>
|
|
protected abstract void SendHttpGet(Uri url);
|
|
|
|
/// <summary> Method check if model or file is Not up-to-date. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
/// <param name="checkFunc"> the check function. </param>
|
|
/// <returns> true if it is not up-to-date, otherwise false. </returns>
|
|
protected abstract bool CheckIsNotUpToDate(object checkFunc);
|
|
|
|
/// <summary> Method check if file is Not up-to-date for load process. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
/// <returns> true if it is not up-to-date, otherwise false. </returns>
|
|
protected abstract bool CheckLoadFileIsNotUpToDate();
|
|
|
|
/// <summary> Method check if file is Not up-to-date for load process. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
/// <returns> true if it is not up-to-date, otherwise false. </returns>
|
|
protected abstract bool CheckSaveFileIsNotUpToDate();
|
|
|
|
/// <summary> Initializes the file object. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
protected abstract void InitFile();
|
|
|
|
/// <summary> Initializes the web object. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
protected abstract void InitHttpApi();
|
|
|
|
/// <summary> Check if the model io type is file. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
/// <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>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
/// <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;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region private
|
|
|
|
/// <summary> Initialize the class. Is called by the constructors. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
/// <param name="modelType"> model IO type. </param>
|
|
/// <param name="fileName"> name of the data file. </param>
|
|
/// <param name="url"> url of the feed data. </param>
|
|
private void Init(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();
|
|
}
|
|
|
|
if ((this.IsHttpApi() == true)
|
|
&& (url.Equals(string.Empty) == false))
|
|
{
|
|
this.InitHttpApi();
|
|
}
|
|
}
|
|
|
|
/// <summary> Executes the on i/o callback operation. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
/// <param name="callbackFunc"> The callback function. </param>
|
|
private void RunOnIOCallback(OnIO callbackFunc)
|
|
{
|
|
if (callbackFunc != null)
|
|
{
|
|
callbackFunc();
|
|
}
|
|
}
|
|
|
|
/// <summary> Executes the on failed callback operation. </summary>
|
|
/// <remarks> fiedlchr, 15.10.2013. </remarks>
|
|
/// <param name="specialFunc"> The special function. </param>
|
|
/// <param name="defaultFunc"> The default function. </param>
|
|
private void RunOnFailedCallback(OnFailed specialFunc, OnFailed defaultFunc)
|
|
{
|
|
if (specialFunc != null)
|
|
{
|
|
specialFunc();
|
|
}
|
|
else if (defaultFunc != null)
|
|
{
|
|
defaultFunc();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
}
|
|
} |