Logging and docs added in several classes #27 #28 #53

Merged
brandleo merged 13 commits from logging_and_docs into main 2022-05-13 22:54:04 +02:00
7 changed files with 218 additions and 41 deletions
Showing only changes of commit c7d9fd0908 - Show all commits

View File

@ -10,21 +10,23 @@ import javafx.scene.paint.Color;
import javafx.scene.text.Font; import javafx.scene.text.Font;
import java.io.IOException; import java.io.IOException;
import java.util.logging.Logger;
/**
*
*/
public class Factory { public class Factory {
private TournamentDecorator tournamentDecorator; private TournamentDecorator tournamentDecorator;
private FileIO fileIO; private FileIO fileIO;
private static final Logger logger = Logger.getLogger(FileIO.class.getCanonicalName());
public Factory(FileIO fileIO, TournamentDecorator tournamentDecorator) { public Factory(FileIO fileIO, TournamentDecorator tournamentDecorator) {
this.fileIO = fileIO; this.fileIO = fileIO;
this.tournamentDecorator = tournamentDecorator; this.tournamentDecorator = tournamentDecorator;
} }
public TournamentDecorator getTournamentDecorator() {
return tournamentDecorator;
}
public void setTournament(Tournament tournament) { public void setTournament(Tournament tournament) {
this.tournamentDecorator.setTournament(tournament); this.tournamentDecorator.setTournament(tournament);
} }
@ -34,8 +36,8 @@ public class Factory {
try { try {
return loader.load(); return loader.load();
} catch (IOException e) { } catch (IOException e) {
logger.warning("Fatal error program can not continue after this: " + e );
e.printStackTrace(); e.printStackTrace();
//TODO handle and logging
} }
return null; return null;
} }
@ -85,8 +87,8 @@ public class Factory {
controller.setup(tournamentDecorator, fileIO, factoryDecorator, box, gameDecorator); controller.setup(tournamentDecorator, fileIO, factoryDecorator, box, gameDecorator);
return controller; return controller;
} catch (IOException e) { } catch (IOException e) {
logger.warning("Fatal error program can not continue after this: " + e );
e.printStackTrace(); e.printStackTrace();
//TODO LOGGER
} }
return null; return null;
} }
@ -118,6 +120,11 @@ public class Factory {
} }
/**
*
* @param pane
* @param error
*/
public void resetFooter(BorderPane pane,boolean error) { public void resetFooter(BorderPane pane,boolean error) {
VBox bottom = (VBox) pane.getBottom(); VBox bottom = (VBox) pane.getBottom();
VBox vBox; VBox vBox;
@ -130,6 +137,9 @@ public class Factory {
vBox.setBorder(null); vBox.setBorder(null);
} }
/**
* Enum for keeping the different fxml form views
*/
public enum View { public enum View {
tournamentList("tournamentList/tournamentList.fxml"), tournamentList("tournamentList/tournamentList.fxml"),
participantFormular("participantAddFormular/participantFormular.fxml"), participantFormular("participantAddFormular/participantFormular.fxml"),

View File

@ -12,63 +12,128 @@ import javafx.scene.shape.Line;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.logging.Logger;
public class FactoryDecorator implements IsObservable{ /**
* Factory Decorator Class giving additional functionality to the factory and holding the listeners in itself.
*/
public class FactoryDecorator implements IsObservable {
private Factory factory; private Factory factory;
private FileIO fileIO; private FileIO fileIO;
private Pane pane; private Pane pane;
private List<IsObserver> listener = new ArrayList<>(); private final List<IsObserver> listener = new ArrayList<>();
public FactoryDecorator(FileIO fileIO, Factory factory, Pane pane){ private static final Logger logger = Logger.getLogger(FileIO.class.getCanonicalName());
/**
* Setup of Factory Decorator with needed classes
*
* @param fileIO for Reading and Saving Files
* @param factory factory which this class adds additional functionality to
* @param pane standard pane
*/
public FactoryDecorator(FileIO fileIO, Factory factory, Pane pane) {
logger.fine("Setting up the Factory decorator");
setFactory(factory); setFactory(factory);
setFileIO(fileIO); setFileIO(fileIO);
setPane(pane); setPane(pane);
} }
/**
* Setting the File IO Class for its functionality
*
* @param fileIO for reading and saving to and from a file
*/
public void setFileIO(FileIO fileIO) { public void setFileIO(FileIO fileIO) {
logger.finer("Setting the FileIO to the FactoryDecorator");
this.fileIO = fileIO; this.fileIO = fileIO;
} }
/**
* Setting the main class
*
* @param factory needed for the main functionality
*/
public void setFactory(Factory factory) { public void setFactory(Factory factory) {
logger.finer("Setting the factory to the FactoryDecorator");
this.factory = factory; this.factory = factory;
} }
/**
* Setting of the given pane to the factory decorator
*
* @param pane that will be set
*/
public void setPane(Pane pane) { public void setPane(Pane pane) {
logger.finer("Setting the pane to the FactoryDecorator");
this.pane = pane; this.pane = pane;
} }
/**
* Method adds a new Listener to the listener list
*
* @param observer that is being added to the Listener List
*/
@Override @Override
public void addListener(IsObserver observer) { public void addListener(IsObserver observer) {
logger.fine("Adding Listener: " + observer);
listener.add(observer); listener.add(observer);
} }
/**
* Removes a Listener from the Listener List
*
* @param observer the Listener to be removed
*/
@Override @Override
public void removeListener(IsObserver observer) { public void removeListener(IsObserver observer) {
logger.fine("Removing Listener: " + observer);
listener.remove(observer); listener.remove(observer);
} }
public void openTournament(FileIO.TournamentFile tournamentFile){ /**
* Opens a tournament File in connection with the File IO Class, shows error Message if error occurs while opening
* it.
*
* @param tournamentFile the File to be opened
*/
public void openTournament(FileIO.TournamentFile tournamentFile) {
logger.finer("Trying to open tournament file:" + tournamentFile);
try { try {
factory.setTournament(fileIO.loadTournament(tournamentFile)); factory.setTournament(fileIO.loadTournament(tournamentFile));
openScheduleView(); openScheduleView();
clearMessage(false); clearMessage(false);
logger.fine("Opened tournament file successfully");
} catch (IOException | ClassNotFoundException e) { } catch (IOException | ClassNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
logger.warning("Failed to open tournament file Error: " + e);
printMessageToFooter("Fehler beim lesen der Datei.", true); printMessageToFooter("Fehler beim lesen der Datei.", true);
} //TODO handle and logging }
} }
/**
* Initializes the display of the Tournament list view
*/
public void openTournamentList() { public void openTournamentList() {
logger.fine("Showing TournamentList view");
factory.showTournamentList((BorderPane) pane, this); factory.showTournamentList((BorderPane) pane, this);
informListener(); informListener();
} }
public void openParticipantFormular() { /**
* Initializes the view of the participant form
*/
public void openParticipantForm() {
logger.fine("Showing participant form view");
factory.showParticipantFormular((BorderPane) pane, this); factory.showParticipantFormular((BorderPane) pane, this);
informListener(); informListener();
} }
public void openPlacesFormular() { /**
* Initializes the view of the places form
*/
public void openPlacesForm() {
logger.fine("Showing places form view");
factory.showPlacesFormular((BorderPane) pane, this); factory.showPlacesFormular((BorderPane) pane, this);
informListener(); informListener();
} }
@ -81,7 +146,7 @@ public class FactoryDecorator implements IsObservable{
public void loadGameList(HBox hBoxCenter, TournamentDecorator tournamentDecorator, boolean treeView) { public void loadGameList(HBox hBoxCenter, TournamentDecorator tournamentDecorator, boolean treeView) {
hBoxCenter.getChildren().clear(); hBoxCenter.getChildren().clear();
if(tournamentDecorator.getTournament() == null){ if (tournamentDecorator.getTournament() == null) {
return; return;
} }
@ -93,7 +158,7 @@ public class FactoryDecorator implements IsObservable{
for (int i = 0; i < gameList.size(); i++) { for (int i = 0; i < gameList.size(); i++) {
List<GameDecorator> newGameDecoratorsList = new ArrayList<>(); List<GameDecorator> newGameDecoratorsList = new ArrayList<>();
VBox vBox = new VBox(); VBox vBox = new VBox();
if(treeView){ if (treeView) {
vBox.setAlignment(Pos.CENTER); vBox.setAlignment(Pos.CENTER);
vBox.setSpacing(gameBoxHeight * spacingFactor); vBox.setSpacing(gameBoxHeight * spacingFactor);
} else { } else {
@ -103,12 +168,12 @@ public class FactoryDecorator implements IsObservable{
for (int j = 0; j < gameList.get(i).size(); j++) { for (int j = 0; j < gameList.get(i).size(); j++) {
GameDecorator gameDecorator = new GameDecorator(gameList.get(i).get(j)); GameDecorator gameDecorator = new GameDecorator(gameList.get(i).get(j));
newGameDecoratorsList.add(gameDecorator); newGameDecoratorsList.add(gameDecorator);
GameController gameController = openGameView(vBox,gameDecorator); GameController gameController = openGameView(vBox, gameDecorator);
if(i>0){ if (i > 0) {
gameController.addListener(gameDecoratorsList.get(j*2)); gameController.addListener(gameDecoratorsList.get(j * 2));
gameController.addListener(gameDecoratorsList.get(j*2+1)); gameController.addListener(gameDecoratorsList.get(j * 2 + 1));
} else if(gameBoxHeight == 0) { } else if (gameBoxHeight == 0) {
gameBoxHeight = gameController.getGameBoxHeigth(); gameBoxHeight = gameController.getGameBoxHeight();
} }
gameDecorator.addListener(new IsObserver() { gameDecorator.addListener(new IsObserver() {
@Override @Override
@ -119,28 +184,28 @@ public class FactoryDecorator implements IsObservable{
gameController.loadContent(); gameController.loadContent();
} }
hBoxCenter.getChildren().add(vBox); hBoxCenter.getChildren().add(vBox);
if(treeView){ if (treeView) {
if(i+1 < gameList.size()) if (i + 1 < gameList.size())
hBoxCenter.getChildren().add(drawLines(vBox, gameBoxHeight, 30)); hBoxCenter.getChildren().add(drawLines(vBox, gameBoxHeight, 30));
} }
gameDecoratorsList = newGameDecoratorsList; gameDecoratorsList = newGameDecoratorsList;
} }
} }
public VBox drawLines(VBox gameVBox, double gameBoxHeight, double lineLength){ public VBox drawLines(VBox gameVBox, double gameBoxHeight, double lineLength) {
VBox completeLineVBox = new VBox(); VBox completeLineVBox = new VBox();
completeLineVBox.setAlignment(Pos.CENTER_LEFT); completeLineVBox.setAlignment(Pos.CENTER_LEFT);
double lineSpacing = gameVBox.getSpacing() + gameBoxHeight - 1; double lineSpacing = gameVBox.getSpacing() + gameBoxHeight - 1;
completeLineVBox.setSpacing(lineSpacing); completeLineVBox.setSpacing(lineSpacing);
for(int i = 0; i < gameVBox.getChildren().size(); i+=2){ for (int i = 0; i < gameVBox.getChildren().size(); i += 2) {
HBox lineBox = new HBox(); HBox lineBox = new HBox();
lineBox.setAlignment(Pos.CENTER); lineBox.setAlignment(Pos.CENTER);
//add Lines from left Game to center //add Lines from left Game to center
VBox vBox = new VBox(); VBox vBox = new VBox();
vBox.setSpacing(lineSpacing); vBox.setSpacing(lineSpacing);
vBox.getChildren().add(new Line(0,0,lineLength,0)); vBox.getChildren().add(new Line(0, 0, lineLength, 0));
vBox.getChildren().add(new Line(0,0,lineLength,0)); vBox.getChildren().add(new Line(0, 0, lineLength, 0));
lineBox.getChildren().add(vBox); lineBox.getChildren().add(vBox);
@ -157,20 +222,43 @@ public class FactoryDecorator implements IsObservable{
return completeLineVBox; return completeLineVBox;
} }
/**
* Method Initializes the Game View, in order to do that a vbox is needed and the gameDecorator
* @param vBox used for display
* @param gameDecorator
* @return
*/
public GameController openGameView(VBox vBox, GameDecorator gameDecorator) { public GameController openGameView(VBox vBox, GameDecorator gameDecorator) {
return factory.loadGameView(vBox ,gameDecorator, this);
return factory.loadGameView(vBox, gameDecorator, this);
} }
/**
* Method that initializes a new Message to be written on the footer, if it's an error boolean can be set.
*
* @param msg The message to be written
* @param error true if an error false if not
*/
public void printMessageToFooter(String msg, boolean error) { public void printMessageToFooter(String msg, boolean error) {
factory.printMessageToFooter((BorderPane) pane,msg,error); logger.fine("Initializes to write message: " + msg + " on the footer");
factory.printMessageToFooter((BorderPane) pane, msg, error);
} }
public void clearMessage(boolean error){ /**
* Method used to clear Messages shown on the footer
* @param error true if an error false if not
*/
public void clearMessage(boolean error) {
logger.fine("Initializing to clear messages from the footer");
factory.resetFooter((BorderPane) pane, error); factory.resetFooter((BorderPane) pane, error);
} }
/**
* Method that informs all listeners of an update.
*/
public void informListener() { public void informListener() {
for(IsObserver observer : listener) {
for (IsObserver observer : listener) {
observer.update(); observer.update();
} }
} }

View File

@ -181,6 +181,7 @@ public class TournamentDecorator implements IsObservable{
executorService.awaitTermination(2000, TimeUnit.MILLISECONDS); executorService.awaitTermination(2000, TimeUnit.MILLISECONDS);
} }
private class saveTask implements Runnable { private class saveTask implements Runnable {
@Override @Override

View File

@ -1,22 +1,40 @@
package ch.zhaw.projekt2.turnierverwaltung.main.gameScheduleView; package ch.zhaw.projekt2.turnierverwaltung.main.gameScheduleView;
import ch.zhaw.projekt2.turnierverwaltung.FileIO;
import javafx.scene.control.Alert; import javafx.scene.control.Alert;
import javafx.scene.control.ButtonBar; import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonType; import javafx.scene.control.ButtonType;
import java.util.logging.Logger;
/**
* Class that is used to display the popup window to confirm a sensitive action of the user.
*/
public class AlertNewSchedule extends Alert { public class AlertNewSchedule extends Alert {
private ButtonType yesButton = new ButtonType("Ja", ButtonBar.ButtonData.YES); private final ButtonType yesButton = new ButtonType("Ja", ButtonBar.ButtonData.YES);
private ButtonType noButton = new ButtonType("Nein", ButtonBar.ButtonData.NO); private final ButtonType noButton = new ButtonType("Nein", ButtonBar.ButtonData.NO);
private boolean result; private boolean result;
private static final Logger logger = Logger.getLogger(FileIO.class.getCanonicalName());
/**
* Popup to ask the user if he is sure that he wants to reshuffle the game board.
*/
public AlertNewSchedule() { public AlertNewSchedule() {
super(AlertType.WARNING); super(AlertType.WARNING);
logger.fine("Displaying Popup to ask user if he wants to reshuffle the game board");
setTitle("Neu erstellen"); setTitle("Neu erstellen");
setHeaderText("Spielplan neu erstellen?"); setHeaderText("Spielplan neu erstellen?");
setContentText("Sind Sie sicher, dass Sie den Spielplan neu erstellen moechten?\nAlle Spielfortschritte gehen daraufhin verloren!"); setContentText("Sind Sie sicher, dass Sie den Spielplan neu erstellen moechten?\nAlle Spielfortschritte gehen daraufhin verloren!");
getButtonTypes().setAll(yesButton,noButton); getButtonTypes().setAll(yesButton, noButton);
} }
/**
* Result gathered from previous question popup window
*
* @return boolean true if yes button is pressed and false if no is pressed
*/
public boolean showAndGetResult() { public boolean showAndGetResult() {
showAndWait().ifPresent(input -> { showAndWait().ifPresent(input -> {
result = input == yesButton; result = input == yesButton;

View File

@ -10,6 +10,9 @@ import javafx.scene.control.TextField;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
/**
* Class GameController in Charge of the Controller Element of the Schedule view.
*/
public class GameController extends FXController{ public class GameController extends FXController{
private GameDecorator gameDecorator; private GameDecorator gameDecorator;
@ -33,7 +36,7 @@ public class GameController extends FXController{
private TextField pointsTeamTwo; private TextField pointsTeamTwo;
@FXML @FXML
void saveGameResult(Event event) { void saveGameResult() {
gameDecorator.saveGameResult(pointsTeamOne.getText(), pointsTeamTwo.getText()); gameDecorator.saveGameResult(pointsTeamOne.getText(), pointsTeamTwo.getText());
} }
@ -42,7 +45,7 @@ public class GameController extends FXController{
gameDecorator.saveGamePlace(newPlace); gameDecorator.saveGamePlace(newPlace);
} }
public double getGameBoxHeigth(){ public double getGameBoxHeight(){
return mainVBox.getPrefHeight(); return mainVBox.getPrefHeight();
} }

View File

@ -41,12 +41,12 @@ public class GameScheduleController extends FXController {
@FXML @FXML
void openPlacesFormular(ActionEvent event) { void openPlacesFormular(ActionEvent event) {
getFactoryDecorator().openPlacesFormular(); getFactoryDecorator().openPlacesForm();
} }
@FXML @FXML
void openParticipantFormular(ActionEvent event) { void openParticipantFormular(ActionEvent event) {
getFactoryDecorator().openParticipantFormular(); getFactoryDecorator().openParticipantForm();
} }
@FXML @FXML

View File

@ -1,6 +1,6 @@
package ch.zhaw.projekt2.turnierverwaltung; package ch.zhaw.projekt2.turnierverwaltung;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -12,10 +12,13 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.logging.Logger;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
/**
* FileIO Test Class
*/
class FileIOTest { class FileIOTest {
String RESOURCES_DIR = "./src/test/resources/ch/zhaw/projekt2/turnierverwaltung/"; String RESOURCES_DIR = "./src/test/resources/ch/zhaw/projekt2/turnierverwaltung/";
@ -23,6 +26,11 @@ class FileIOTest {
String saveDir; String saveDir;
FileIO io; FileIO io;
/**
* Method checks if a new directory is set up correctly and can be accessed.
*
* @throws IOException Exceptions should not be thrown
*/
@Test @Test
void FileIONewDir() throws IOException { void FileIONewDir() throws IOException {
mainDir = RESOURCES_DIR + "FileIONew"; mainDir = RESOURCES_DIR + "FileIONew";
@ -50,14 +58,23 @@ class FileIOTest {
assertFalse(saveDirFile.exists()); assertFalse(saveDirFile.exists());
} }
/**
* Method tests the read behavior and if a file is read correctly
*/
@Nested @Nested
class Read{ class Read{
/**
* Sets up a directory
*/
@BeforeEach @BeforeEach
void init() { void init() {
mainDir = RESOURCES_DIR + "FileIORead"; mainDir = RESOURCES_DIR + "FileIORead";
io = new FileIO(mainDir); io = new FileIO(mainDir);
} }
/**
* Test if the list is displayed correctly when getting it via getList
*/
@Test @Test
void getList() { void getList() {
List<FileIO.TournamentFile> tournaments = io.getList(); List<FileIO.TournamentFile> tournaments = io.getList();
@ -65,6 +82,9 @@ class FileIOTest {
assertEquals("test1.txt", tournaments.get(1).getName()); assertEquals("test1.txt", tournaments.get(1).getName());
} }
/**
* Test behaviour when the list is empty
*/
@Test @Test
void getListEmpty() { void getListEmpty() {
mainDir = RESOURCES_DIR + "FileIOEmpty"; mainDir = RESOURCES_DIR + "FileIOEmpty";
@ -72,6 +92,12 @@ class FileIOTest {
assertEquals(0, io.getList().size()); assertEquals(0, io.getList().size());
} }
/**
* Tests behavior when loading a tournament that exists.
*
* @throws IOException Exceptions should not be thrown
* @throws ClassNotFoundException Exceptions should not be thrown
*/
@Test @Test
void loadTournament() throws IOException, ClassNotFoundException { void loadTournament() throws IOException, ClassNotFoundException {
mainDir = RESOURCES_DIR + "FileIORead"; mainDir = RESOURCES_DIR + "FileIORead";
@ -80,6 +106,9 @@ class FileIOTest {
assertEquals("test1", tournament.getName()); assertEquals("test1", tournament.getName());
} }
/**
* Test behavior when trying to load non-existent tournament
*/
@Test @Test
void loadTournamentNotExisting(){ void loadTournamentNotExisting(){
File file = new File("Not-existing-File"); File file = new File("Not-existing-File");
@ -88,11 +117,17 @@ class FileIOTest {
assertFalse(file.exists()); assertFalse(file.exists());
} }
/**
* Tests behavior when trying to load an empty tournament.
*/
@Test @Test
void loadTournamentEmpty(){ void loadTournamentEmpty(){
assertThrows(IOException.class, () -> io.loadTournament(new File(mainDir + "/saves/empty.txt"))); assertThrows(IOException.class, () -> io.loadTournament(new File(mainDir + "/saves/empty.txt")));
} }
/**
* Tests behavior when the tournamentfile input is null
*/
@Test @Test
void loadTournamentFileNull(){ void loadTournamentFileNull(){
assertThrows(IllegalArgumentException.class, () -> io.loadTournament(null)); assertThrows(IllegalArgumentException.class, () -> io.loadTournament(null));
@ -107,6 +142,13 @@ class FileIOTest {
io = new FileIO(mainDir); io = new FileIO(mainDir);
} }
/**
* Saves the Saving mechanism and deletion
*
* @throws IOException Exceptions should not be thrown
* @throws InvalidNameException Exceptions should not be thrown
* @throws Tournament.InvalidTypeException Exceptions should not be thrown
*/
@Test @Test
void saveTournament() throws IOException, InvalidNameException, Tournament.InvalidTypeException { void saveTournament() throws IOException, InvalidNameException, Tournament.InvalidTypeException {
Tournament tournament = null; Tournament tournament = null;
@ -118,6 +160,9 @@ class FileIOTest {
assertFalse(file.exists()); assertFalse(file.exists());
} }
/**
* Tests behavior when a tournament is being saved that is only null
*/
@Test @Test
void saveTournamentNull(){ void saveTournamentNull(){
assertThrows(IllegalArgumentException.class, () -> io.saveTournament(null)); assertThrows(IllegalArgumentException.class, () -> io.saveTournament(null));
@ -132,6 +177,10 @@ class FileIOTest {
io = new FileIO(mainDir); io = new FileIO(mainDir);
} }
/**
* Test if tournament that does exist can be deleted
* @throws IOException Exceptions should not be thrown
*/
@Test @Test
void deleteTournament() throws IOException { void deleteTournament() throws IOException {
File file = new File(mainDir + "/saves/test1.txt"); File file = new File(mainDir + "/saves/test1.txt");
@ -141,6 +190,11 @@ class FileIOTest {
assertFalse(file.exists()); assertFalse(file.exists());
} }
/**
* Testing if tournament that does not exist can be deleted
*
* @throws IOException Exception should not be thrown only checking for FileNotFoundException
*/
@Test @Test
void deleteTournamentNotExisting() throws IOException { void deleteTournamentNotExisting() throws IOException {
File file = new File("Not-existing-File"); File file = new File("Not-existing-File");
@ -149,6 +203,9 @@ class FileIOTest {
assertFalse(file.exists()); assertFalse(file.exists());
} }
/**
* Tests if a tournament that is null can be deleted
*/
@Test @Test
void deleteTournamentNull(){ void deleteTournamentNull(){
assertThrows(IllegalArgumentException.class, () -> io.deleteTournament(null)); assertThrows(IllegalArgumentException.class, () -> io.deleteTournament(null));