commit 767931cca99a16c23720e6dec4b0159e1108cc6b
Author: Jakub Danek <jakub.danek@yoso.fi>
Date:   Thu Oct 10 15:42:25 2019 +0200

    re #37 unify user profile endpoints under single controller and namespace

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 ff8fc53..9b6cd4a 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
@@ -5,31 +5,19 @@ import org.danekja.ymanager.business.FileService;
 import org.danekja.ymanager.business.Manager;
 import org.danekja.ymanager.dto.*;
 import org.danekja.ymanager.util.localization.Language;
-import org.danekja.ymanager.util.localization.Message;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpHeaders;
-import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Function;
 
-import static org.springframework.http.HttpStatus.OK;
-import static org.springframework.http.ResponseEntity.ok;
 import static org.springframework.web.bind.annotation.RequestMethod.*;
 
 @RestController
-public class ApiController {
-
-    private static final Logger log = LoggerFactory.getLogger(ApiController.class);
+public class ApiController extends BaseController {
 
     private final Manager manager;
 
@@ -41,58 +29,6 @@ public class ApiController {
         this.fileService = fileService;
     }
 
-    private ResponseEntity sendError(Integer errorCode, String messageKey, Language language) {
-        String localizedMessage = Message.getString(language, messageKey);
-        Map<String, String> result = new HashMap<>();
-        result.put("error", errorCode.toString());
-        result.put("message", localizedMessage);
-        return ResponseEntity.status(errorCode).contentType(MediaType.APPLICATION_JSON).body(result);
-    }
-
-    private <T> ResponseEntity handle(Language language, RESTInvokeHandler<T> handler) {
-        try {
-            handler.invoke();
-            return ok(OK);
-        } catch (RESTFullException e) {
-            log.error(e.getMessage());
-            return sendError(400, e.getLocalizedMessage(), language);
-        } catch (Exception e) {
-            log.error(e.getMessage());
-            return sendError(401, e.getMessage(), language);
-        }
-    }
-
-    private <T> ResponseEntity handle(Language language, RESTGetHandler<T> handler) {
-        return handle(language, handler, null, null);
-    }
-
-    private <T> ResponseEntity handle(Language language, RESTGetHandler<T> handler, Function<T, String[]> header, Function<T, Object> bodyValue) {
-        try {
-            T result = handler.get();
-
-            ResponseEntity.BodyBuilder response = ResponseEntity.ok();
-
-            if (header != null) {
-                String[] headers = header.apply(result);
-
-                if (headers.length > 1) {
-                    response.header(headers[0], Arrays.copyOfRange(headers, 1, headers.length - 1));
-                } else if (headers.length == 1) {
-                    response.header(headers[0]);
-                }
-            }
-
-            return response.body(bodyValue != null ? bodyValue.apply(result) : result);
-
-        } catch (RESTFullException e) {
-            log.error(e.getMessage());
-            return sendError(400, e.getLocalizedMessage(), language);
-        } catch (Exception e) {
-            log.error(e.getMessage());
-            return sendError(401, "rest.exception.generic", language);
-        }
-    }
-
     private Long getUserId(String id) {
         // TODO verify permission
         if (id.toLowerCase().equals("me")) {
@@ -140,16 +76,6 @@ public class ApiController {
          );
     }
 
-    @RequestMapping(value = "/user/{id}/profile", method=GET)
-    public ResponseEntity userProfile(
-            @PathVariable("id") String id,
-            @RequestParam(value = "lang", required = false) String lang)
-    {
-        return handle(Language.getLanguage(lang), () ->
-                manager.getUserProfile(getUserId(id))
-        );
-    }
-
     @RequestMapping(value = "/user/{id}/calendar", method=GET)
     public ResponseEntity userCalendar(
             @PathVariable("id") String id,
diff --git a/server/src/main/java/org/danekja/ymanager/ws/rest/BaseController.java b/server/src/main/java/org/danekja/ymanager/ws/rest/BaseController.java
new file mode 100644
index 0000000..88c6dd9
--- /dev/null
+++ b/server/src/main/java/org/danekja/ymanager/ws/rest/BaseController.java
@@ -0,0 +1,73 @@
+package org.danekja.ymanager.ws.rest;
+
+import org.danekja.ymanager.util.localization.Language;
+import org.danekja.ymanager.util.localization.Message;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Function;
+
+import static org.springframework.http.HttpStatus.OK;
+import static org.springframework.http.ResponseEntity.ok;
+
+public abstract class BaseController {
+
+    protected final Logger LOG = LoggerFactory.getLogger(this.getClass());
+
+    protected <T> ResponseEntity handle(Language language, RESTGetHandler<T> handler) {
+        return handle(language, handler, null, null);
+    }
+
+    protected <T> ResponseEntity handle(Language language, RESTGetHandler<T> handler, Function<T, String[]> header, Function<T, Object> bodyValue) {
+        try {
+            T result = handler.get();
+
+            ResponseEntity.BodyBuilder response = ResponseEntity.ok();
+
+            if (header != null) {
+                String[] headers = header.apply(result);
+
+                if (headers.length > 1) {
+                    response.header(headers[0], Arrays.copyOfRange(headers, 1, headers.length - 1));
+                } else if (headers.length == 1) {
+                    response.header(headers[0]);
+                }
+            }
+
+            return response.body(bodyValue != null ? bodyValue.apply(result) : result);
+
+        } catch (RESTFullException e) {
+            LOG.error(e.getMessage());
+            return sendError(400, e.getLocalizedMessage(), language);
+        } catch (Exception e) {
+            LOG.error(e.getMessage());
+            return sendError(401, "rest.exception.generic", language);
+        }
+    }
+
+    protected ResponseEntity sendError(Integer errorCode, String messageKey, Language language) {
+        String localizedMessage = Message.getString(language, messageKey);
+        Map<String, String> result = new HashMap<>();
+        result.put("error", errorCode.toString());
+        result.put("message", localizedMessage);
+        return ResponseEntity.status(errorCode).contentType(MediaType.APPLICATION_JSON).body(result);
+    }
+
+    protected <T> ResponseEntity handle(Language language, RESTInvokeHandler<T> handler) {
+        try {
+            handler.invoke();
+            return ok(OK);
+        } catch (RESTFullException e) {
+            LOG.error(e.getMessage());
+            return sendError(400, e.getLocalizedMessage(), language);
+        } catch (Exception e) {
+            LOG.error(e.getMessage());
+            return sendError(401, e.getMessage(), language);
+        }
+    }
+}
diff --git a/server/src/main/java/org/danekja/ymanager/ws/rest/UserController.java b/server/src/main/java/org/danekja/ymanager/ws/rest/UserController.java
index 57eaa5b..8cf4d84 100644
--- a/server/src/main/java/org/danekja/ymanager/ws/rest/UserController.java
+++ b/server/src/main/java/org/danekja/ymanager/ws/rest/UserController.java
@@ -1,24 +1,25 @@
 package org.danekja.ymanager.ws.rest;
 
-import org.danekja.ymanager.business.UserManager;
+import org.danekja.ymanager.business.Manager;
 import org.danekja.ymanager.domain.User;
-import org.danekja.ymanager.dto.FullUserProfile;
+import org.danekja.ymanager.util.localization.Language;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
 import org.springframework.security.authentication.AnonymousAuthenticationToken;
 import org.springframework.security.core.Authentication;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 /**
  * Controller for Users collection of WS API.
  */
-@RestController("/users")
-public class UserController {
+@RestController
+@RequestMapping("/users")
+public class UserController extends BaseController {
 
-    private final UserManager manager;
+    private final Manager manager;
 
     @Autowired
-    public UserController(UserManager manager) {
+    public UserController(Manager manager) {
         this.manager = manager;
     }
 
@@ -29,13 +30,23 @@ public class UserController {
      * @return user information object
      */
     @GetMapping("/current/profile")
-    public FullUserProfile getCurrentUser(Authentication auth) {
+    public ResponseEntity getCurrentUser(Authentication auth) {
 
-        if (auth instanceof AnonymousAuthenticationToken) {
+        if (auth instanceof AnonymousAuthenticationToken
+                || auth.getPrincipal() == null
+                || !(auth.getPrincipal() instanceof User)) {
             return null;
         }
 
-        User user = manager.getUser(auth.getName());
-        return user != null ? new FullUserProfile(user) : null;
+        return getUserProfile(((User) auth.getPrincipal()).getId(), null);
+    }
+
+    @GetMapping("/{id}/profile")
+    public ResponseEntity getUserProfile(
+            @PathVariable("id") Long id,
+            @RequestParam(value = "lang", required = false) String lang) {
+        return handle(Language.getLanguage(lang), () ->
+                manager.getUserProfile(id)
+        );
     }
 }
