commit 5df617eb90045652f4a9e6225a5e7ab6043285ad
Author: Lukas Cerny <luc.cerny@gmail.com>
Date:   Sat Mar 23 13:19:49 2019 +0100

    Re #7143 Prepared developper's environment

diff --git a/.gitignore b/.gitignore
index a1c2a23..55166f6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,23 +1,28 @@
-# Compiled class file
-*.class
-
-# Log file
-*.log
-
-# BlueJ files
-*.ctxt
-
-# Mobile Tools for Java (J2ME)
-.mtj.tmp/
-
-# Package Files #
-*.jar
-*.war
-*.nar
-*.ear
-*.zip
-*.tar.gz
-*.rar
-
-# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
-hs_err_pid*
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+# IntelliJ
+.idea/* 
+*.iml
+ 
\ No newline at end of file
diff --git a/build.sh b/build.sh
new file mode 100644
index 0000000..446a4f5
--- /dev/null
+++ b/build.sh
@@ -0,0 +1 @@
+mvn package && docker restart yamanager_app
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..8148e62
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,33 @@
+version: '3.1'
+
+services:
+
+  app:
+    image: openjdk:13-jdk-alpine
+    container_name: yamanager_app
+    volumes:
+      - /tmp
+      - ./target/ymanager-1.0-SNAPSHOT.jar:/app.jar
+    entrypoint: java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 -Djava.security.egd=file:/dev/./urandom -jar /app.jar
+    restart: always
+    ports:
+      - 9080:8080
+      - 6005:5005
+    depends_on:
+      - db
+    links:
+      - db
+
+  db:
+    image: mariadb
+    container_name: yamanager_db
+    restart: always
+    volumes:
+      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
+    environment:
+      MYSQL_ROOT_PASSWORD: root
+      MYSQL_USER: user
+      MYSQL_PASSWORD: passwd
+      MYSQL_DATABASE: yamanager
+    ports:
+      - 3306:3306
\ No newline at end of file
diff --git a/init.sql b/init.sql
new file mode 100644
index 0000000..34a78ec
--- /dev/null
+++ b/init.sql
@@ -0,0 +1,10 @@
+CREATE TABLE test (
+  id MEDIUMINT NOT NULL AUTO_INCREMENT,
+  message VARCHAR(255),
+  PRIMARY KEY (id)
+);
+
+INSERT INTO test (message) VALUES ('test 1');
+INSERT INTO test (message) VALUES ('test 2');
+INSERT INTO test (message) VALUES ('test 3');
+INSERT INTO test (message) VALUES ('test 4');
\ No newline at end of file
diff --git a/install.sh b/install.sh
new file mode 100644
index 0000000..7d0dc6c
--- /dev/null
+++ b/install.sh
@@ -0,0 +1 @@
+docker-compose up
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..7ac16fe
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>cz.zcu.fav.kiv</groupId>
+    <artifactId>ymanager</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.0.5.RELEASE</version>
+    </parent>
+
+    <properties>
+        <java.version>1.8</java.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <!-- DATABASE -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-jdbc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mariadb.jdbc</groupId>
+            <artifactId>mariadb-java-client</artifactId>
+            <version>2.4.1</version>
+        </dependency>
+
+
+        <!-- TESTS -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>2.25.1</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/src/main/java/cz/zcu/yamanager/Application.java b/src/main/java/cz/zcu/yamanager/Application.java
new file mode 100644
index 0000000..c4ea291
--- /dev/null
+++ b/src/main/java/cz/zcu/yamanager/Application.java
@@ -0,0 +1,19 @@
+package cz.zcu.yamanager;
+
+import cz.zcu.yamanager.util.localization.Language;
+import cz.zcu.yamanager.util.localization.Message;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+    public static void main(String[] args) {
+
+        Message.config()
+                .addLanguage(Language.EN)
+                .addLanguage(Language.CZ);
+
+        SpringApplication.run(Application.class, args);
+    }
+}
diff --git a/src/main/java/cz/zcu/yamanager/domain/Test.java b/src/main/java/cz/zcu/yamanager/domain/Test.java
new file mode 100644
index 0000000..0c93da2
--- /dev/null
+++ b/src/main/java/cz/zcu/yamanager/domain/Test.java
@@ -0,0 +1,25 @@
+package cz.zcu.yamanager.domain;
+
+public class Test {
+
+    private final long id;
+    private final String message;
+
+    public Test(long id, String message) {
+        this.id = id;
+        this.message = message;
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("Test[id=%d, message='%s']", id, message);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/cz/zcu/yamanager/repository/HelloRepository.java b/src/main/java/cz/zcu/yamanager/repository/HelloRepository.java
new file mode 100644
index 0000000..1829f01
--- /dev/null
+++ b/src/main/java/cz/zcu/yamanager/repository/HelloRepository.java
@@ -0,0 +1,28 @@
+package cz.zcu.yamanager.repository;
+
+import cz.zcu.yamanager.domain.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public class HelloRepository {
+
+    private static final Logger log = LoggerFactory.getLogger(HelloRepository.class);
+
+    private final JdbcTemplate jdbc;
+
+    @Autowired
+    public HelloRepository(JdbcTemplate jdbc) {
+        this.jdbc = jdbc;
+    }
+
+    public List<Test> all() {
+        return jdbc.query("SELECT id, message FROM test",
+                (rs, rowNum) -> new Test(rs.getLong("id"), rs.getString("message")));
+    }
+}
diff --git a/src/main/java/cz/zcu/yamanager/util/localization/Language.java b/src/main/java/cz/zcu/yamanager/util/localization/Language.java
new file mode 100644
index 0000000..b475055
--- /dev/null
+++ b/src/main/java/cz/zcu/yamanager/util/localization/Language.java
@@ -0,0 +1,23 @@
+package cz.zcu.yamanager.util.localization;
+
+import java.util.Locale;
+
+public enum  Language {
+
+    EN  (Locale.ENGLISH),
+    CZ  (new Locale("cs", "")),
+
+    ;
+    private Locale locale;
+    Language(Locale locale) {
+        this.locale = locale;
+    }
+
+    public Locale getLocale() {
+        return locale;
+    }
+
+    public static Language get(String lang) {
+        return valueOf(lang.toUpperCase());
+    }
+}
diff --git a/src/main/java/cz/zcu/yamanager/util/localization/Message.java b/src/main/java/cz/zcu/yamanager/util/localization/Message.java
new file mode 100644
index 0000000..dfe0d01
--- /dev/null
+++ b/src/main/java/cz/zcu/yamanager/util/localization/Message.java
@@ -0,0 +1,44 @@
+package cz.zcu.yamanager.util.localization;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import static java.util.ResourceBundle.getBundle;
+
+public final class Message {
+
+    private static Map<Language, ResourceBundle> BUNDLES;
+
+    static {
+        BUNDLES = new HashMap<>();
+
+        config().addLanguage(Language.EN);
+    }
+
+    public interface Config {
+        Config addLanguage(Language language);
+    }
+
+    public static Config config() {
+        return new Config() {
+
+            @Override
+            public Config addLanguage(Language language) {
+                if (!BUNDLES.containsKey(language)) {
+                    BUNDLES.put(language, getBundle("Message", language.getLocale()));
+                }
+                return this;
+            }
+        };
+    }
+
+    public static String getString(Language language, String key) {
+        if (!BUNDLES.containsKey(language)) return language.name()+" SOURCE MISSING";
+        return BUNDLES.get(language).getString(key);
+    }
+
+    public static String getString(String key) {
+        return getString(Language.EN, key);
+    }
+}
diff --git a/src/main/java/cz/zcu/yamanager/ws/rest/HelloController.java b/src/main/java/cz/zcu/yamanager/ws/rest/HelloController.java
new file mode 100644
index 0000000..1869d7a
--- /dev/null
+++ b/src/main/java/cz/zcu/yamanager/ws/rest/HelloController.java
@@ -0,0 +1,35 @@
+package cz.zcu.yamanager.ws.rest;
+
+import cz.zcu.yamanager.domain.Test;
+import cz.zcu.yamanager.repository.HelloRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+import static cz.zcu.yamanager.util.localization.Language.get;
+import static cz.zcu.yamanager.util.localization.Message.getString;
+import static org.springframework.web.bind.annotation.RequestMethod.GET;
+
+@RestController
+public class HelloController {
+
+    private final HelloRepository repository;
+
+    @Autowired
+    public HelloController(HelloRepository repository) {
+        this.repository = repository;
+    }
+
+    @RequestMapping(value = "/hello", method=GET)
+    public String hello(@RequestParam(value = "lang", required = false, defaultValue = "en") String lang) {
+        return getString(get(lang), "hello");
+    }
+
+    @RequestMapping(value = "/database", method=GET)
+    public List<Test> database() {
+        return repository.all();
+    }
+}
diff --git a/src/main/java/cz/zcu/yamanager/ws/rest/TestController.java b/src/main/java/cz/zcu/yamanager/ws/rest/TestController.java
new file mode 100644
index 0000000..4b56de9
--- /dev/null
+++ b/src/main/java/cz/zcu/yamanager/ws/rest/TestController.java
@@ -0,0 +1,21 @@
+package cz.zcu.yamanager.ws.rest;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import static org.springframework.web.bind.annotation.RequestMethod.GET;
+import static org.springframework.web.bind.annotation.RequestMethod.POST;
+
+@RestController("/test")
+public class TestController {
+
+    @RequestMapping(method=GET)
+    public String get() {
+        return "test GET";
+    }
+
+    @RequestMapping(method=POST)
+    public String post() {
+        return "test POST";
+    }
+}
diff --git a/src/main/resources/Message_cs.properties b/src/main/resources/Message_cs.properties
new file mode 100644
index 0000000..93e0714
--- /dev/null
+++ b/src/main/resources/Message_cs.properties
@@ -0,0 +1 @@
+hello=Ahoj sv\u011Bte
diff --git a/src/main/resources/Message_en.properties b/src/main/resources/Message_en.properties
new file mode 100644
index 0000000..f67bdaa
--- /dev/null
+++ b/src/main/resources/Message_en.properties
@@ -0,0 +1 @@
+hello=Hello world
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
new file mode 100644
index 0000000..70e1f23
--- /dev/null
+++ b/src/main/resources/application.properties
@@ -0,0 +1,4 @@
+spring.datasource.url=jdbc:mariadb://db:3306/yamanager
+spring.datasource.username=user
+spring.datasource.password=passwd
+spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
\ No newline at end of file
diff --git a/src/test/java/cz/zcu/yamanager/util/localization/MessageTest.java b/src/test/java/cz/zcu/yamanager/util/localization/MessageTest.java
new file mode 100644
index 0000000..722963b
--- /dev/null
+++ b/src/test/java/cz/zcu/yamanager/util/localization/MessageTest.java
@@ -0,0 +1,43 @@
+package cz.zcu.yamanager.util.localization;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class MessageTest {
+
+    @Test
+    void getString_inCzech_true() {
+        Message.config().addLanguage(Language.CZ);
+
+        assertEquals("český jazyk", Message.getString(Language.CZ, "hello"));
+    }
+
+    @Test
+    void getString_inEnglish_true() {
+        Message.config().addLanguage(Language.EN);
+
+        assertEquals("english language", Message.getString(Language.EN, "hello"));
+    }
+
+    @Test
+    void getString_general_true() {
+        assertEquals("english language", Message.getString("hello"));
+    }
+
+    @Test
+    void getString_multiple_true() {
+        Message.config()
+                .addLanguage(Language.CZ)
+                .addLanguage(Language.EN);
+
+        assertEquals("český jazyk", Message.getString(Language.CZ, "hello"));
+        assertEquals("english language", Message.getString(Language.EN, "hello"));
+        assertEquals("english language", Message.getString("hello"));
+    }
+
+    @Test
+    void getString_missingSource_true() {
+        assertEquals("CZ SOURCE MISSING", Message.getString(Language.CZ, "hello"));
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/cz/zcu/yamanager/ws/rest/HelloControllerTest.java b/src/test/java/cz/zcu/yamanager/ws/rest/HelloControllerTest.java
new file mode 100644
index 0000000..d5edd8a
--- /dev/null
+++ b/src/test/java/cz/zcu/yamanager/ws/rest/HelloControllerTest.java
@@ -0,0 +1,32 @@
+package cz.zcu.yamanager.ws.rest;
+
+import cz.zcu.yamanager.util.localization.Language;
+import cz.zcu.yamanager.util.localization.Message;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class HelloControllerTest {
+
+    private HelloController helloController;
+
+    @BeforeEach
+    void setUp() {
+        Message.config()
+                .addLanguage(Language.EN)
+                .addLanguage(Language.CZ);
+
+        helloController = new HelloController(null);
+    }
+
+    @Test
+    void hello_inCzech_true() {
+        assertEquals("český jazyk", helloController.hello("cz"));
+    }
+
+    @Test
+    void hello_inEnglish_true() {
+        assertEquals("english language", helloController.hello("en"));
+    }
+}
\ No newline at end of file
diff --git a/src/test/resources/Message_cs.properties b/src/test/resources/Message_cs.properties
new file mode 100644
index 0000000..0f51c69
--- /dev/null
+++ b/src/test/resources/Message_cs.properties
@@ -0,0 +1 @@
+hello=\u010Desk\u00FD jazyk
diff --git a/src/test/resources/Message_en.properties b/src/test/resources/Message_en.properties
new file mode 100644
index 0000000..19da5d6
--- /dev/null
+++ b/src/test/resources/Message_en.properties
@@ -0,0 +1 @@
+hello=english language
