//----------------------------------------------------------------------------- // // Company copyright tag. // // fiedlchr // 05.07.2013 //----------------------------------------------------------------------------- namespace CampusAppWPortalLib8.Model { using System; using System.Collections.Generic; using CampusAppWPortalLib8.Model.Utility; using CampusAppWPortalLib8.Utility; /// /// abstract Base model io handling class. /// /// 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. /// /// 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. /// /// 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. /// public delegate void OnIO(); /// /// Delegate of the OnFailed(File/Web) callback function. /// public delegate void OnFailed(); /// /// Delegate of the IsModelUpToDate callback function. /// /// 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 public event IsModelUpToDate IsModelUpToDateOnSave = null; #endregion #region Property /// /// Gets or sets the Model. /// public T Model { get { return this.model; } set { this.model = value; } } /// /// Gets or sets the File. /// public AbstractFile File { get { return this.file; } protected set { this.file = value; } } /// /// Gets or sets the ModelType. /// public ModelType ModelType { get { return this.modelType; } protected set { this.modelType = value; } } /// /// Gets or sets the Api. /// public AbstractHttpRequest Api { get { return this.api; } protected set { this.api = value; } } /// /// Gets or sets the ApiUrl. /// public Uri HttpApiUri { get { return this.httpApiUri; } protected set { this.httpApiUri = value; } } /// /// Gets or sets the FileName. /// public string FileName { get { return this.fileName; } protected set { this.fileName = value; } } #endregion #region Method #region public /// /// Method Fire all Events for fail load /// public void FireLoadFailEvents() { this.RunOnFailedCallback(this.OnFailedWeb, this.OnFailedLoad); } /// /// Method Fire all Events for load is complete /// public void FireLoadCompletedEvents() { this.RunOnIOCallback(this.OnLoaded); } /// /// Forces a update from web. /// public void ForceWebUpdate() { this.LoadData(ForceType.FORCE_WEB); } /// /// Forces a update from file. /// 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. /// /// 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. /// /// 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. /// /// model io type public ModelType GetModelType() { return this.modelType; } /// /// Create the parameterized uri. /// /// uri parameter list public void SetUriParams(List parameters) { if (this.api != null) { this.paramizedUri = this.api.CreateGetUrl(parameters); } } /// /// Clear the parameterized uri. /// public void ClearUriParams() { this.paramizedUri = null; } #endregion #region protected /// /// Abstract declaration of the model deserialize function. /// /// model data as byte array /// true, is succeeded protected abstract bool DeserializeModel(byte[] modelData); /// /// Abstract declaration of the model serialize function. /// /// model data as byte array protected abstract byte[] SerializeModel(); /// /// Method send a HttpGet /// /// the url protected abstract void SendHttpGet(Uri url); /// /// Method check if model or file is Not up-to-date /// /// 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 /// /// 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 /// /// true if it is not up-to-date, otherwise false protected abstract bool CheckSaveFileIsNotUpToDate(); /// /// Initializes the file object. /// protected abstract void InitFile(); /// /// Initializes the web object. /// protected abstract void InitHttpApi(); /// /// Check if the model io type is file. /// /// 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. /// /// 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. /// /// 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. /// /// The callback function. private void RunOnIOCallback(OnIO callbackFunc) { if (callbackFunc != null) { callbackFunc(); } } /// Executes the on failed callback operation. /// The special function. /// The default function. private void RunOnFailedCallback(OnFailed specialFunc, OnFailed defaultFunc) { if (specialFunc != null) { specialFunc(); } else if (defaultFunc != null) { defaultFunc(); } } #endregion #endregion } }