/// <summary> /// Erzeugt eine Instanz der Reminder Klasse, welche mit den Daten gefüllt /// wird, die der Nutzer eingegeben hat. /// </summary> /// <returns>Eine Instanz von Reminder, oder null, falls Erzeugung fehlschlägt.</returns> private Reminder createReminderFromEnteredData() { Moderator activeModerator = channelController.GetLocalModerator(); if (activeModerator == null) { Debug.WriteLine("No active moderator. Cannot continue."); return null; } DateTime selectedStartDateTmp = new DateTime(SelectedStartDate.Year, SelectedStartDate.Month, SelectedStartDate.Day, SelectedTime.Hours, SelectedTime.Minutes, SelectedTime.Seconds); DateTime selectedEndDateTmp = new DateTime(SelectedEndDate.Year, SelectedEndDate.Month, SelectedEndDate.Day, SelectedTime.Hours, SelectedTime.Minutes, SelectedTime.Seconds); selectedStartDateTmp = DateTime.SpecifyKind(selectedStartDateTmp, DateTimeKind.Local); selectedEndDateTmp = DateTime.SpecifyKind(selectedEndDateTmp, DateTimeKind.Local); DateTimeOffset reminderStartDate = new DateTimeOffset(selectedStartDateTmp); DateTimeOffset reminderEndDate = new DateTimeOffset(selectedEndDateTmp); //// Start und Ende-Datum //DateTimeOffset reminderStartDate = new DateTimeOffset(SelectedStartDate.Year, SelectedStartDate.Month, SelectedStartDate.Day, // SelectedTime.Hours, SelectedTime.Minutes, SelectedTime.Seconds, TimeZoneInfo.Local.BaseUtcOffset); //DateTimeOffset reminderEndDate = new DateTimeOffset(SelectedEndDate.Year, SelectedEndDate.Month, SelectedEndDate.Day, // SelectedTime.Hours, SelectedTime.Minutes, SelectedTime.Seconds, TimeZoneInfo.Local.BaseUtcOffset); int chosenInterval = IntervalValue; int channelId = SelectedChannel.Id; int authorId = activeModerator.Id; string enteredTitle = Title; string enteredContent = Text; Priority priority = Priority.NORMAL; if (IsPriorityHighSelected) { priority = Priority.HIGH; } bool ignoreFlag = SkipNextReminderDate; Reminder newReminder = new Reminder() { StartDate = reminderStartDate, EndDate = reminderEndDate, Interval = chosenInterval, ChannelId = channelId, AuthorId = authorId, Title = enteredTitle, Text = enteredContent, MessagePriority = priority, Ignore = ignoreFlag }; return newReminder; }
/// <summary> /// Holt den Reminder mit der angegebenen Id aus der lokalen Datenbank, sofern /// der Datensatz vorhanden ist. /// </summary> /// <param name="reminderId">Die Id des Reminders, der aus der DB geholt werden soll.</param> /// <returns>Ein Objekt vom Typ Reminder, oder null, falls kein Datensatz existiert hat.</returns> /// <exception cref="DatabaseException">Wirft DatabaseException, wenn Abruf der Daten fehlschlägt.</exception> public Reminder GetReminder(int reminderId) { Reminder reminder = null; // Frage das Mutex Objekt ab. Mutex mutex = DatabaseManager.GetDatabaseAccessMutexObject(); // Fordere Zugriff auf die Datenbank an. if (mutex.WaitOne(DatabaseManager.MutexTimeoutValue)) { using (SQLiteConnection conn = DatabaseManager.GetConnection()) { try { string sql = @"SELECT * FROM Reminder WHERE Id=?;"; int channelId, interval, authorId; string title, text; bool ignore; bool? isActive = null; Priority priority; DateTimeOffset startDate, endDate, creationDate, modificationDate; using (var stmt = conn.Prepare(sql)) { stmt.Bind(1, reminderId); if (stmt.Step() == SQLiteResult.ROW) { channelId = Convert.ToInt32(stmt["Channel_Id"]); startDate = DatabaseManager.DateTimeFromSQLite(stmt["StartDate"].ToString()); endDate = DatabaseManager.DateTimeFromSQLite(stmt["EndDate"].ToString()); creationDate = DatabaseManager.DateTimeFromSQLite(stmt["CreationDate"].ToString()); modificationDate = DatabaseManager.DateTimeFromSQLite(stmt["ModificationDate"].ToString()); interval = Convert.ToInt32(stmt["Interval"]); ignore = ((long)stmt["Ignore"] == 1) ? true : false; title = (string)stmt["Title"]; text = (string)stmt["Text"]; authorId = Convert.ToInt32(stmt["Author_Moderator_Id"]); priority = (Priority)Enum.ToObject(typeof(Priority), stmt["Priority"]); if (stmt["Active"] != null) { isActive = ((long)stmt["Active"] == 1) ? true : false; } reminder = new Reminder(reminderId, creationDate, modificationDate, startDate, endDate, interval, ignore, channelId, authorId, title, text, priority); reminder.IsActive = isActive; // Setze IsActive Property. } } } catch (SQLiteException sqlEx) { Debug.WriteLine("Extraction of reminder with id {0} has failed. Msg is: {1}.", reminderId, sqlEx.Message); throw new DatabaseException(sqlEx.Message); } catch (Exception ex) { Debug.WriteLine("GetReminder has failed. The message is: {0} and stack trace is {1}.", ex.Message, ex.StackTrace); throw new DatabaseException(ex.Message); } finally { mutex.ReleaseMutex(); } } } else { Debug.WriteLine("Couldn't get access to database. Time out."); throw new DatabaseException("Could not get access to the database."); } return reminder; }
/// <summary> /// Aktualisiert das Datum des nächsten Termins, an dem der Reminder feuert. /// </summary> private void updateNextReminderDate() { Debug.WriteLine("In updateNextReminderDate."); if (SelectedStartDate == DateTimeOffset.MinValue || SelectedEndDate == DateTimeOffset.MinValue) return; DateTime selectedStartDateTmp = new DateTime(SelectedStartDate.Year, SelectedStartDate.Month, SelectedStartDate.Day, SelectedTime.Hours, SelectedTime.Minutes, SelectedTime.Seconds); DateTime selectedEndDateTmp = new DateTime(SelectedEndDate.Year, SelectedEndDate.Month, SelectedEndDate.Day, SelectedTime.Hours, SelectedTime.Minutes, SelectedTime.Seconds); selectedStartDateTmp = DateTime.SpecifyKind(selectedStartDateTmp, DateTimeKind.Local); selectedEndDateTmp = DateTime.SpecifyKind(selectedEndDateTmp, DateTimeKind.Local); DateTimeOffset reminderStartDate = new DateTimeOffset(selectedStartDateTmp); DateTimeOffset reminderEndDate = new DateTimeOffset(selectedEndDateTmp); //DateTimeOffset reminderStartDate = new DateTimeOffset(SelectedStartDate.Year, SelectedStartDate.Month, SelectedStartDate.Day, // SelectedTime.Hours, SelectedTime.Minutes, SelectedTime.Seconds, TimeZoneInfo.Local.BaseUtcOffset); //DateTimeOffset reminderEndDate = new DateTimeOffset(SelectedEndDate.Year, SelectedEndDate.Month, SelectedEndDate.Day, // SelectedTime.Hours, SelectedTime.Minutes, SelectedTime.Seconds, TimeZoneInfo.Local.BaseUtcOffset); // Erzeuge Reminder Objekt mit aktuellen Daten und lasse den nächsten // Reminder Zeitpunkt bestimmen. Reminder reminderTmp = new Reminder() { StartDate = reminderStartDate, EndDate = reminderEndDate, Ignore = SkipNextReminderDate, Interval = IntervalValue }; reminderTmp.ComputeFirstNextDate(); reminderTmp.EvaluateIsExpired(); if (reminderTmp.IsExpired) { Debug.WriteLine("Reminder is expired."); IsReminderExpired = true; } else { IsReminderExpired = false; } NextReminderDate = reminderTmp.NextDate; }
/// <summary> /// Speichert den übergebenen Reminder in der lokalen Datenbank ab. /// </summary> /// <param name="reminder">Das Reminder Objekt mit den Daten des Reminder.</param> /// <exception cref="DatabaseException">Wirft eine DatabaseException, wenn das Abspeichern fehlschlägt.</exception> public void StoreReminder(Reminder reminder) { if (reminder == null) return; // Frage das Mutex Objekt ab. Mutex mutex = DatabaseManager.GetDatabaseAccessMutexObject(); // Fordere Zugriff auf die Datenbank an. if (mutex.WaitOne(DatabaseManager.MutexTimeoutValue)) { using (SQLiteConnection conn = DatabaseManager.GetConnection()) { try { string sql = @"INSERT INTO Reminder (Id, Channel_Id, StartDate, EndDate, CreationDate, ModificationDate, ""Interval"", ""Ignore"", Title, Text, Priority, Author_Moderator_Id, Active) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"; using (var insertStmt = conn.Prepare(sql)) { insertStmt.Bind(1, reminder.Id); insertStmt.Bind(2, reminder.ChannelId); insertStmt.Bind(3, DatabaseManager.DateTimeToSQLite(reminder.StartDate)); insertStmt.Bind(4, DatabaseManager.DateTimeToSQLite(reminder.EndDate)); insertStmt.Bind(5, DatabaseManager.DateTimeToSQLite(reminder.CreationDate)); insertStmt.Bind(6, DatabaseManager.DateTimeToSQLite(reminder.ModificationDate)); insertStmt.Bind(7, reminder.Interval); insertStmt.Bind(8, (reminder.Ignore) ? 1 : 0); insertStmt.Bind(9, reminder.Title); insertStmt.Bind(10, reminder.Text); insertStmt.Bind(11, (int)reminder.MessagePriority); insertStmt.Bind(12, reminder.AuthorId); if (reminder.IsActive == null) { insertStmt.Bind(13, reminder.IsActive); } else { insertStmt.Bind(13, (reminder.IsActive == true) ? 1 : 0); } insertStmt.Step(); Debug.WriteLine("Stored reminder with id {0}.", reminder.Id); } } catch (SQLiteException sqlEx) { Debug.WriteLine("Couldn't store reminder with id {0}.", reminder.Id); throw new DatabaseException(sqlEx.Message); } catch (Exception ex) { Debug.WriteLine("StoreReminder has failed. The message is: {0} and stack trace is {1}.", ex.Message, ex.StackTrace); throw new DatabaseException(ex.Message); } finally { mutex.ReleaseMutex(); } } } else { Debug.WriteLine("Couldn't get access to database. Time out."); throw new DatabaseException("Could not get access to the database."); } }
/// <summary> /// Aktualisiert den lokalen Datensatz für den übergebenen Reminder. /// Schreibt die Werte des übergebenen Objekts als neuen Datensatz anstelle des alten /// Datensatzes in die Datenbank. /// </summary> /// <param name="updatedReminder">Das Reminder Objekt mit den aktualisierten Reminder-Daten.</param> /// <exception cref="DatabaseException">Wirft DatabaseException, wenn Update fehlschlägt.</exception> public void UpdateReminder(Reminder updatedReminder) { if (updatedReminder == null) return; // Frage das Mutex Objekt ab. Mutex mutex = DatabaseManager.GetDatabaseAccessMutexObject(); // Fordere Zugriff auf die Datenbank an. if (mutex.WaitOne(DatabaseManager.MutexTimeoutValue)) { using (SQLiteConnection conn = DatabaseManager.GetConnection()) { try { string sql = @"UPDATE Reminder SET Channel_Id=?, StartDate=?, EndDate=?, CreationDate=?, ModificationDate=?, ""Interval""=?, ""Ignore""=?, Title=?, Text=?, Priority=?, Author_Moderator_Id=?, Active=? WHERE Id=?;"; using (var updateStmt = conn.Prepare(sql)) { updateStmt.Bind(1, updatedReminder.ChannelId); updateStmt.Bind(2, DatabaseManager.DateTimeToSQLite(updatedReminder.StartDate)); updateStmt.Bind(3, DatabaseManager.DateTimeToSQLite(updatedReminder.EndDate)); updateStmt.Bind(4, DatabaseManager.DateTimeToSQLite(updatedReminder.CreationDate)); updateStmt.Bind(5, DatabaseManager.DateTimeToSQLite(updatedReminder.ModificationDate)); updateStmt.Bind(6, updatedReminder.Interval); updateStmt.Bind(7, (updatedReminder.Ignore) ? 1 : 0); updateStmt.Bind(8, updatedReminder.Title); updateStmt.Bind(9, updatedReminder.Text); updateStmt.Bind(10, (int)updatedReminder.MessagePriority); updateStmt.Bind(11, updatedReminder.AuthorId); updateStmt.Bind(12, (updatedReminder.IsActive == true) ? 1 : 0); updateStmt.Bind(13, updatedReminder.Id); if (updateStmt.Step() != SQLiteResult.DONE) Debug.WriteLine("Update for reminder with id {0} has failed.", updatedReminder.Id); else Debug.WriteLine("Successfully updated reminder with id {0}.", updatedReminder.Id); } } catch (SQLiteException sqlEx) { Debug.WriteLine("Update of reminder with id {0} has failed. Msg is: {1}.", updatedReminder.Id, sqlEx.Message); throw new DatabaseException(sqlEx.Message); } catch (Exception ex) { Debug.WriteLine("Update of reminder has failed. The message is: {0} and stack trace is {1}.", ex.Message, ex.StackTrace); throw new DatabaseException(ex.Message); } finally { mutex.ReleaseMutex(); } } } else { Debug.WriteLine("Couldn't get access to database. Time out."); throw new DatabaseException("Could not get access to the database."); } }
/// <summary> /// Hilfsmethode, die eine Speicherung eines Reminders realisiert, bei der /// fehlende Informationen zunächst vom Server abgefragt werden. /// Beachte: Mögliche Fehler werden von dieser Methode nicht zurückgeliefert. /// </summary> /// <param name="reminder">Der zu speichernde Reminder.</param> private async Task storeReminderIncludingRelevantInformationAsync(Reminder reminder) { Debug.WriteLine("Starting storeReminderIncludingRelevantInformationAsync."); try { List<Moderator> moderators = await GetResponsibleModeratorsAsync(reminder.ChannelId); if (moderators == null) return; foreach (Moderator moderator in moderators) { if (!moderatorDatabaseManager.IsModeratorStored(moderator.Id)) { Debug.WriteLine("Need to store moderator with id {0} in local DB.", moderator.Id); moderatorDatabaseManager.StoreModerator(moderator); } if (moderator.IsActive) { if (!channelDatabaseManager.IsResponsibleForChannel(reminder.ChannelId, moderator.Id)) { Debug.WriteLine("Need to add moderator with id {0} as responsible moderator for channel with id {1}.", moderator.Id, reminder.ChannelId); channelDatabaseManager.AddModeratorToChannel(reminder.ChannelId, moderator.Id, true); } } } if (!moderatorDatabaseManager.IsModeratorStored(reminder.AuthorId)) { // Wenn noch immer der Moderator fehlt, dann bilde ab auf Dummy Moderator. Debug.WriteLine("Need to map author to dummy moderator."); reminder.AuthorId = 0; } // Speichere reminder. channelDatabaseManager.StoreReminder(reminder); Debug.WriteLine("Finished storeReminderIncludingRelevantInformationAsync."); } catch (DatabaseException ex) { Debug.WriteLine("Fallback method storeReminderIncludingRelevantInformationAsync failed due to database exception." + "Reminder with id {0} couldn't be stored. Msg is: {1}", reminder.Id, ex.Message); } catch (ClientException clientEx) { Debug.WriteLine("Fallback method storeReminderIncludingRelevantInformationAsync failed due to client exception." + "Reminder with id {0} couldn't be stored. ErrorCode is: {1}", reminder.Id, clientEx.ErrorCode); } }
/// <summary> /// Aktualisiert die für die View relevanten Parameter eines Reminder Objekts, welches aktuell /// vom ViewModel gehalten wird. /// </summary> /// <param name="currentReminder">Die aktuell gehaltene Reminder-Instanz.</param> /// <param name="newReminder">Die Reminder-Instanz mit den neuen Daten.</param> private void updateViewRelatedPropertiesOfReminder(Reminder currentReminder, Reminder newReminder) { currentReminder.StartDate = newReminder.StartDate; currentReminder.EndDate = newReminder.EndDate; currentReminder.Interval = newReminder.Interval; currentReminder.Ignore = newReminder.Ignore; currentReminder.IsActive = newReminder.IsActive; currentReminder.Text = newReminder.Text; currentReminder.Title = newReminder.Title; currentReminder.MessagePriority = newReminder.MessagePriority; currentReminder.ModificationDate = newReminder.ModificationDate; currentReminder.AuthorId = newReminder.AuthorId; currentReminder.ComputeFirstNextDate(); currentReminder.EvaluateIsExpired(); }
/// <summary> /// Erstellt ein Objekt vom Typ Reminder, bei welchem genau die Felder gesetzt sind, die sich /// bei den übergebenen Instanzen geändert haben. Das zurückgelieferte Objekt enthält dabei die aktualisierten /// Werte in den geänderten Feldern. Das zurückgegebene Objekt kann direkt für einen Aktualisierungsrequest an den /// Server genutzt werden. Gab es überhaupt keine Änderung so liefert die Methode null zurück. /// </summary> /// <param name="oldReminder">Das Objekt mit den Daten vor der Aktualisierung.</param> /// <param name="newReminder">Das Objekt mit den aktualisierten Werten.</param> /// <returns>Ein Objekt vom Typ Reminder, in welchem genau die Felder gesetzt sind, die /// sich geändert haben. Liefert null, wenn es gar keine Änderung gab.</returns> private Reminder createUpdatableReminderInstance(Reminder oldReminder, Reminder newReminder) { bool hasChanged = false; Reminder updatableReminder = new Reminder(); if (DateTimeOffset.Compare(oldReminder.StartDate, newReminder.StartDate) != 0) { hasChanged = true; updatableReminder.StartDate = newReminder.StartDate; } if (DateTimeOffset.Compare(oldReminder.EndDate, newReminder.EndDate) != 0) { hasChanged = true; updatableReminder.EndDate = newReminder.EndDate; } if (oldReminder.Interval != newReminder.Interval) { hasChanged = true; updatableReminder.Interval = newReminder.Interval; } if (oldReminder.Ignore != newReminder.Ignore) { hasChanged = true; updatableReminder.Ignore = newReminder.Ignore; } if (oldReminder.Text != newReminder.Text) { hasChanged = true; updatableReminder.Text = newReminder.Text; } if (oldReminder.Title != newReminder.Title) { hasChanged = true; updatableReminder.Title = newReminder.Title; } // Beachte: Message Priority muss gesetzt werden, da sonst der Default-Wert beim JSON Parsing // in das JSON Dokument geschrieben wird und dadurch ungewollt die Einstellung des Reminder ändern könnte. if (oldReminder.MessagePriority != newReminder.MessagePriority) { hasChanged = true; updatableReminder.MessagePriority = newReminder.MessagePriority; } else { updatableReminder.MessagePriority = oldReminder.MessagePriority; } // Prüfe, ob sich überhaupt eine Property geändert hat. if (!hasChanged) { Debug.WriteLine("No Property of reminder has been updated. Method will return null."); updatableReminder = null; } return updatableReminder; }
/// <summary> /// Sende Request zum Ändern des Aktivitätszustandes des Reminders mit der angegebenen Id /// zum Server. Die Aktualisierung wird auf dem Server vorgenommen. /// </summary> /// <param name="channelId">Die Id des Kanals zu dem der Reminder gehört.</param> /// <param name="reminderId">Die Id des Reminder, dessen Aktivitätszustand geändert werden soll.</param> /// <param name="isActive">Der neue Zustand.</param> /// <returns>Liefert true, wenn Aktualisierung erfolgreich, ansonsten false.</returns> /// <exception cref="ClientException">Wirft ClientException, wenn Aktualisierungsrequest nicht erfolgreich, /// oder ein anderes Problem aufgetreten ist.</exception> public async Task<bool> ChangeReminderActiveStatusAsync(int channelId, int reminderId, bool? isActive) { Moderator activeModerator = GetLocalModerator(); if (activeModerator == null) return false; // Erstelle Reminder-Objekt für Aktualisierungsrequest. Reminder updatableReminder = new Reminder() { Id = reminderId, ChannelId = channelId, IsActive = isActive }; // Generiere Json-Dokument. string jsonContent = jsonParser.ParseReminderToJson(updatableReminder); if (jsonContent == null) return false; string serverResponse = null; try { // Sende Request an den Server. serverResponse = await channelApi.SendUpdateReminderRequestAsync( activeModerator.ServerAccessToken, channelId, reminderId, jsonContent); } catch (APIException ex) { if (ex.ErrorCode == ErrorCodes.ChannelNotFound) { Debug.WriteLine("Channel not found on server. Channel probably deleted."); // Behandlung Not Found. Kanal wahrscheinlich gelöscht. MarkChannelAsDeleted(channelId); } if (ex.ErrorCode == ErrorCodes.ReminderNotFound) { Debug.WriteLine("Reminder not found on server. Reminder probably deleted."); // Behandlung von Not Found. Reminder wahrscheinlich gelöscht. DeleteLocalReminder(reminderId); } Debug.WriteLine("Update request for reminder with id {0} has failed.", reminderId); throw new ClientException(ex.ErrorCode, ex.Message); } // Parse Server Antwort. if (serverResponse != null) { Reminder updatedReminder = jsonParser.ParseReminderFromJson(serverResponse); if (updatableReminder != null) { // Aktualisiere lokalen Datensatz. ReplaceLocalReminder(updatedReminder); } } return true; }
/// <summary> /// Aktualisiert einen Reminder. Ermittelt die zu aktualisierenden Properties und führt einen /// Aktualisierungsrequest an den Server aus, um die Ressource zu aktualisieren. Bei einer erfolgreichen /// Aktualisierung wird auch der lokal gehaltene Datensatz aktualisiert. /// </summary> /// <param name="oldReminder">Das Reminder Objekt mit den Daten vor der Aktualisierung.</param> /// <param name="newReminder">Das Reminder Objekt mit den aktualisiertern Daten.</param> /// <returns>Liefert true, wenn die Aktualisierung erfolgreich durchgeführt werden konnte. /// Liefert false, wenn Aktualisierung fehlgeschlagen ist, z.B. aufgrund eines Validierungsfehlers.</returns> /// <exception cref="ClientException">Wirft eine ClientException, wenn ein Fehler während der Aktualisierung auftritt, der /// dem Nutzer gemeldet werden muss, z.B. wenn der Server den Request abgelehnt hat.</exception> public async Task<bool> UpdateReminderAsync(Reminder oldReminder, Reminder newReminder) { if (oldReminder == null || newReminder == null) return false; Moderator activeModerator = GetLocalModerator(); if (activeModerator == null) return false; // Validiere zunächst die neu eingegebenen Daten, bei Validierungsfehlern kann hier gleich abgebrochen werden. clearValidationErrors(); newReminder.ClearValidationErrors(); newReminder.ValidateAll(); if (newReminder.HasValidationErrors()) { // Melde Validierungsfehler und breche ab. reportValidationErrors(newReminder.GetValidationErrors()); return false; } // Erstelle Objekt für Aktualisierungsrequest an den Server. Reminder updatableReminder = createUpdatableReminderInstance(oldReminder, newReminder); if (updatableReminder == null) { Debug.WriteLine("No changes in reminder object detected. No update request required."); return true; } // Generiere Json-Dokument. string jsonContent = jsonParser.ParseReminderToJson(updatableReminder); if (jsonContent == null) return false; string serverResponse = null; try { // Sende Request an den Server. serverResponse = await channelApi.SendUpdateReminderRequestAsync( activeModerator.ServerAccessToken, oldReminder.ChannelId, oldReminder.Id, jsonContent); } catch (APIException ex) { if (ex.ErrorCode == ErrorCodes.ChannelNotFound) { Debug.WriteLine("Channel not found on server. Channel probably deleted."); // Behandlung Not Found. Kanal wahrscheinlich gelöscht. MarkChannelAsDeleted(oldReminder.ChannelId); } if (ex.ErrorCode == ErrorCodes.ReminderNotFound) { Debug.WriteLine("Reminder not found on server. Reminder probably deleted."); // Behandlung von Not Found. Reminder wahrscheinlich gelöscht. DeleteLocalReminder(oldReminder.Id); } Debug.WriteLine("Update request for reminder with id {0} has failed.", oldReminder.Id); throw new ClientException(ex.ErrorCode, ex.Message); } // Parse Server Antwort. if (serverResponse != null) { Reminder updatedReminder = jsonParser.ParseReminderFromJson(serverResponse); if (updatableReminder != null) { ReplaceLocalReminder(updatedReminder); } } return true; }
/// <summary> /// Erzeugt einen neuen Reminder. Führt die /// Validierung der Daten durch. Überträgt die Reminder-Daten an den Server und /// speichert die Daten lokal ab, wenn die Bestätigung vom Server kommt. /// </summary> /// <param name="newReminder">Das Objekt, welches die Daten des neu anzulegenden /// Reminders beinhaltet.</param> /// <returns>Liefert true, wenn Reminder erfolgreich angelegt werden konnte, sonst false.</returns> /// <exception cref="ClientException">Wirft ClientException, wenn ein Fehler während des Erstellungsvorgangs auftritt. /// Beispielsweise dann, wenn der Server den Request ablehnt.</exception> public async Task<bool> CreateReminderAsync(Reminder newReminder) { if (newReminder == null) return false; Moderator activeModerator = GetLocalModerator(); if (activeModerator == null) { Debug.WriteLine("No active moderator. Need to abort CreateReminderAsync."); return false; } // Führe Validierung durch. clearValidationErrors(); newReminder.ClearValidationErrors(); newReminder.ValidateAll(); if (newReminder.HasValidationErrors()) { // Melde Validierungsfehler und breche ab. reportValidationErrors(newReminder.GetValidationErrors()); return false; } // Erstelle JSON-Dokument. string jsonContent = jsonParser.ParseReminderToJson(newReminder); if (jsonContent == null) { Debug.WriteLine("Couldn't parse reminder to json. Need to abort execution."); return false; } string serverResponse = null; try { // Setzte Request an Server ab. serverResponse = await channelApi.SendCreateReminderRequestAsync( activeModerator.ServerAccessToken, newReminder.ChannelId, jsonContent); } catch (APIException ex) { if (ex.ErrorCode == ErrorCodes.ChannelNotFound) { Debug.WriteLine("Channel not found on server. Channel probably deleted."); // Behandlung Not Found. Kanal wahrscheinlich gelöscht. MarkChannelAsDeleted(newReminder.ChannelId); } Debug.WriteLine("Request to create reminder has failed."); throw new ClientException(ex.ErrorCode, ex.Message); } // Parse Reminder aus Server-Antwort. Reminder createdReminder = jsonParser.ParseReminderFromJson(serverResponse); if (createdReminder != null) { createdReminder.IsActive = true; // Ist aktiv, wenn er gerade erstellt wurde. // Speichere Reminder lokal ab. StoreReminder(createdReminder); } return true; }
/// <summary> /// Ersetze die lokal verwaltete Reminderressource durch eine neuere Version /// derselben Ressource. /// </summary> /// <param name="newReminder">Die neuere Version der Reminderressource.</param> /// <exception cref="ClientException">Wirft eine ClientException, wenn ein Fehler /// während des Vorgangs auftritt.</exception> public void ReplaceLocalReminder(Reminder newReminder) { try { channelDatabaseManager.UpdateReminder(newReminder); } catch (DatabaseException ex) { Debug.WriteLine("Failed to replace local reminder."); throw new ClientException(ErrorCodes.LocalDatabaseException, ex.Message); } }
/// <summary> /// Speichere den Reminder lokal im Speicher ab. /// </summary> /// <param name="reminder">Das Reminder Objekt mit den Reminder Daten.</param> /// <exception cref="ClientException">Wirft Exception, wenn Speichern fehlschlägt.</exception> public void StoreReminder(Reminder reminder) { try { if (!moderatorDatabaseManager.IsModeratorStored(reminder.AuthorId)) { Debug.WriteLine("Missing author. Can't store reminder directly. Start fallback method"); Task.Run(() => storeReminderIncludingRelevantInformationAsync(reminder)); } else { channelDatabaseManager.StoreReminder(reminder); } } catch (DatabaseException ex) { Debug.WriteLine("Failed to store reminder."); throw new ClientException(ErrorCodes.LocalDatabaseException, ex.Message); } }
/// <summary> /// Serialisiert ein Objekt vom Typ Reminder in ein JSON-Dokument. /// </summary> /// <param name="reminder">Das zu serialisierende Objekt.</param> /// <returns>Das Objekt in Form eines JSON-Dokument, oder null, wenn die Umwandlung fehlgeschlagen ist.</returns> public string ParseReminderToJson(Reminder reminder) { if (reminder == null) return null; string jsonContent = null; try { //// Spezielle Serialisierungssettings für Datum. //JsonSerializerSettings utcDateSettings = new JsonSerializerSettings(); //utcDateSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc; //Newtonsoft.Json.Converters.IsoDateTimeConverter dateConverter = new Newtonsoft.Json.Converters.IsoDateTimeConverter //{ // DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffzz" //}; //utcDateSettings.Converters.Add(dateConverter); jsonContent = JsonConvert.SerializeObject(reminder); // Anpassung Json Content zwecks Datumsformat. string finalJson = string.Empty; string[] parts = jsonContent.Split(new string[] { "," }, StringSplitOptions.None); foreach (string part in parts) { if (part.Contains("startDate") || part.Contains("endDate")) { string[] splittedDate = part.Split(new string[] { ":" }, StringSplitOptions.None); // Füge Teil 1 wieder an, ebenso wie den Doppelpunkt. finalJson += splittedDate[0] + ":"; string date = string.Empty; if (splittedDate[0].Contains("\"startDate\"")) { // Parse Datum mit eigener Parse Methode. date = "\"" + parseDateTimeToISO8601Format(reminder.StartDate) + "\""; } else if (splittedDate[0].Contains("\"endDate\"")) { // Parse Datum mit eigener Parse Methode. date = "\"" + parseDateTimeToISO8601Format(reminder.EndDate) + "\""; } // Füge Datum an. finalJson += date; //finalJson += part.Substring(0, finalJson.Length - 1) + ".000Z" + part.Substring(finalJson.Length - 1, 1); // Füge Millisekunden Bereich an. } else { finalJson += part; } finalJson += ","; } finalJson = finalJson.Substring(0, finalJson.Length - 1); Debug.WriteLine("JsonParsingManager: Final json is: {0}", finalJson); jsonContent = finalJson; } catch (JsonException jsonEx) { Debug.WriteLine("JsonParsingManager: Could not serialize reminder to json."); Debug.WriteLine("JsonParsingManager: Message is: {0}.", jsonEx.Message); } return jsonContent; }