commit 74d6b99b9a545c12052a8c569887e65a80d70e5b
Author: Jakub Danek <jakub.danek@yoso.fi>
Date:   Tue Oct 15 15:20:30 2019 +0200

    re #31 separate part of DefaultSettings interface into own repository
    
    Required for easier implementation of #29 (user registration)

diff --git a/server/src/main/java/org/danekja/ymanager/business/ApiManager.java b/server/src/main/java/org/danekja/ymanager/business/ApiManager.java
index d4e574c..1d6c743 100644
--- a/server/src/main/java/org/danekja/ymanager/business/ApiManager.java
+++ b/server/src/main/java/org/danekja/ymanager/business/ApiManager.java
@@ -4,10 +4,11 @@ import org.danekja.ymanager.business.auth.anot.CanModifyVacation;
 import org.danekja.ymanager.business.auth.anot.IsEmployer;
 import org.danekja.ymanager.business.auth.anot.IsOwner;
 import org.danekja.ymanager.business.auth.anot.IsSignedIn;
+import org.danekja.ymanager.domain.DefaultSettings;
 import org.danekja.ymanager.domain.*;
-import org.danekja.ymanager.dto.DefaultSettings;
 import org.danekja.ymanager.dto.*;
 import org.danekja.ymanager.repository.RequestRepository;
+import org.danekja.ymanager.repository.SettingsRepository;
 import org.danekja.ymanager.repository.UserRepository;
 import org.danekja.ymanager.repository.VacationRepository;
 import org.danekja.ymanager.ws.rest.exceptions.RESTFullException;
@@ -33,14 +34,16 @@ public class ApiManager implements Manager {
     private final RequestRepository requestRepository;
     private final UserRepository userRepository;
     private final VacationRepository vacationRepository;
+    private final SettingsRepository settingsRepository;
 
     private final AuthorizationService authService;
 
     @Autowired
-    public ApiManager(RequestRepository requestRepository, UserRepository userRepository, VacationRepository vacationRepository, AuthorizationService authService) {
+    public ApiManager(RequestRepository requestRepository, UserRepository userRepository, VacationRepository vacationRepository, SettingsRepository settingsRepository, AuthorizationService authService) {
         this.requestRepository = requestRepository;
         this.userRepository = userRepository;
         this.vacationRepository = vacationRepository;
+        this.settingsRepository = settingsRepository;
         this.authService = authService;
     }
 
@@ -70,7 +73,7 @@ public class ApiManager implements Manager {
     @IsSignedIn
     public DefaultSettings getDefaultSettings() throws RESTFullException {
         try {
-            return userRepository.getLastDefaultSettings().orElse(new DefaultSettings());
+            return settingsRepository.get();
         } catch (DataAccessException e) {
             log.error(e.getMessage());
             throw new RESTFullException(e.getMessage(), "database.error");
@@ -104,7 +107,7 @@ public class ApiManager implements Manager {
     @IsEmployer
     public void createSettings(DefaultSettings settings) throws RESTFullException {
         try {
-            org.danekja.ymanager.domain.DefaultSettings defaultSettings = new org.danekja.ymanager.domain.DefaultSettings();
+            DefaultSettings defaultSettings = new DefaultSettings();
             defaultSettings.setSickDayCount(settings.getSickDayCount());
             defaultSettings.setNotification(settings.getNotification());
             userRepository.insertSettings(defaultSettings);
diff --git a/server/src/main/java/org/danekja/ymanager/business/Manager.java b/server/src/main/java/org/danekja/ymanager/business/Manager.java
index 2591676..e11760c 100644
--- a/server/src/main/java/org/danekja/ymanager/business/Manager.java
+++ b/server/src/main/java/org/danekja/ymanager/business/Manager.java
@@ -1,5 +1,6 @@
 package org.danekja.ymanager.business;
 
+import org.danekja.ymanager.domain.DefaultSettings;
 import org.danekja.ymanager.domain.RequestType;
 import org.danekja.ymanager.domain.Status;
 import org.danekja.ymanager.dto.*;
diff --git a/server/src/main/java/org/danekja/ymanager/domain/DefaultSettings.java b/server/src/main/java/org/danekja/ymanager/domain/DefaultSettings.java
index e151a6f..e098976 100644
--- a/server/src/main/java/org/danekja/ymanager/domain/DefaultSettings.java
+++ b/server/src/main/java/org/danekja/ymanager/domain/DefaultSettings.java
@@ -32,6 +32,14 @@ public class DefaultSettings {
      */
     private LocalDateTime notification;
 
+    public DefaultSettings() {
+    }
+
+    public DefaultSettings(Integer sickDayCount, LocalDateTime notification) {
+        this.setSickDayCount(sickDayCount);
+        this.setNotification(notification);
+    }
+
     /**
      * Returns the ID of this default settings.
      *
diff --git a/server/src/main/java/org/danekja/ymanager/dto/DefaultSettings.java b/server/src/main/java/org/danekja/ymanager/dto/DefaultSettings.java
index 5c5b5ad..5de2ed7 100644
--- a/server/src/main/java/org/danekja/ymanager/dto/DefaultSettings.java
+++ b/server/src/main/java/org/danekja/ymanager/dto/DefaultSettings.java
@@ -19,6 +19,19 @@ public class DefaultSettings {
      */
     private LocalDateTime notification;
 
+    public DefaultSettings() {
+    }
+
+    public DefaultSettings(Integer sickDayCount, LocalDateTime notification) {
+        this.sickDayCount = sickDayCount;
+        this.notification = notification;
+    }
+
+    public DefaultSettings(org.danekja.ymanager.domain.DefaultSettings src) {
+        this.sickDayCount = src.getSickDayCount();
+        this.notification = src.getNotification();
+    }
+
     /**
      * Returns the default number of available sick days in this default settings.
      *
@@ -54,5 +67,9 @@ public class DefaultSettings {
     public void setNotification(final LocalDateTime notification) {
         this.notification = notification;
     }
+
+    public org.danekja.ymanager.domain.DefaultSettings toEntity() {
+        return new org.danekja.ymanager.domain.DefaultSettings(getSickDayCount(), getNotification());
+    }
 }
 
diff --git a/server/src/main/java/org/danekja/ymanager/repository/SettingsRepository.java b/server/src/main/java/org/danekja/ymanager/repository/SettingsRepository.java
new file mode 100644
index 0000000..214a83e
--- /dev/null
+++ b/server/src/main/java/org/danekja/ymanager/repository/SettingsRepository.java
@@ -0,0 +1,15 @@
+package org.danekja.ymanager.repository;
+
+import org.danekja.ymanager.domain.DefaultSettings;
+
+/**
+ * DAO interface for settings object.
+ */
+public interface SettingsRepository {
+
+    /**
+     * @return currently valid default settings
+     */
+    DefaultSettings get();
+
+}
diff --git a/server/src/main/java/org/danekja/ymanager/repository/UserRepository.java b/server/src/main/java/org/danekja/ymanager/repository/UserRepository.java
index 1cc74f4..4f55441 100644
--- a/server/src/main/java/org/danekja/ymanager/repository/UserRepository.java
+++ b/server/src/main/java/org/danekja/ymanager/repository/UserRepository.java
@@ -240,7 +240,7 @@ public class UserRepository {
                 user.getFirstName(), user.getLastName(), user.getVacationCount(), user.getTotalSickDayCount(), user.getTakenSickDayCount(), user.getNotification(), user.getEmail(), user.getPhoto(), user.getRole().name(), user.getStatus().name());
     }
 
-    public void insertSettings(final org.danekja.ymanager.domain.DefaultSettings settings) {
+    public void insertSettings(final DefaultSettings settings) {
         this.jdbc.update("INSERT INTO default_settings (no_sick_days, alert) VALUES (?, ?)", settings.getSickDayCount(), settings.getNotification());
     }
 
diff --git a/server/src/main/java/org/danekja/ymanager/repository/jdbc/JdbcSettingsRepository.java b/server/src/main/java/org/danekja/ymanager/repository/jdbc/JdbcSettingsRepository.java
new file mode 100644
index 0000000..a9a2461
--- /dev/null
+++ b/server/src/main/java/org/danekja/ymanager/repository/jdbc/JdbcSettingsRepository.java
@@ -0,0 +1,32 @@
+package org.danekja.ymanager.repository.jdbc;
+
+import org.danekja.ymanager.domain.DefaultSettings;
+import org.danekja.ymanager.repository.SettingsRepository;
+import org.danekja.ymanager.repository.jdbc.mappers.DefaultSettingsMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JdbcSettingsRepository implements SettingsRepository {
+
+    private static final RowMapper<DefaultSettings> SETTINGS_ROW_MAPPER = new DefaultSettingsMapper();
+
+    /**
+     * The connection to a database.
+     */
+    private final JdbcTemplate jdbc;
+
+    @Autowired
+    public JdbcSettingsRepository(JdbcTemplate jdbc) {
+        this.jdbc = jdbc;
+    }
+
+    @Override
+    public DefaultSettings get() {
+        //TODO order by creation date
+        return this.jdbc.queryForObject("SELECT * FROM default_settings ORDER BY id DESC LIMIT 1", SETTINGS_ROW_MAPPER);
+    }
+
+}
diff --git a/server/src/main/java/org/danekja/ymanager/repository/jdbc/mappers/DefaultSettingsMapper.java b/server/src/main/java/org/danekja/ymanager/repository/jdbc/mappers/DefaultSettingsMapper.java
new file mode 100644
index 0000000..77973db
--- /dev/null
+++ b/server/src/main/java/org/danekja/ymanager/repository/jdbc/mappers/DefaultSettingsMapper.java
@@ -0,0 +1,26 @@
+package org.danekja.ymanager.repository.jdbc.mappers;
+
+import org.danekja.ymanager.domain.DefaultSettings;
+import org.springframework.jdbc.core.RowMapper;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+public class DefaultSettingsMapper implements RowMapper<DefaultSettings> {
+
+    /**
+     * Maps a row from a result of a query to an DefaultSettings.
+     *
+     * @param resultSet the row from the result
+     * @param i         the index of the row
+     * @return the DefaultSettings object
+     * @throws java.sql.SQLException if the columnLabel is not valid; if a database access error occurs or this method is called on a closed result set
+     */
+    @Override
+    public DefaultSettings mapRow(ResultSet resultSet, int i) throws SQLException {
+        final DefaultSettings settings = new DefaultSettings();
+        settings.setSickDayCount(resultSet.getInt("no_sick_days"));
+        settings.setNotification(resultSet.getTimestamp("alert").toLocalDateTime());
+        return settings;
+    }
+}
diff --git a/server/src/main/java/org/danekja/ymanager/ws/rest/ApiController.java b/server/src/main/java/org/danekja/ymanager/ws/rest/ApiController.java
index e5b395e..8eda547 100644
--- a/server/src/main/java/org/danekja/ymanager/ws/rest/ApiController.java
+++ b/server/src/main/java/org/danekja/ymanager/ws/rest/ApiController.java
@@ -1,6 +1,5 @@
 package org.danekja.ymanager.ws.rest;
 
-import org.apache.commons.lang3.StringUtils;
 import org.danekja.ymanager.business.FileService;
 import org.danekja.ymanager.business.Manager;
 import org.danekja.ymanager.domain.RequestType;
@@ -36,21 +35,6 @@ public class ApiController extends BaseController {
         this.fileService = fileService;
     }
 
-    private Long getUserId(String id) {
-        // TODO verify permission
-        if (id.toLowerCase().equals("me")) {
-            return 1L;
-        } else if (StringUtils.isNumeric(id)) {
-            return Long.valueOf(id);
-        } else {
-            throw new IllegalArgumentException("User not found.");
-        }
-    }
-
-    private Long getUserId(Long id) {
-        return id == null ? getUserId("me") : id;
-    }
-
     // *********************** GET ****************************
 
     @RequestMapping(value = "/users/requests/vacation", method=GET)
@@ -75,9 +59,9 @@ public class ApiController extends BaseController {
 
     @RequestMapping(value = "/user/{id}/calendar", method=GET)
     public ResponseEntity userCalendar(
-            @PathVariable("id") String id,
+            @PathVariable("id") Long id,
             @RequestParam(value = "lang", required = false) String lang,
-            @RequestParam(value = "from", required = true) String from,
+            @RequestParam(value = "from") String from,
             @RequestParam(value = "to", required = false) String to,
             @RequestParam(value = "status", required = false) String status)
     {
@@ -85,7 +69,7 @@ public class ApiController extends BaseController {
             DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
             LocalDate fromDate = LocalDate.parse(from, formatter);
             LocalDate toDate = to != null ? LocalDate.parse(to, formatter) : null;
-            return manager.getUserCalendar(getUserId(id), fromDate, toDate, Status.getStatus(status));
+            return manager.getUserCalendar(id, fromDate, toDate, Status.getStatus(status));
         });
     }
 
@@ -93,8 +77,7 @@ public class ApiController extends BaseController {
     public ResponseEntity settings(
             @RequestParam(value = "lang", required = false) String lang)
     {
-        return handle(Language.getLanguage(lang), manager::getDefaultSettings
-        );
+        return handle(Language.getLanguage(lang), () -> new DefaultSettings(manager.getDefaultSettings()));
     }
 
     // *********************** POST ****************************
@@ -105,7 +88,7 @@ public class ApiController extends BaseController {
             @RequestBody DefaultSettings settings)
     {
         return handle(Language.getLanguage(lang), () ->
-                manager.createSettings(settings)
+                manager.createSettings(settings.toEntity())
         );
     }
 
@@ -128,10 +111,13 @@ public class ApiController extends BaseController {
     @RequestMapping(value = "/user/settings", method=PUT)
     public ResponseEntity userSettings(
             @RequestParam(value = "lang", required = false) String lang,
-            @RequestBody UserSettings settings)
+            @RequestBody UserSettings settings,
+            Authentication auth)
     {
+        //TODO make api endpoint contain userId in path as part of #39
+        //TODO drop the auth parameter afterwards
         return handle(Language.getLanguage(lang), () ->
-                manager.changeSettings(getUserId("me"), settings)
+                manager.changeSettings(((User) auth.getPrincipal()).getId(), settings)
         );
     }
 
