From d088e6a50c2e05ae22254888fbbacc20e02ceec6 Mon Sep 17 00:00:00 2001
From: Peter Kurfer <peter.kurfer@fh-rosenheim.de>
Date: Thu, 13 Dec 2018 23:34:14 +0100
Subject: [PATCH] Cleanup

---
 README.md                                     |   6 +-
 build.gradle                                  |   8 +-
 src/main/java/de/thro/inf/prg3/a11/App.java   | 203 +++++++++---------
 .../de/thro/inf/prg3/a11/MenuSelection.java   |  10 +-
 .../inf/prg3/a11/openmensa/OpenMensaAPI.java  |  72 ++++---
 .../a11/openmensa/OpenMensaAPIService.java    |  37 ++--
 .../inf/prg3/a11/openmensa/model/Canteen.java | 157 +++++++-------
 .../inf/prg3/a11/openmensa/model/Meal.java    | 143 ++++++------
 .../prg3/a11/openmensa/model/PageInfo.java    | 122 +++++------
 .../inf/prg3/a11/openmensa/model/State.java   |  83 +++----
 .../inf/prg3/a11/tests/OpenMensaApiTests.java | 141 ++++++------
 src/test/resources/log4j2.xml                 |  13 ++
 12 files changed, 514 insertions(+), 481 deletions(-)
 create mode 100644 src/test/resources/log4j2.xml

diff --git a/README.md b/README.md
index 67a6856..6d5e775 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,9 @@
-_This is an assignment to the class [Programmieren 3](https://hsro-inf-prg3.github.io) at the [University of Applied Sciences Rosenheim](http://www.fh-rosenheim.de)._
+_This is an assignment to the class [Programmieren 3](https://hsro-inf-prg3.github.io) at the [Technical University of Applied Sciences Rosenheim](https://www.th-rosenheim.de)._
 
 # Assignment 11: Futures - CLI variant
 
+[![](https://travis-ci.org/hsro-inf-prg3/11-futures-cli.svg?branch=master)](https://travis-ci.org/hsro-inf-prg3/11-futures-cli)
+
 This assignment covers the more advanced multithreading topics _futures_ and _future chaining_.
 Futures are a feature of Java 8 and can be compared to the concept of _promises_ in JavaScript.
 
@@ -79,4 +81,4 @@ The required method to fetch a state is already present in the OpenMensaAPI.
 
 If you retrieved the state of the canteen at it is open at the specified date you have to retrieve the meals for the same params.
 Keep in mind to block the main thread to display the retrieved meals after you retrieved them.
-If the canteen is not open at the specified date a meaningful message should be printed to inform the user, that the date has to be changed.
\ No newline at end of file
+If the canteen is not open at the specified date a meaningful message should be printed to inform the user, that the date has to be changed.
diff --git a/build.gradle b/build.gradle
index b48488a..dc6437f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -15,17 +15,17 @@ mainClassName = 'de.thro.inf.prg3.a11.App'
 
 dependencies {
     /* Commons Lang3 */
-    implementation "org.apache.commons:commons-lang3:$commons_lang_version"
+    implementation ("org.apache.commons:commons-lang3:${commons_lang_version}")
 
     /* Retrofit */
-    implementation "com.squareup.retrofit2:retrofit:$retrofit2_version"
-    implementation "com.squareup.retrofit2:converter-gson:$retrofit2_version"
+    implementation("com.squareup.retrofit2:retrofit:${retrofit2_version}")
+    implementation("com.squareup.retrofit2:converter-gson:${retrofit2_version}")
 
     /* JUnit 5 */
 	testCompile("org.junit.jupiter:junit-jupiter-api:${junitVersion}")
 	testRuntime("org.junit.jupiter:junit-jupiter-engine:${junitVersion}")
 	testRuntime("org.junit.jupiter:junit-jupiter-params:${junitVersion}")
-    testRuntime("org.apache.logging.log4j:log4j-core:${log4jVersion}")
+    testImplementation("org.apache.logging.log4j:log4j-core:${log4jVersion}")
     testRuntime("org.apache.logging.log4j:log4j-jul:${log4jVersion}")
 }
 
diff --git a/src/main/java/de/thro/inf/prg3/a11/App.java b/src/main/java/de/thro/inf/prg3/a11/App.java
index 5091ba6..8558c00 100644
--- a/src/main/java/de/thro/inf/prg3/a11/App.java
+++ b/src/main/java/de/thro/inf/prg3/a11/App.java
@@ -16,115 +16,116 @@ import java.util.stream.IntStream;
  * Created on 12/16/17.
  */
 public class App {
-    private static final String OPEN_MENSA_DATE_FORMAT = "yyyy-MM-dd";
+	private static final String OPEN_MENSA_DATE_FORMAT = "yyyy-MM-dd";
 
-    private static final SimpleDateFormat dateFormat = new SimpleDateFormat(OPEN_MENSA_DATE_FORMAT, Locale.getDefault());
-    private static final Scanner inputScanner = new Scanner(System.in);
-    private static final OpenMensaAPI openMensaAPI = OpenMensaAPIService.getInstance().getOpenMensaAPI();
-    private static final Calendar currentDate = Calendar.getInstance();
-    private static int currentCanteenId = -1;
+	private static final SimpleDateFormat dateFormat = new SimpleDateFormat(OPEN_MENSA_DATE_FORMAT, Locale.getDefault());
+	private static final Scanner inputScanner = new Scanner(System.in);
+	private static final OpenMensaAPI openMensaAPI = OpenMensaAPIService.getInstance().getOpenMensaAPI();
+	private static final Calendar currentDate = Calendar.getInstance();
+	private static int currentCanteenId = -1;
 
-    public static void main(String[] args) {
-        MenuSelection selection;
-        /* loop while true to get back to the menu every time an action was performed */
-        do {
-            selection = menu();
-            switch (selection) {
-                case SHOW_CANTEENS:
-                    printCanteens();
-                    break;
-                case SET_CANTEEN:
-                    readCanteen();
-                    break;
-                case SHOW_MEALS:
-                    printMeals();
-                    break;
-                case SET_DATE:
-                    readDate();
-                    break;
-                case QUIT:
-                    System.exit(0);
+	public static void main(String[] args) {
+		MenuSelection selection;
+		/* loop while true to get back to the menu every time an action was performed */
+		do {
+			selection = menu();
+			switch (selection) {
+				case SHOW_CANTEENS:
+					printCanteens();
+					break;
+				case SET_CANTEEN:
+					readCanteen();
+					break;
+				case SHOW_MEALS:
+					printMeals();
+					break;
+				case SET_DATE:
+					readDate();
+					break;
+				case QUIT:
+					System.exit(0);
 
-            }
-        } while (true);
-    }
+			}
+		} while (true);
+	}
 
-    private static void printCanteens() {
-        System.out.print("Fetching canteens [");
-        /* TODO fetch all canteens and print them to STDOUT
-         * at first get a page without an index to be able to extract the required pagination information
-         * afterwards you can iterate the remaining pages
-         * keep in mind that you should await the process as the user has to select canteen with a specific id */
-    }
+	private static void printCanteens() {
+		System.out.print("Fetching canteens [");
+		/* TODO fetch all canteens and print them to STDOUT
+		 * at first get a page without an index to be able to extract the required pagination information
+		 * afterwards you can iterate the remaining pages
+		 * keep in mind that you should await the process as the user has to select canteen with a specific id */
+	}
 
-    private static void printMeals() {
-        /* TODO fetch all meals for the currently selected canteen
-         * to avoid errors retrieve at first the state of the canteen and check if the canteen is opened at the selected day
-         * don't forget to check if a canteen was selected previously! */
-    }
+	private static void printMeals() {
+		/* TODO fetch all meals for the currently selected canteen
+		 * to avoid errors retrieve at first the state of the canteen and check if the canteen is opened at the selected day
+		 * don't forget to check if a canteen was selected previously! */
+	}
 
-    /**
-     * Utility method to select a canteen
-     */
-    private static void readCanteen() {
-        /* typical input reading pattern */
-        boolean readCanteenId = false;
-        do {
-            try {
-                System.out.println("Enter canteen id:");
-                currentCanteenId = inputScanner.nextInt();
-                readCanteenId = true;
-            }catch (Exception e) {
-                System.out.println("Sorry could not read the canteen id");
-            }
-        }while (!readCanteenId);
-    }
+	/**
+	 * Utility method to select a canteen
+	 */
+	private static void readCanteen() {
+		/* typical input reading pattern */
+		boolean readCanteenId = false;
+		do {
+			try {
+				System.out.println("Enter canteen id:");
+				currentCanteenId = inputScanner.nextInt();
+				readCanteenId = true;
+			} catch (Exception e) {
+				System.out.println("Sorry could not read the canteen id");
+			}
+		} while (!readCanteenId);
+	}
 
-    /**
-     * Utility method to read a date and update the calendar
-     */
-    private static void readDate() {
-        /* typical input reading pattern */
-        boolean readDate = false;
-        do {
-            try {
-                System.out.println("Pleae enter date in the format yyyy-mm-dd:");
-                Date d = dateFormat.parse(inputScanner.next());
-                currentDate.setTime(d);
-                readDate = true;
-            }catch (ParseException p) {
-                System.out.println("Sorry, the entered date could not be parsed.");
-            }
-        }while (!readDate);
+	/**
+	 * Utility method to read a date and update the calendar
+	 */
+	private static void readDate() {
+		/* typical input reading pattern */
+		boolean readDate = false;
+		do {
+			try {
+				System.out.println("Pleae enter date in the format yyyy-mm-dd:");
+				Date d = dateFormat.parse(inputScanner.next());
+				currentDate.setTime(d);
+				readDate = true;
+			} catch (ParseException p) {
+				System.out.println("Sorry, the entered date could not be parsed.");
+			}
+		} while (!readDate);
 
-    }
+	}
 
-    /**
-     * Utility method to print menu and read the user selection
-     * @return user selection as MenuSelection
-     */
-    private static MenuSelection menu() {
-        IntStream.range(0, 20).forEach(i -> System.out.print("#"));
-        System.out.println();
-        System.out.println("1) Show canteens");
-        System.out.println("2) Set canteen");
-        System.out.println("3) Show meals");
-        System.out.println("4) Set date");
-        System.out.println("5) Quit");
-        IntStream.range(0, 20).forEach(i -> System.out.print("#"));
-        System.out.println();
+	/**
+	 * Utility method to print menu and read the user selection
+	 *
+	 * @return user selection as MenuSelection
+	 */
+	private static MenuSelection menu() {
+		IntStream.range(0, 20).forEach(i -> System.out.print("#"));
+		System.out.println();
+		System.out.println("1) Show canteens");
+		System.out.println("2) Set canteen");
+		System.out.println("3) Show meals");
+		System.out.println("4) Set date");
+		System.out.println("5) Quit");
+		IntStream.range(0, 20).forEach(i -> System.out.print("#"));
+		System.out.println();
 
-        switch (inputScanner.nextInt()) {
-            case 1:
-                return MenuSelection.SHOW_CANTEENS;
-            case 2:
-                return MenuSelection.SET_CANTEEN;
-            case 3:
-                return MenuSelection.SHOW_MEALS;
-            case 4:
-                return MenuSelection.SET_DATE;
-            default:
-                return MenuSelection.QUIT;
-        }
-    }
+		switch (inputScanner.nextInt()) {
+			case 1:
+				return MenuSelection.SHOW_CANTEENS;
+			case 2:
+				return MenuSelection.SET_CANTEEN;
+			case 3:
+				return MenuSelection.SHOW_MEALS;
+			case 4:
+				return MenuSelection.SET_DATE;
+			default:
+				return MenuSelection.QUIT;
+		}
+	}
 }
diff --git a/src/main/java/de/thro/inf/prg3/a11/MenuSelection.java b/src/main/java/de/thro/inf/prg3/a11/MenuSelection.java
index e6d9881..5cb37d8 100644
--- a/src/main/java/de/thro/inf/prg3/a11/MenuSelection.java
+++ b/src/main/java/de/thro/inf/prg3/a11/MenuSelection.java
@@ -5,9 +5,9 @@ package de.thro.inf.prg3.a11;
  * Created on 12/18/17.
  */
 public enum MenuSelection {
-    SHOW_CANTEENS,
-    SET_CANTEEN,
-    SHOW_MEALS,
-    SET_DATE,
-    QUIT
+	SHOW_CANTEENS,
+	SET_CANTEEN,
+	SHOW_MEALS,
+	SET_DATE,
+	QUIT
 }
diff --git a/src/main/java/de/thro/inf/prg3/a11/openmensa/OpenMensaAPI.java b/src/main/java/de/thro/inf/prg3/a11/openmensa/OpenMensaAPI.java
index d389374..9e82cff 100644
--- a/src/main/java/de/thro/inf/prg3/a11/openmensa/OpenMensaAPI.java
+++ b/src/main/java/de/thro/inf/prg3/a11/openmensa/OpenMensaAPI.java
@@ -16,39 +16,43 @@ import java.util.concurrent.CompletableFuture;
  */
 public interface OpenMensaAPI {
 
-    /**
-     * Retrieve the first page of all canteens
-     * includes the response wrapper to be able to extract required headers for further pagination handling
-     * @return first page of canteens wrapped in a response object
-     */
-    @GET("canteens")
-    CompletableFuture<Response<List<Canteen>>> getCanteens();
-
-    /**
-     * Retrieve any page of all canteens
-     * does not include the response wrapper because the required information should be retrieved before this method is used
-     * @param pageNumber index of the page to retrieve
-     * @return List of canteens as async future
-     */
-    @GET("canteens")
-    CompletableFuture<List<Canteen>> getCanteens(@Query("page")int pageNumber);
-
-    /**
-     * Get the state of a canteen specified by its id at the specified date
-     * @param canteenId id of the canteen
-     * @param date date for which the state should be looked up
-     * @return state of the mensa - may be closed or !closed
-     */
-    @GET("canteens/{canteenId}/days/{date}")
-    CompletableFuture<State> getCanteenState(@Path("canteenId") int canteenId, @Path("date") String date);
-
-    /**
-     * Retrieve the meals for specified date served at canteen specified by its id
-     * @param canteenId id of the canteen
-     * @param date date for which the meals should be retrieved
-     * @return List of meals wrapped as async future
-     */
-    @GET("canteens/{canteenId}/days/{date}/meals")
-    CompletableFuture<List<Meal>> getMeals(@Path("canteenId") int canteenId, @Path("date") String date);
+	/**
+	 * Retrieve the first page of all canteens
+	 * includes the response wrapper to be able to extract required headers for further pagination handling
+	 *
+	 * @return first page of canteens wrapped in a response object
+	 */
+	@GET("canteens")
+	CompletableFuture<Response<List<Canteen>>> getCanteens();
+
+	/**
+	 * Retrieve any page of all canteens
+	 * does not include the response wrapper because the required information should be retrieved before this method is used
+	 *
+	 * @param pageNumber index of the page to retrieve
+	 * @return List of canteens as async future
+	 */
+	@GET("canteens")
+	CompletableFuture<List<Canteen>> getCanteens(@Query("page") int pageNumber);
+
+	/**
+	 * Get the state of a canteen specified by its id at the specified date
+	 *
+	 * @param canteenId id of the canteen
+	 * @param date      date for which the state should be looked up
+	 * @return state of the mensa - may be closed or !closed
+	 */
+	@GET("canteens/{canteenId}/days/{date}")
+	CompletableFuture<State> getCanteenState(@Path("canteenId") int canteenId, @Path("date") String date);
+
+	/**
+	 * Retrieve the meals for specified date served at canteen specified by its id
+	 *
+	 * @param canteenId id of the canteen
+	 * @param date      date for which the meals should be retrieved
+	 * @return List of meals wrapped as async future
+	 */
+	@GET("canteens/{canteenId}/days/{date}/meals")
+	CompletableFuture<List<Meal>> getMeals(@Path("canteenId") int canteenId, @Path("date") String date);
 
 }
diff --git a/src/main/java/de/thro/inf/prg3/a11/openmensa/OpenMensaAPIService.java b/src/main/java/de/thro/inf/prg3/a11/openmensa/OpenMensaAPIService.java
index b85303f..317e820 100644
--- a/src/main/java/de/thro/inf/prg3/a11/openmensa/OpenMensaAPIService.java
+++ b/src/main/java/de/thro/inf/prg3/a11/openmensa/OpenMensaAPIService.java
@@ -6,32 +6,33 @@ import retrofit2.converter.gson.GsonConverterFactory;
 /**
  * OpenMensaAPI service
  * holds an instance of OpenMensaAPI to avoid multiple instantiations of the API
+ *
  * @author Peter Kurfer
  */
 
 public final class OpenMensaAPIService {
 
-    /* singleton instance */
-    private static final OpenMensaAPIService ourInstance = new OpenMensaAPIService();
-    private final OpenMensaAPI openMensaAPI;
+	/* singleton instance */
+	private static final OpenMensaAPIService ourInstance = new OpenMensaAPIService();
+	private final OpenMensaAPI openMensaAPI;
 
-    /* singleton accessor */
-    public static OpenMensaAPIService getInstance() {
-        return ourInstance;
-    }
+	private OpenMensaAPIService() {
 
-    private OpenMensaAPIService() {
+		/* Initialize Retrofit */
+		Retrofit retrofit = new Retrofit.Builder()
+			.baseUrl("http://openmensa.org/api/v2/")
+			.addConverterFactory(GsonConverterFactory.create())
+			.build();
 
-        /* Initialize Retrofit */
-        Retrofit retrofit = new Retrofit.Builder()
-                .baseUrl("http://openmensa.org/api/v2/")
-                .addConverterFactory(GsonConverterFactory.create())
-                .build();
+		openMensaAPI = retrofit.create(OpenMensaAPI.class);
+	}
 
-        openMensaAPI = retrofit.create(OpenMensaAPI.class);
-    }
+	/* singleton accessor */
+	public static OpenMensaAPIService getInstance() {
+		return ourInstance;
+	}
 
-    public OpenMensaAPI getOpenMensaAPI() {
-        return openMensaAPI;
-    }
+	public OpenMensaAPI getOpenMensaAPI() {
+		return openMensaAPI;
+	}
 }
diff --git a/src/main/java/de/thro/inf/prg3/a11/openmensa/model/Canteen.java b/src/main/java/de/thro/inf/prg3/a11/openmensa/model/Canteen.java
index 55c9733..966939d 100644
--- a/src/main/java/de/thro/inf/prg3/a11/openmensa/model/Canteen.java
+++ b/src/main/java/de/thro/inf/prg3/a11/openmensa/model/Canteen.java
@@ -5,86 +5,87 @@ import org.apache.commons.lang3.builder.HashCodeBuilder;
 
 /**
  * Data transfer object for a canteen retrieved from the OpenMensaAPI
+ *
  * @author Peter Kurfer
  */
 
 public final class Canteen {
-    private int id;
-    private String name;
-    private String city;
-    private String address;
-    private double[] coordinates;
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getCity() {
-        return city;
-    }
-
-    public void setCity(String city) {
-        this.city = city;
-    }
-
-    public String getAddress() {
-        return address;
-    }
-
-    public void setAddress(String address) {
-        this.address = address;
-    }
-
-    public double[] getCoordinates() {
-        return coordinates;
-    }
-
-    public void setCoordinates(double[] coordinates) {
-        this.coordinates = coordinates;
-    }
-
-    @Override
-    public String toString() {
-        return String.format("%s\t%s", getId(), getName());
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-
-        if (!(o instanceof Canteen)) return false;
-
-        Canteen canteen = (Canteen) o;
-
-        return new EqualsBuilder()
-                .append(getId(), canteen.getId())
-                .append(getName(), canteen.getName())
-                .append(getCity(), canteen.getCity())
-                .append(getAddress(), canteen.getAddress())
-                .append(getCoordinates(), canteen.getCoordinates())
-                .isEquals();
-    }
-
-    @Override
-    public int hashCode() {
-        return new HashCodeBuilder(17, 37)
-                .append(getId())
-                .append(getName())
-                .append(getCity())
-                .append(getAddress())
-                .append(getCoordinates())
-                .toHashCode();
-    }
+	private int id;
+	private String name;
+	private String city;
+	private String address;
+	private double[] coordinates;
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getCity() {
+		return city;
+	}
+
+	public void setCity(String city) {
+		this.city = city;
+	}
+
+	public String getAddress() {
+		return address;
+	}
+
+	public void setAddress(String address) {
+		this.address = address;
+	}
+
+	public double[] getCoordinates() {
+		return coordinates;
+	}
+
+	public void setCoordinates(double[] coordinates) {
+		this.coordinates = coordinates;
+	}
+
+	@Override
+	public String toString() {
+		return String.format("%s\t%s", getId(), getName());
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (this == o) return true;
+
+		if (!(o instanceof Canteen)) return false;
+
+		Canteen canteen = (Canteen) o;
+
+		return new EqualsBuilder()
+			.append(getId(), canteen.getId())
+			.append(getName(), canteen.getName())
+			.append(getCity(), canteen.getCity())
+			.append(getAddress(), canteen.getAddress())
+			.append(getCoordinates(), canteen.getCoordinates())
+			.isEquals();
+	}
+
+	@Override
+	public int hashCode() {
+		return new HashCodeBuilder(17, 37)
+			.append(getId())
+			.append(getName())
+			.append(getCity())
+			.append(getAddress())
+			.append(getCoordinates())
+			.toHashCode();
+	}
 }
diff --git a/src/main/java/de/thro/inf/prg3/a11/openmensa/model/Meal.java b/src/main/java/de/thro/inf/prg3/a11/openmensa/model/Meal.java
index 62ec1ac..ef67ebd 100644
--- a/src/main/java/de/thro/inf/prg3/a11/openmensa/model/Meal.java
+++ b/src/main/java/de/thro/inf/prg3/a11/openmensa/model/Meal.java
@@ -8,79 +8,80 @@ import java.util.List;
 
 /**
  * Data transfer object for a meal retrieved from the OpenMensaAPI
+ *
  * @author Peter Kurfer
  */
 
 public final class Meal {
-    private int id;
-    private String name;
-    private String category;
-    private List<String> notes;
-
-    public Meal() {
-        notes = new LinkedList<>();
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getCategory() {
-        return category;
-    }
-
-    public void setCategory(String category) {
-        this.category = category;
-    }
-
-    public List<String> getNotes() {
-        return notes;
-    }
-
-    public void setNotes(List<String> notes) {
-        this.notes = notes;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-
-        if (!(o instanceof Meal)) return false;
-
-        Meal meal = (Meal) o;
-
-        return new EqualsBuilder()
-                .append(getId(), meal.getId())
-                .append(getName(), meal.getName())
-                .append(getCategory(), meal.getCategory())
-                .append(getNotes(), meal.getNotes())
-                .isEquals();
-    }
-
-    @Override
-    public int hashCode() {
-        return new HashCodeBuilder(17, 37)
-                .append(getId())
-                .append(getName())
-                .append(getCategory())
-                .append(getNotes())
-                .toHashCode();
-    }
-
-    @Override
-    public String toString() {
-        return name;
-    }
+	private int id;
+	private String name;
+	private String category;
+	private List<String> notes;
+
+	public Meal() {
+		notes = new LinkedList<>();
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getCategory() {
+		return category;
+	}
+
+	public void setCategory(String category) {
+		this.category = category;
+	}
+
+	public List<String> getNotes() {
+		return notes;
+	}
+
+	public void setNotes(List<String> notes) {
+		this.notes = notes;
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (this == o) return true;
+
+		if (!(o instanceof Meal)) return false;
+
+		Meal meal = (Meal) o;
+
+		return new EqualsBuilder()
+			.append(getId(), meal.getId())
+			.append(getName(), meal.getName())
+			.append(getCategory(), meal.getCategory())
+			.append(getNotes(), meal.getNotes())
+			.isEquals();
+	}
+
+	@Override
+	public int hashCode() {
+		return new HashCodeBuilder(17, 37)
+			.append(getId())
+			.append(getName())
+			.append(getCategory())
+			.append(getNotes())
+			.toHashCode();
+	}
+
+	@Override
+	public String toString() {
+		return name;
+	}
 }
diff --git a/src/main/java/de/thro/inf/prg3/a11/openmensa/model/PageInfo.java b/src/main/java/de/thro/inf/prg3/a11/openmensa/model/PageInfo.java
index 89106c3..8b0579b 100644
--- a/src/main/java/de/thro/inf/prg3/a11/openmensa/model/PageInfo.java
+++ b/src/main/java/de/thro/inf/prg3/a11/openmensa/model/PageInfo.java
@@ -12,74 +12,74 @@ import retrofit2.Response;
 
 public final class PageInfo {
 
-    private static final String TOTAL_PAGES_HEADER = "X-Total-Pages";
-    private static final String TOTAL_ITEM_COUNT_HEADER = "X-Total-Count";
-    private static final String ITEM_COUNT_PER_PAGE_HEADER = "X-Per-Page";
-    private static final String CURRENT_PAGE_INDEX_HEADER = "X-Current-Page";
+	private static final String TOTAL_PAGES_HEADER = "X-Total-Pages";
+	private static final String TOTAL_ITEM_COUNT_HEADER = "X-Total-Count";
+	private static final String ITEM_COUNT_PER_PAGE_HEADER = "X-Per-Page";
+	private static final String CURRENT_PAGE_INDEX_HEADER = "X-Current-Page";
 
-    private final int totalCountOfPages;
-    private final int totalCountOfItems;
-    private final int itemCountPerPage;
-    private final int currentPageIndex;
+	private final int totalCountOfPages;
+	private final int totalCountOfItems;
+	private final int itemCountPerPage;
+	private final int currentPageIndex;
 
-    /**
-     * Default constructor
-     * only used by 'factory method' `extractFromReponse(...)`
-     */
-    private PageInfo(int totalCountOfPages, int totalCountOfItems, int itemCountPerPage, int currentPageIndex) {
-        this.totalCountOfPages = totalCountOfPages;
-        this.totalCountOfItems = totalCountOfItems;
-        this.itemCountPerPage = itemCountPerPage;
-        this.currentPageIndex = currentPageIndex;
-    }
+	/**
+	 * Default constructor
+	 * only used by 'factory method' `extractFromReponse(...)`
+	 */
+	private PageInfo(int totalCountOfPages, int totalCountOfItems, int itemCountPerPage, int currentPageIndex) {
+		this.totalCountOfPages = totalCountOfPages;
+		this.totalCountOfItems = totalCountOfItems;
+		this.itemCountPerPage = itemCountPerPage;
+		this.currentPageIndex = currentPageIndex;
+	}
 
-    /**
-     * @return total count of pages or -1 if required header was not present
-     */
-    public int getTotalCountOfPages() {
-        return totalCountOfPages;
-    }
+	/**
+	 * Factory method to create a PageInfo by parsing the headers of a response which includes the required information
+	 *
+	 * @param apiResponse response object to parse
+	 * @param <T>         concrete response type
+	 * @return PageInfo instance - may contain default fallback values see getters
+	 */
+	public static <T extends Response<?>> PageInfo extractFromResponse(T apiResponse) {
+		Headers headers = apiResponse.headers();
+		int totalPages = extractFromHeaders(headers, TOTAL_PAGES_HEADER, -1);
+		int totalItemCount = extractFromHeaders(headers, TOTAL_ITEM_COUNT_HEADER, -1);
+		int itemCountPerPage = extractFromHeaders(headers, ITEM_COUNT_PER_PAGE_HEADER, -1);
+		int currentPageIndex = extractFromHeaders(headers, CURRENT_PAGE_INDEX_HEADER, -1);
 
-    /**
-     * @return total item count or -1 if required header was not present
-     */
-    public int getTotalCountOfItems() {
-        return totalCountOfItems;
-    }
+		return new PageInfo(totalPages, totalItemCount, itemCountPerPage, currentPageIndex);
+	}
 
-    /**
-     * @return item count on every page or -1 if required header was not present
-     */
-    public int getItemCountPerPage() {
-        return itemCountPerPage;
-    }
+	private static int extractFromHeaders(Headers headers, String headerName, int fallback) {
+		String headerValue = headers.get(headerName);
+		return headerValue == null ? fallback : Integer.parseInt(headerValue);
+	}
 
-    /**
-     * @return current page index or -1 if required header was not present
-     */
-    public int getCurrentPageIndex() {
-        return currentPageIndex;
-    }
+	/**
+	 * @return total count of pages or -1 if required header was not present
+	 */
+	public int getTotalCountOfPages() {
+		return totalCountOfPages;
+	}
 
-    /**
-     * Factory method to create a PageInfo by parsing the headers of a response which includes the required information
-     *
-     * @param apiResponse response object to parse
-     * @param <T> concrete response type
-     * @return PageInfo instance - may contain default fallback values see getters
-     */
-    public static <T extends Response<?>> PageInfo extractFromResponse(T apiResponse) {
-        Headers headers = apiResponse.headers();
-        int totalPages = extractFromHeaders(headers, TOTAL_PAGES_HEADER, -1);
-        int totalItemCount = extractFromHeaders(headers, TOTAL_ITEM_COUNT_HEADER, -1);
-        int itemCountPerPage = extractFromHeaders(headers, ITEM_COUNT_PER_PAGE_HEADER, -1);
-        int currentPageIndex = extractFromHeaders(headers, CURRENT_PAGE_INDEX_HEADER, -1);
+	/**
+	 * @return total item count or -1 if required header was not present
+	 */
+	public int getTotalCountOfItems() {
+		return totalCountOfItems;
+	}
 
-        return new PageInfo(totalPages, totalItemCount, itemCountPerPage, currentPageIndex);
-    }
+	/**
+	 * @return item count on every page or -1 if required header was not present
+	 */
+	public int getItemCountPerPage() {
+		return itemCountPerPage;
+	}
 
-    private static int extractFromHeaders(Headers headers, String headerName, int fallback) {
-        String headerValue = headers.get(headerName);
-        return headerValue == null ? fallback : Integer.parseInt(headerValue);
-    }
+	/**
+	 * @return current page index or -1 if required header was not present
+	 */
+	public int getCurrentPageIndex() {
+		return currentPageIndex;
+	}
 }
diff --git a/src/main/java/de/thro/inf/prg3/a11/openmensa/model/State.java b/src/main/java/de/thro/inf/prg3/a11/openmensa/model/State.java
index 9febe81..0eb236a 100644
--- a/src/main/java/de/thro/inf/prg3/a11/openmensa/model/State.java
+++ b/src/main/java/de/thro/inf/prg3/a11/openmensa/model/State.java
@@ -6,61 +6,62 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
 
 /**
  * Data transfer object for a state of a canteen retrieved from the OpenMensaAPI
+ *
  * @author Peter Kurfer
  */
 
 public final class State {
 
-    private String date;
-    private boolean closed = true;
+	private String date;
+	private boolean closed = true;
 
-    public State() {
-        date = "";
-    }
+	public State() {
+		date = "";
+	}
 
-    public String getDate() {
-        return date;
-    }
+	public String getDate() {
+		return date;
+	}
 
-    public void setDate(String date) {
-        this.date = date;
-    }
+	public void setDate(String date) {
+		this.date = date;
+	}
 
-    public boolean isClosed() {
-        return closed;
-    }
+	public boolean isClosed() {
+		return closed;
+	}
 
-    public void setClosed(boolean closed) {
-        this.closed = closed;
-    }
+	public void setClosed(boolean closed) {
+		this.closed = closed;
+	}
 
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
+	@Override
+	public boolean equals(Object o) {
+		if (this == o) return true;
 
-        if (!(o instanceof State)) return false;
+		if (!(o instanceof State)) return false;
 
-        State state = (State) o;
+		State state = (State) o;
 
-        return new EqualsBuilder()
-                .append(isClosed(), state.isClosed())
-                .append(getDate(), state.getDate())
-                .isEquals();
-    }
+		return new EqualsBuilder()
+			.append(isClosed(), state.isClosed())
+			.append(getDate(), state.getDate())
+			.isEquals();
+	}
 
-    @Override
-    public int hashCode() {
-        return new HashCodeBuilder(17, 37)
-                .append(getDate())
-                .append(isClosed())
-                .toHashCode();
-    }
+	@Override
+	public int hashCode() {
+		return new HashCodeBuilder(17, 37)
+			.append(getDate())
+			.append(isClosed())
+			.toHashCode();
+	}
 
-    @Override
-    public String toString() {
-        return new ToStringBuilder(this)
-                .append("date", date)
-                .append("closed", closed)
-                .toString();
-    }
+	@Override
+	public String toString() {
+		return new ToStringBuilder(this)
+			.append("date", date)
+			.append("closed", closed)
+			.toString();
+	}
 }
diff --git a/src/test/java/de/thro/inf/prg3/a11/tests/OpenMensaApiTests.java b/src/test/java/de/thro/inf/prg3/a11/tests/OpenMensaApiTests.java
index d52e90d..6d546df 100644
--- a/src/test/java/de/thro/inf/prg3/a11/tests/OpenMensaApiTests.java
+++ b/src/test/java/de/thro/inf/prg3/a11/tests/OpenMensaApiTests.java
@@ -3,7 +3,10 @@ package de.thro.inf.prg3.a11.tests;
 import de.thro.inf.prg3.a11.openmensa.OpenMensaAPI;
 import de.thro.inf.prg3.a11.openmensa.OpenMensaAPIService;
 import de.thro.inf.prg3.a11.openmensa.model.PageInfo;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
 import retrofit2.HttpException;
 
 import java.text.SimpleDateFormat;
@@ -16,72 +19,78 @@ import static org.junit.jupiter.api.Assertions.*;
 /**
  * @author Peter Kurfer
  */
-
+@TestInstance(TestInstance.Lifecycle.PER_METHOD)
 class OpenMensaApiTests {
 
-    private static final int THRO_MENSA_ID = 229;
-    private static final String OPEN_MENSA_DATE_FORMAT = "yyyy-MM-dd";
-    private final SimpleDateFormat dateFormat;
-    private final OpenMensaAPI openMensaAPI;
-    private final Calendar calendar;
-
-    OpenMensaApiTests() {
-        dateFormat = new SimpleDateFormat(OPEN_MENSA_DATE_FORMAT, Locale.getDefault());
-        openMensaAPI = OpenMensaAPIService.getInstance().getOpenMensaAPI();
-        calendar = Calendar.getInstance();
-    }
-
-    @Test
-    void testGetFirstMensaPage() throws ExecutionException, InterruptedException {
-        final var canteensResponse = openMensaAPI.getCanteens().get();
-
-        assertNotNull(canteensResponse);
-        assertNotNull(canteensResponse.body());
-        assertNotEquals(0, canteensResponse.body().size());
-
-        for (var c : canteensResponse.body()) {
-            System.out.println(c.getName());
-        }
-    }
-
-    @Test
-    void testExtractPageInfo() throws ExecutionException, InterruptedException {
-        final var canteensResponse = openMensaAPI.getCanteens().get();
-
-        final var pageInfo = PageInfo.extractFromResponse(canteensResponse);
-
-        assertNotNull(pageInfo);
-        assertEquals(canteensResponse.body().size(), pageInfo.getItemCountPerPage());
-        assertTrue(pageInfo.getTotalCountOfItems() > 0);
-        assertTrue(pageInfo.getTotalCountOfPages() > 0);
-        assertTrue(pageInfo.getCurrentPageIndex() > 0);
-    }
-
-    @Test
-    void testGetCanteenState() throws InterruptedException {
-        try {
-            final var mensaState = openMensaAPI.getCanteenState(THRO_MENSA_ID, dateFormat.format(calendar.getTime())).get();
-            assertNotNull(mensaState);
-        }catch (ExecutionException e) {
-            if(e.getCause() instanceof HttpException) {
-                System.out.println(String.format("HTTP error: %s", e.getCause().getMessage()));
-            }
-        }
-    }
-
-
-    @Test
-    void testGetMultiplePages() throws ExecutionException, InterruptedException {
-        final var firstPage = openMensaAPI.getCanteens().get();
-
-        assertNotNull(firstPage);
-        assertNotNull(firstPage.body());
-
-        final var pageInfo = PageInfo.extractFromResponse(firstPage);
-        for(var i = 2; i <= pageInfo.getTotalCountOfPages(); i++) {
-            var canteensPage = openMensaAPI.getCanteens(i).get();
-            assertNotNull(canteensPage);
-            assertNotEquals(0, canteensPage.size());
-        }
-    }
+	private static final Logger logger = LogManager.getLogger(OpenMensaApiTests.class);
+	private static final int THRO_MENSA_ID = 229;
+	private static final String OPEN_MENSA_DATE_FORMAT = "yyyy-MM-dd";
+	private static final SimpleDateFormat dateFormat = new SimpleDateFormat(OPEN_MENSA_DATE_FORMAT, Locale.getDefault());
+
+	private final OpenMensaAPI openMensaAPI;
+	private final Calendar calendar;
+
+	OpenMensaApiTests() {
+		openMensaAPI = OpenMensaAPIService
+			.getInstance()
+			.getOpenMensaAPI();
+
+		calendar = Calendar.getInstance();
+	}
+
+	@Test
+	void testGetFirstMensaPage() throws ExecutionException, InterruptedException {
+		final var canteensResponse = openMensaAPI.getCanteens().get();
+
+		assertNotNull(canteensResponse);
+		assertNotNull(canteensResponse.body());
+		assertNotEquals(0, canteensResponse.body().size());
+
+		for (var c : canteensResponse.body()) {
+			logger.info(c.getName());
+		}
+	}
+
+	@Test
+	void testExtractPageInfo() throws ExecutionException, InterruptedException {
+		final var canteensResponse = openMensaAPI.getCanteens().get();
+
+		final var pageInfo = PageInfo.extractFromResponse(canteensResponse);
+
+		assertNotNull(pageInfo);
+		assertEquals(canteensResponse.body().size(), pageInfo.getItemCountPerPage());
+		assertTrue(pageInfo.getTotalCountOfItems() > 0);
+		assertTrue(pageInfo.getTotalCountOfPages() > 0);
+		assertTrue(pageInfo.getCurrentPageIndex() > 0);
+	}
+
+	@Test
+	void testGetCanteenState() throws InterruptedException {
+		try {
+			var date = dateFormat.format(calendar.getTime());
+			logger.info("Fetching canteen state for date {}", date);
+			final var mensaState = openMensaAPI.getCanteenState(THRO_MENSA_ID, date).get();
+			assertNotNull(mensaState);
+		} catch (ExecutionException e) {
+			if (e.getCause() instanceof HttpException) {
+				logger.info("HTTP error: {}", e.getCause().getMessage());
+			}
+		}
+	}
+
+
+	@Test
+	void testGetMultiplePages() throws ExecutionException, InterruptedException {
+		final var firstPage = openMensaAPI.getCanteens().get();
+
+		assertNotNull(firstPage);
+		assertNotNull(firstPage.body());
+
+		final var pageInfo = PageInfo.extractFromResponse(firstPage);
+		for (var i = 2; i <= pageInfo.getTotalCountOfPages(); i++) {
+			var canteensPage = openMensaAPI.getCanteens(i).get();
+			assertNotNull(canteensPage);
+			assertNotEquals(0, canteensPage.size());
+		}
+	}
 }
diff --git a/src/test/resources/log4j2.xml b/src/test/resources/log4j2.xml
new file mode 100644
index 0000000..2628b03
--- /dev/null
+++ b/src/test/resources/log4j2.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="WARN">
+	<Appenders>
+		<Console name="Console" target="SYSTEM_OUT">
+			<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
+		</Console>
+	</Appenders>
+	<Loggers>
+		<Root level="all">
+			<AppenderRef ref="Console"/>
+		</Root>
+	</Loggers>
+</Configuration>
-- 
GitLab