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