/// <summary> /// Aktualisiert den Nutzernamen des lokalen Nutzers der Anwendung, falls eine Änderung /// gegenüber dem aktuellen Nutzernamen vorliegt. Die Aktualisierung erfolgt sowohl lokal, /// als auch auf dem REST Server. /// </summary> /// <param name="username">Der neue Nutzername des lokalen Nutzers.</param> /// <exception cref="ClientException">Wirft ClientException, wenn Aktualisierung nicht durchgeführt werden konnte.</exception> public async Task<bool> UpdateLocalUsernameAsync(string username) { User currentLocalUser = base.getLocalUser(); // Prüfe, ob der Name aktualisiert werden muss. if(String.Compare(currentLocalUser.Name, username) != 0) { // Setze neuen Namen in ein Nutzer Objekt und führe Eingabevalidierung durch. User tmpLocalUser = new User(); tmpLocalUser.Name = username; tmpLocalUser.ValidateNameProperty(); if(tmpLocalUser.HasValidationError("Name")) { // Melde Validationsfehler und breche ab. base.reportValidationErrors(tmpLocalUser.GetValidationErrors()); return false; } else { tmpLocalUser.ClearValidationErrors(); base.clearValidationErrorForProperty("Name"); } // Verwende Funktionalität im LocalUserController, um die Aktualisierung des Namens durchzuführen. await localUserController.UpdateLocalUserAsync(username, null); } return true; }
/// <summary> /// Erzeugt ein JSON-Dokument aus dem übergebenen User-Objekt. /// </summary> /// <param name="user">Das zu serialisierende User Objekt.</param> /// <returns>Ein generiertes JSON-Dokument mit den Nutzerdaten, oder null falls Serialisierung fehlschlägt.</returns> public string ParseUserToJsonString(User user) { string jsonContent = null; try { jsonContent = JsonConvert.SerializeObject(user); } catch (JsonException ex) { Debug.WriteLine("JsonParsingManager: Error during serialization of user object. " + "Exception is: " + ex.Message); } return jsonContent; }
/// <summary> /// Speichert einen Datensatz einer Nutzer-Ressource lokal ab. /// </summary> /// <param name="user">Der zu speichernde Datensatz in Form eines Nutzer Objekts.</param> /// <exception cref="ClientException">Wirft ClientException, wenn Speicherung fehlschlägt.</exception> public void StoreUserLocally(User user) { try { userDBManager.StoreUser(user); } catch (DatabaseException ex) { Debug.WriteLine("StoreUserLocally: Failed to store the user in local DB. Msg is {0}.", ex.Message); throw new ClientException(ErrorCodes.LocalDatabaseException, ex.Message); } }
/// <summary> /// Erstelle einen lokalen Nutzeraccount. /// </summary> /// <param name="name">Der Name für den Nutzer.</param> /// <returns>Liefert true zurück, wenn der Account erfolgreich angelegt wurde. False, wenn die Validierung fehlgeschlagen hat.</returns> /// <exception cref="ClientException">Wirft eine ClientException, wenn die Erstellung des Nutzeraccounts wegen eines aufgetretenen Fehlers fehlschlägt.</exception> public async Task<bool> CreateLocalUserAsync(string name) { Debug.WriteLine("Starting createLocalUser()."); // TODO: Platziere diesen Code woanders und gebe ihn über einen Parameter an diese Methode. // Frage eine Kanal-URI vom WNS ab, die dann als PushAccessToken für diesen Nutzer dient. PushNotificationChannel pushChannel = null; try { pushChannel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync(); Debug.WriteLine("Received a channel URI: " + pushChannel.Uri); } catch (Exception ex) { Debug.WriteLine("Exception occurred in CreateLocalUserAsync during WNS initialization. The message is: {0}.", ex.Message); // Abbilden auf ClientException. throw new ClientException(ErrorCodes.WnsChannelInitializationFailed, "Initialization of channel to WNS has failed."); } User localUser = new User(); localUser.Name = name; localUser.PushAccessToken = pushChannel.Uri; localUser.Platform = DataHandlingLayer.DataModel.Enums.Platform.WINDOWS; // Führe Datenvalidierung auf Property Name aus. localUser.ClearValidationErrors(); clearValidationErrorForProperty("Name"); localUser.ValidateNameProperty(); if(localUser.HasValidationError("Name")) { reportValidationErrors(localUser.GetValidationErrors()); return false; } // Generiere Json String aus dem Objekt. string jsonContent = jsonParser.ParseUserToJsonString(localUser); Debug.WriteLine("The json String is: " + jsonContent); if (jsonContent == null) { Debug.WriteLine("Error during serialization to json. Cannot continue."); throw new ClientException(ErrorCodes.JsonParserError, "Creation of user account has failed."); } // Sende einen Request zum Erstellen eines Nutzeraccounts. string responseString; try { responseString = await userAPI.SendCreateUserRequestAsync(jsonContent); } catch (APIException e) { Debug.WriteLine("Error occured. The creation of the user account has failed."); Debug.WriteLine("The error code is: " + e.ErrorCode + " and the status code of the response is: " + e.ResponseStatusCode); // Abbilden des aufgetretenen Fehlers auf eine ClientException. throw new ClientException(e.ErrorCode, "Creation of user account has failed."); } // Deserialisiere den Antwort String des Servers. localUser = jsonParser.ParseUserFromJson(responseString); // Speichere den erstellten Nutzeraccount in der Datenbank ab. if (localUser != null) { try { localUserDB.StoreLocalUser(localUser); } catch (DatabaseException ex) { Debug.WriteLine("A exception occurred in the local database. Exception message is: " + ex.Message); // Abbilden des aufgetretenen Fehlers auf eine ClientException. throw new ClientException(ErrorCodes.LocalDatabaseException, "Creation of user account has failed."); } } else { // Abbilden des aufgetretenen Fehlers auf eine ClientException. throw new ClientException(ErrorCodes.JsonParserError, "Creation of user account has failed."); } Debug.WriteLine("Finished createLocalUser()."); return true; }
/// <summary> /// Fügt den übergebenen Nutzer als aktiven Nutzer der Gruppe mit der angegebenen Id hinzu. /// </summary> /// <param name="groupId">Die Id der Gruppe.</param> /// <param name="user">Der hinzuzufügende Nutzer.</param> /// <exception cref="ClientException">Wirft ClientException, wenn Aktion fehlschlägt.</exception> public void AddParticipantToGroup(int groupId, User user) { if (!groupDBManager.IsGroupStored(groupId)) { Debug.WriteLine("AddParticipantToGroup: There is no group with id {0} in the local datasets.", groupId); throw new ClientException(ErrorCodes.GroupNotFound, "Cannot continue without stored group."); } // Prüfe, ob der Nutzer schon in den lokalen Datensätzen gespeichert ist. bool stored = userController.IsUserLocallyStored(user.Id); if (!stored) { userController.StoreUserLocally(user); } // Füge Nutzer als aktiver Teilnehmer der Gruppe hinzu. try { bool? activeStatus = groupDBManager.RetrieveActiveStatusOfParticipant(groupId, user.Id); if (!activeStatus.HasValue) { // Teilnehmer noch nicht in Gruppe. groupDBManager.AddParticipantToGroup(groupId, user.Id, true); } else if (activeStatus.Value == false) { // Setze Teilnehmer wieder in den aktiven Zustand. groupDBManager.ChangeActiveStatusOfParticipant(groupId, user.Id, true); } } catch (DatabaseException ex) { Debug.WriteLine("AddParticipantToGroup: Failed to add participant to group. Msg is {0}.", ex.Message); throw new ClientException(ErrorCodes.LocalDatabaseException, ex.Message); } }
/// <summary> /// Erzeugt eine Instanz der Klasse GroupDetailsViewModel. /// </summary> /// <param name="navService">Eine Referenz auf den Navigationsdienst der Anwendung.</param> /// <param name="errorMapper">Eine Referenz auf den Fehlerdienst der Anwendung.</param> public GroupDetailsViewModel(INavigationService navService, IErrorMapper errorMapper) : base(navService, errorMapper) { // Erzeuge Controller-Instanz. groupController = new GroupController(this); IsGroupParticipant = false; HasLeaveOption = false; localUser = groupController.GetLocalUser(); if (BallotCollection == null) BallotCollection = new ObservableCollection<Ballot>(); if (ConversationCollection == null) ConversationCollection = new ObservableCollection<Conversation>(); // Erzeuge Befehle. JoinGroupCommand = new AsyncRelayCommand( param => executeJoinGroupCommandAsync(), param => canJoinGroup()); LeaveGroupCommand = new AsyncRelayCommand( param => executeLeaveGroupCommandAsync(), param => canLeaveGroup()); EditGroupCommand = new RelayCommand( param => executeEditGroupCommand(), param => canEditGroup()); ConversationSelectedCommand = new RelayCommand( param => executeConversationSelectedCommand(param)); SynchronizeDataCommand = new AsyncRelayCommand( param => executeSynchronizeDataCommandAsync(), param => canSynchronizeData()); DeleteGroupCommand = new AsyncRelayCommand( param => executeDeleteGroupAsync(), param => canDeleteGroup()); DeleteGroupLocallyCommand = new RelayCommand( param => executeDeleteGroupLocallyCommand(), param => canDeleteGroupLocally()); ChangeToGroupSettingsCommand = new RelayCommand( param => executeChangeToGroupSettingsCommand(), param => canChangeToGroupSettings()); ChangeToAddConversationDialog = new RelayCommand( param => executeChangeToAddConversationDialog(), param => canChangeToAddConversationDialog()); BallotSelectedCommand = new RelayCommand( param => executeBallotSectedCommand(param)); SwitchToCreateBallotDialogCommand = new RelayCommand( param => executeSwitchToCreateBallotDialogCommand(), param => canSwitchToCreateBallotDialog()); SwichToGroupParticipantsViewCommand = new RelayCommand( param => executeSwitchToGroupParticipantsView(), param => canSwitchToGroupParticipantsView()); }
/// <summary> /// Lädt die Abstimmungsergebnisse der gewählten Abstimmung und bereitet deren Anzeige vor. /// </summary> public async Task LoadBallotOptionResultsAsync() { if (SelectedBallot == null || AffectedGroup == null) return; List<VoteResult> voteResults = new List<VoteResult>(); try { List<Option> options = await Task.Run(() => groupController.GetOptions(SelectedBallot.Id, true)); Dictionary<int, User> groupParticipants = await Task.Run(() => groupController.GetParticipantsLookupDirectory(AffectedGroup.Id)); int totalAmountOfVotes = 0; foreach (Option option in options) { VoteResult result = new VoteResult() { OptionId = option.Id, OptionText = option.Text, IsLastVoteResultInList = false }; if (SelectedBallot.HasPublicVotes.HasValue) { result.IsPublic = SelectedBallot.HasPublicVotes.Value; } if (option.VoterIds != null) { // Setze Anzahl Stimmen. result.VoteCount = option.VoterIds.Count; // Addiere Anzahl Stimmen auf Gesamtzahl auf. totalAmountOfVotes += option.VoterIds.Count; if (result.IsPublic) { List<User> voters = new List<User>(); foreach (var voter in option.VoterIds) { if (groupParticipants.ContainsKey(voter)) { voters.Add(groupParticipants[voter]); } else { User dummy = new User() { Name = "Unknown user" }; voters.Add(dummy); } } // Generiere String mit Nutzern, die abgestimmt haben. result.GenerateVoterNamesString(voters); } } voteResults.Add(result); } // Berechne Abstimmungsergebnis. foreach (VoteResult result in voteResults) { result.CalculateVoteResultInPercentage(totalAmountOfVotes); } // Lade Collection. VoteResultsCollection = new ObservableCollection<VoteResult>(voteResults); if (VoteResultsCollection.Count > 0) VoteResultsCollection.Last<VoteResult>().IsLastVoteResultInList = true; } catch (ClientException ex) { Debug.WriteLine("LoadBallotOptionResultsAsync: Loading failed. Message is {0}.", ex.Message); displayError(ex.ErrorCode); } }
/// <summary> /// Erzeugt eine Instanz der Klasse BallotDetailsViewModel. /// </summary> /// <param name="navService">Eine Referenz auf den Navigationsdienst der Anwendung.</param> /// <param name="errorMapper">Eine Referenz auf den Fehlerdienst der Anwendung.</param> public BallotDetailsViewModel(INavigationService navService, IErrorMapper errorMapper) : base (navService, errorMapper) { groupController = new GroupController(this); localUser = groupController.GetLocalUser(); if (BallotOptionCollection == null) BallotOptionCollection = new ObservableCollection<Option>(); if (VoteResultsCollection == null) VoteResultsCollection = new ObservableCollection<VoteResult>(); PlaceVotesCommand = new AsyncRelayCommand( param => executePlaceVotesCommand(), param => canPlaceVotes()); SynchronizeBallotCommand = new AsyncRelayCommand( param => executeSynchronizeBallotCommand(), param => canSynchronizeBallot()); SwitchToEditDialogCommand = new RelayCommand( param => executeSwitchToEditDialogCommand(), param => canSwitchToEditDialog()); DeleteBallotCommand = new AsyncRelayCommand( param => executeDeleteBallotAsync(), param => canDeleteBallot()); }
/// <summary> /// Ruft das Nutzerobjekt ab, das über die angegebene Id identifiziert wird. /// Im Objekt sind jedoch nur die Eigenschaften Id und Name gesetzt. /// </summary> /// <param name="userId">Die Id des Nutzers.</param> /// <returns>Ein Objekt vom Typ User.</returns> /// <exception cref="DatabaseException">Wirft DatabaseException, falls Abruf fehlschlägt.</exception> public User GetUser(int userId) { User user = 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 query = @"SELECT * FROM User WHERE Id=?;"; using (var stmt = conn.Prepare(query)) { stmt.Bind(1, userId); if (stmt.Step() == SQLiteResult.ROW) { user = new User() { Id = userId, Name = (string)stmt["Name"] }; } } } catch (SQLiteException sqlEx) { Debug.WriteLine("GetUser: SQLiteException occurred. Msg is {0}.", sqlEx.Message); throw new DatabaseException(sqlEx.Message); } catch (Exception ex) { Debug.WriteLine("GetUser: Exception occurred. Msg is {0}.", ex.Message); throw new DatabaseException(ex.Message); } finally { mutex.ReleaseMutex(); } } } else { Debug.WriteLine("GetUser: Mutex timeout."); throw new DatabaseException("GetUser: Timeout: Failed to get access to DB."); } return user; }
/// <summary> /// Speichert einen Nutzerdatensatz in der Datenbank ab. /// </summary> /// <param name="user">Der zu speichernde Datensatz als Objekt der Klasse User.</param> /// <exception cref="DatabaseException">Wirft DatabaseException, wenn Speichern fehlschlägt.</exception> public void StoreUser(User user) { // 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 query = @"INSERT INTO User (Id, Name) VALUES (?, ?);"; using (var stmt = conn.Prepare(query)) { stmt.Bind(1, user.Id); stmt.Bind(2, user.Name); if (stmt.Step() != SQLiteResult.DONE) Debug.WriteLine("Failed to store user with id {0} to database.", user.Id); else Debug.WriteLine("Successfully stored user with id {0} to database.", user.Id); } } catch (SQLiteException sqlEx) { Debug.WriteLine("StoreUser: SQLiteException occurred. Message is {0}.", sqlEx.Message); throw new DatabaseException(sqlEx.Message); } catch (Exception ex) { Debug.WriteLine("StoreUser: Exception occurred. Message is {0}.", ex.Message); throw new DatabaseException(ex.Message); } finally { mutex.ReleaseMutex(); } } } }
/// <summary> /// Speichert die Referenz auf das lokale Nutzerobjekt im Speicherbereich der Singleton-Klasse LocalUser, /// so dass es zur Laufzeit der Anwendung aus diesem Speicher abgefragt werden kann. /// </summary> /// <param name="localUser">Das Objekt der Klasse User, welches gespeichert werden soll.</param> public void CacheLocalUserObject(User localUser) { this.localUser = localUser; }