From f7a4e893770324d4545077bfd227f8852e75861b Mon Sep 17 00:00:00 2001 From: Andreas Hiess Date: Wed, 18 Mar 2020 08:45:42 +0100 Subject: [PATCH 01/74] test --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index eb0e11c..fb5300b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ # ASD: Morning 4 This is the repository for the team *ASD: Morning 4* + + +TEST \ No newline at end of file From 4e2616e61834458b907da7fc28c902641f88754d Mon Sep 17 00:00:00 2001 From: Andreas Hiess Date: Wed, 18 Mar 2020 09:14:47 +0100 Subject: [PATCH 02/74] test --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fb5300b..f37b02f 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,4 @@ This is the repository for the team *ASD: Morning 4* -TEST \ No newline at end of file +Pull Request Test \ No newline at end of file From 014f521fb534e512291260d326e63dc4386b6e63 Mon Sep 17 00:00:00 2001 From: Christoph Pruell Date: Wed, 18 Mar 2020 09:24:03 +0100 Subject: [PATCH 03/74] Test 1 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eb0e11c..e6c2fd1 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # ASD: Morning 4 -This is the repository for the team *ASD: Morning 4* +This is the repository for the team *ASD: Morning 4*. :D From ff5eb767c03556db62872f4e4c0d457fa53c8169 Mon Sep 17 00:00:00 2001 From: Christoph Pruell Date: Wed, 18 Mar 2020 09:24:46 +0100 Subject: [PATCH 04/74] Test 1 --- .idea/.gitignore | 2 ++ .idea/misc.xml | 6 ++++++ .idea/modules.xml | 8 ++++++++ .idea/vcs.xml | 6 ++++++ ASD-Morning-4.iml | 9 +++++++++ 5 files changed, 31 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 ASD-Morning-4.iml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..5c98b42 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,2 @@ +# Default ignored files +/workspace.xml \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..639900d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..a6be809 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/ASD-Morning-4.iml b/ASD-Morning-4.iml new file mode 100644 index 0000000..8021953 --- /dev/null +++ b/ASD-Morning-4.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file From 25a01d18128b25f573e079a13a093d634ee3e4c4 Mon Sep 17 00:00:00 2001 From: eder13 Date: Wed, 18 Mar 2020 09:25:18 +0100 Subject: [PATCH 05/74] Test --- .idea/misc.xml | 6 ++++++ .idea/modules.xml | 8 ++++++++ .idea/vcs.xml | 6 ++++++ ASD-Morning-4.iml | 9 +++++++++ README.md | 2 ++ 5 files changed, 31 insertions(+) create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 ASD-Morning-4.iml diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..639900d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..a6be809 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/ASD-Morning-4.iml b/ASD-Morning-4.iml new file mode 100644 index 0000000..8021953 --- /dev/null +++ b/ASD-Morning-4.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index eb0e11c..7ced362 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # ASD: Morning 4 This is the repository for the team *ASD: Morning 4* + +Testing From fb60daebec47429a5a7f0e6b2898c5b233374315 Mon Sep 17 00:00:00 2001 From: Andreas Hiess Date: Wed, 18 Mar 2020 09:27:01 +0100 Subject: [PATCH 06/74] asd --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f37b02f..c7a8405 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,4 @@ This is the repository for the team *ASD: Morning 4* -Pull Request Test \ No newline at end of file +Pull Request Testasdasd \ No newline at end of file From 74900365e0511867b396103b63968e1726ccda2f Mon Sep 17 00:00:00 2001 From: eder13 Date: Wed, 18 Mar 2020 09:27:47 +0100 Subject: [PATCH 07/74] Test --- .idea/workspace.xml | 65 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 .idea/workspace.xml diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..2a260f5 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1584518659301 + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 00458e0f037af2d4e897d39be0bb4d3e561c1657 Mon Sep 17 00:00:00 2001 From: Christoph Pruell Date: Wed, 18 Mar 2020 09:27:49 +0100 Subject: [PATCH 08/74] Test 1 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e6c2fd1..dcdbff9 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # ASD: Morning 4 -This is the repository for the team *ASD: Morning 4*. :D +This is the repository for the team *ASD: Morning 4*. :) From 59f20264c13ba762e81c5c703a5846879de595e5 Mon Sep 17 00:00:00 2001 From: Andreas Hiess Date: Wed, 18 Mar 2020 09:28:02 +0100 Subject: [PATCH 09/74] asd --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c7a8405..f37b02f 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,4 @@ This is the repository for the team *ASD: Morning 4* -Pull Request Testasdasd \ No newline at end of file +Pull Request Test \ No newline at end of file From 45109336a652db8a7520788d27dd1f2ac2161886 Mon Sep 17 00:00:00 2001 From: eder13 Date: Wed, 18 Mar 2020 09:28:33 +0100 Subject: [PATCH 10/74] Test --- .idea/workspace.xml | 35 +++++++++++++++++++++++++++-------- README.md | 1 + 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 2a260f5..695cf3a 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,11 +1,7 @@ - - - - - + @@ -53,13 +64,21 @@ - + + + + + - + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 7ced362..c30cba1 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,4 @@ This is the repository for the team *ASD: Morning 4* Testing + \ No newline at end of file From 6ab40392fe969748d01b72f75d6bf75e6ecc3e2c Mon Sep 17 00:00:00 2001 From: Jan Date: Wed, 18 Mar 2020 09:45:40 +0100 Subject: [PATCH 11/74] test --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index eb0e11c..deab57b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # ASD: Morning 4 This is the repository for the team *ASD: Morning 4* + +Test From e21a32dab3d823f9b0c48321d98f52fe71c857df Mon Sep 17 00:00:00 2001 From: Simon Ranftl Date: Wed, 18 Mar 2020 09:46:06 +0100 Subject: [PATCH 12/74] Create .gitignore --- .gitignore | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8da0824 --- /dev/null +++ b/.gitignore @@ -0,0 +1,71 @@ +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser From 7302b94a96941d88e8769c0ecee732321ed8f40b Mon Sep 17 00:00:00 2001 From: eder13 Date: Wed, 18 Mar 2020 09:48:27 +0100 Subject: [PATCH 13/74] Add gitignore --- .idea/workspace.xml | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 695cf3a..d60fb0c 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,8 +1,8 @@ - - + + \ No newline at end of file From eed4997e6712244889190667158ba67909e8200d Mon Sep 17 00:00:00 2001 From: caaarinschn Date: Wed, 18 Mar 2020 08:52:04 +0000 Subject: [PATCH 14/74] test --- test.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 test.txt diff --git a/test.txt b/test.txt new file mode 100644 index 0000000..30d74d2 --- /dev/null +++ b/test.txt @@ -0,0 +1 @@ +test \ No newline at end of file From b03bb1477643693807f354975092e61368f050c4 Mon Sep 17 00:00:00 2001 From: caaarinschn Date: Wed, 18 Mar 2020 08:54:09 +0000 Subject: [PATCH 15/74] test --- test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.txt b/test.txt index 30d74d2..c436dcc 100644 --- a/test.txt +++ b/test.txt @@ -1 +1 @@ -test \ No newline at end of file +test help \ No newline at end of file From 45efc54d566571658b295863f17972e3ccb1efed Mon Sep 17 00:00:00 2001 From: Simon Ranftl Date: Wed, 18 Mar 2020 09:57:47 +0100 Subject: [PATCH 16/74] removed local intellij files --- .idea/.gitignore | 2 - .idea/misc.xml | 6 --- .idea/modules.xml | 8 ---- .idea/vcs.xml | 6 --- .idea/workspace.xml | 96 --------------------------------------------- 5 files changed, 118 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml delete mode 100644 .idea/workspace.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 5c98b42..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Default ignored files -/workspace.xml \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 639900d..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index a6be809..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml deleted file mode 100644 index d60fb0c..0000000 --- a/.idea/workspace.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - 1584518659301 - - - 1584519918726 - - - 1584520067521 - - - 1584520113524 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From f7ba18119cfc0cd2b389d0eb529d82ee73474392 Mon Sep 17 00:00:00 2001 From: sophfelg Date: Wed, 18 Mar 2020 09:59:45 +0100 Subject: [PATCH 17/74] testsophie --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index eb0e11c..23b752c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ # ASD: Morning 4 This is the repository for the team *ASD: Morning 4* +test From ec3bdaecc06281f185d668061df668cc6befcc73 Mon Sep 17 00:00:00 2001 From: Simon Ranftl Date: Wed, 18 Mar 2020 10:00:10 +0100 Subject: [PATCH 18/74] removed .iml file --- ASD-Morning-4.iml | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 ASD-Morning-4.iml diff --git a/ASD-Morning-4.iml b/ASD-Morning-4.iml deleted file mode 100644 index 8021953..0000000 --- a/ASD-Morning-4.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file From ea5d84e5700f7a63fdc90002c90dd21801792004 Mon Sep 17 00:00:00 2001 From: caaarinschn Date: Wed, 18 Mar 2020 09:00:28 +0000 Subject: [PATCH 19/74] entfernt --- README.md | 1 + test.txt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 test.txt diff --git a/README.md b/README.md index eb0e11c..9dc2c88 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ # ASD: Morning 4 This is the repository for the team *ASD: Morning 4* + diff --git a/test.txt b/test.txt deleted file mode 100644 index c436dcc..0000000 --- a/test.txt +++ /dev/null @@ -1 +0,0 @@ -test help \ No newline at end of file From 9bbe8ebee42373a11b1143a37a62f4e407767e23 Mon Sep 17 00:00:00 2001 From: eder13 Date: Wed, 18 Mar 2020 10:01:44 +0100 Subject: [PATCH 20/74] Add gitignore --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 752c381..478ac58 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,4 @@ This is the repository for the team *ASD: Morning 4*. :) -Testing \ No newline at end of file +Testing 2 added gitignore \ No newline at end of file From dd1aee2a75bccb04434255fe955278ed4a752347 Mon Sep 17 00:00:00 2001 From: eder13 Date: Wed, 18 Mar 2020 10:04:06 +0100 Subject: [PATCH 21/74] Initial Setup. --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 478ac58..4cf7bf3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ # ASD: Morning 4 -This is the repository for the team *ASD: Morning 4*. :) - -Testing 2 added gitignore \ No newline at end of file +This is the repository for the team *ASD: Morning 4*. \ No newline at end of file From 1b0fff0565c635458dc9582a30b5fdc853e9ae74 Mon Sep 17 00:00:00 2001 From: chr-pr <62071059+chr-pr@users.noreply.github.com> Date: Wed, 18 Mar 2020 10:21:00 +0100 Subject: [PATCH 22/74] Delete ASD-Morning-4.iml --- ASD-Morning-4.iml | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 ASD-Morning-4.iml diff --git a/ASD-Morning-4.iml b/ASD-Morning-4.iml deleted file mode 100644 index 8021953..0000000 --- a/ASD-Morning-4.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file From b153b1357ccc385f611add3639c2308baefbf7c2 Mon Sep 17 00:00:00 2001 From: eder13 Date: Wed, 18 Mar 2020 11:24:44 +0100 Subject: [PATCH 23/74] Added Meeting Notes. --- README.md | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 367250f..ce6fd5c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,26 @@ # ASD: Morning 4 -test +## Vocabulary Trainer +Vocabulary trainer is a dictionary and training application which allows its users to study and test +vocabulary in a foreign language. + +### Building + +-Coming soon- + +### Meeting Notes + +___18.03.2020___ + +* Using Teamspeak for Voice Calls +* WhatsApp, Slack and Teamspeak chat for messaging +* Setup GitHub Workflow with IntelliJ IDE + * GitHub Login, Fork, Push, Commits, Pull Requests +* Added .gitignore and updated README.md +* Web Application using Java Spring Boot as backend server framework and MySQL database (queries vocabularies). On the Fronted-Side we use HTML. +* TODO until next week: + * Read Java Spring Boot docs and setup a Spring Boot Test Project + * Read MySQL docs and setup everything + * Install Teamviewer for collaborative programming + * Split into groups and create branch for each Issue From 0a97ee75b5c836dad4c2734ac1821310a120e11b Mon Sep 17 00:00:00 2001 From: eder13 Date: Sat, 21 Mar 2020 11:05:28 +0100 Subject: [PATCH 24/74] Add .gitignore for Spring Boot Project. --- .gitignore | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/.gitignore b/.gitignore index 8da0824..090839d 100644 --- a/.gitignore +++ b/.gitignore @@ -69,3 +69,37 @@ fabric.properties # Android studio 3.1+ serialized cache file .idea/caches/build_file_checksums.ser + +## Import from Spring Initializr Web .gitignore + +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/** +!**/src/test/** + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ + +### VS Code ### +.vscode/ From e249a1d4c1f106cef99dfd81a08e8e70dcdb1892 Mon Sep 17 00:00:00 2001 From: eder13 Date: Sat, 21 Mar 2020 12:20:08 +0100 Subject: [PATCH 25/74] Create Spring Boot Project --- mvnw | 310 ++++++++++++++++++ mvnw.cmd | 182 ++++++++++ pom.xml | 49 +++ .../JavaSpringIdeaApplication.java | 13 + .../controllers/ExampleController.java | 24 ++ src/main/resources/application.properties | 1 + .../JavaSpringIdeaApplicationTests.java | 13 + 7 files changed, 592 insertions(+) create mode 100755 mvnw create mode 100644 mvnw.cmd create mode 100644 pom.xml create mode 100644 src/main/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplication.java create mode 100644 src/main/java/br/com/asd4m/javaspringidea/controllers/ExampleController.java create mode 100644 src/main/resources/application.properties create mode 100644 src/test/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplicationTests.java diff --git a/mvnw b/mvnw new file mode 100755 index 0000000..a16b543 --- /dev/null +++ b/mvnw @@ -0,0 +1,310 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..c8d4337 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,182 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..b00f77c --- /dev/null +++ b/pom.xml @@ -0,0 +1,49 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.2.5.RELEASE + + + br.com.asd4m + java-spring-idea + 0.0.1-SNAPSHOT + java-spring-idea + Project Files for Vocabulary Trainer + + + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/src/main/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplication.java b/src/main/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplication.java new file mode 100644 index 0000000..96faff1 --- /dev/null +++ b/src/main/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplication.java @@ -0,0 +1,13 @@ +package br.com.asd4m.javaspringidea; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class JavaSpringIdeaApplication { + + public static void main(String[] args) { + SpringApplication.run(JavaSpringIdeaApplication.class, args); + } + +} diff --git a/src/main/java/br/com/asd4m/javaspringidea/controllers/ExampleController.java b/src/main/java/br/com/asd4m/javaspringidea/controllers/ExampleController.java new file mode 100644 index 0000000..c2b7b5e --- /dev/null +++ b/src/main/java/br/com/asd4m/javaspringidea/controllers/ExampleController.java @@ -0,0 +1,24 @@ +package br.com.asd4m.javaspringidea.controllers; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * ExampleController + * + * @author ASD-Morning-4 + * + */ + +@RestController +@RequestMapping("/api/example") +public class ExampleController { + + @GetMapping("/hello-world") + public ResponseEntity get() { + return ResponseEntity.ok("Hello World!"); + } + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/src/test/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplicationTests.java b/src/test/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplicationTests.java new file mode 100644 index 0000000..15ca702 --- /dev/null +++ b/src/test/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplicationTests.java @@ -0,0 +1,13 @@ +package br.com.asd4m.javaspringidea; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class JavaSpringIdeaApplicationTests { + + @Test + void contextLoads() { + } + +} From 41274993fb4639907594b106d0554caa14a07ddf Mon Sep 17 00:00:00 2001 From: eder13 Date: Sat, 21 Mar 2020 13:21:45 +0100 Subject: [PATCH 26/74] Update Readme.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ce6fd5c..9993b9f 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ vocabulary in a foreign language. ### Building --Coming soon- +---Coming soon--- ### Meeting Notes From 47aa372f18d81acc873247b5a561f3214d09e508 Mon Sep 17 00:00:00 2001 From: Andreas Hiess Date: Sat, 21 Mar 2020 15:01:51 +0100 Subject: [PATCH 27/74] setup-project --- .idea/.name | 1 + .idea/compiler.xml | 18 + .idea/encodings.xml | 6 + .idea/misc.xml | 14 + .idea/vcs.xml | 6 + .mvn/wrapper/MavenWrapperDownloader.java | 117 +++++++ .mvn/wrapper/maven-wrapper.jar | Bin 0 -> 50710 bytes .mvn/wrapper/maven-wrapper.properties | 2 + HELP.md | 21 ++ mvnw | 310 ++++++++++++++++++ mvnw.cmd | 182 ++++++++++ pom.xml | 49 +++ .../ASD/Morning4/Morning4Application.java | 13 + .../controller/ExampleController.java | 18 + src/main/resources/application.properties | 1 + .../Morning4/Morning4ApplicationTests.java | 13 + 16 files changed, 771 insertions(+) create mode 100644 .idea/.name create mode 100644 .idea/compiler.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/vcs.xml create mode 100644 .mvn/wrapper/MavenWrapperDownloader.java create mode 100644 .mvn/wrapper/maven-wrapper.jar create mode 100644 .mvn/wrapper/maven-wrapper.properties create mode 100644 HELP.md create mode 100644 mvnw create mode 100644 mvnw.cmd create mode 100644 pom.xml create mode 100644 src/main/java/ASD/Morning4/Morning4Application.java create mode 100644 src/main/java/ASD/Morning4/controller/ExampleController.java create mode 100644 src/main/resources/application.properties create mode 100644 src/test/java/ASD/Morning4/Morning4ApplicationTests.java diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..decaa25 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +Morning-4 \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..30edeea --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..b26911b --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..d24ea8e --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 0000000..e76d1f3 --- /dev/null +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,117 @@ +/* + * Copyright 2007-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + private static final String WRAPPER_VERSION = "0.5.6"; + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" + + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if(mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if(mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { + String username = System.getenv("MVNW_USERNAME"); + char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); + Authenticator.setDefault(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(username, password); + } + }); + } + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..2cc7d4a55c0cd0092912bf49ae38b3a9e3fd0054 GIT binary patch literal 50710 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 EfAhh=DF6Tf literal 0 HcmV?d00001 diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..642d572 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git a/HELP.md b/HELP.md new file mode 100644 index 0000000..c106dcd --- /dev/null +++ b/HELP.md @@ -0,0 +1,21 @@ +# Read Me First +The following was discovered as part of building this project: + +* The original package name 'ASD.Morning-4' is invalid and this project uses 'ASD.Morning4' instead. + +# Getting Started + +### Reference Documentation +For further reference, please consider the following sections: + +* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html) +* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/maven-plugin/) +* [Spring Web](https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#boot-features-developing-web-applications) + +### Guides +The following guides illustrate how to use some features concretely: + +* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/) +* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/) +* [Building REST services with Spring](https://spring.io/guides/tutorials/bookmarks/) + diff --git a/mvnw b/mvnw new file mode 100644 index 0000000..a16b543 --- /dev/null +++ b/mvnw @@ -0,0 +1,310 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..c8d4337 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,182 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..b2063c5 --- /dev/null +++ b/pom.xml @@ -0,0 +1,49 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.2.5.RELEASE + + + ASD + Morning-4 + 0.0.1-SNAPSHOT + Morning-4 + Demo project for Spring Boot + + + 11 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/src/main/java/ASD/Morning4/Morning4Application.java b/src/main/java/ASD/Morning4/Morning4Application.java new file mode 100644 index 0000000..a8ad723 --- /dev/null +++ b/src/main/java/ASD/Morning4/Morning4Application.java @@ -0,0 +1,13 @@ +package ASD.Morning4; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Morning4Application { + + public static void main(String[] args) { + SpringApplication.run(Morning4Application.class, args); + } + +} diff --git a/src/main/java/ASD/Morning4/controller/ExampleController.java b/src/main/java/ASD/Morning4/controller/ExampleController.java new file mode 100644 index 0000000..bb5e28f --- /dev/null +++ b/src/main/java/ASD/Morning4/controller/ExampleController.java @@ -0,0 +1,18 @@ +package ASD.Morning4.controller; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + + +@RestController +@RequestMapping("") +public class ExampleController { + + @GetMapping("") + public ResponseEntity get() { + return ResponseEntity.ok("Hello World!"); + } + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/src/test/java/ASD/Morning4/Morning4ApplicationTests.java b/src/test/java/ASD/Morning4/Morning4ApplicationTests.java new file mode 100644 index 0000000..b96b41f --- /dev/null +++ b/src/test/java/ASD/Morning4/Morning4ApplicationTests.java @@ -0,0 +1,13 @@ +package ASD.Morning4; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class Morning4ApplicationTests { + + @Test + void contextLoads() { + } + +} From bce8cdb8263247db3edabd15807f71b507d42621 Mon Sep 17 00:00:00 2001 From: sseiH <62178996+sseiH@users.noreply.github.com> Date: Sat, 21 Mar 2020 15:04:15 +0100 Subject: [PATCH 28/74] Delete MavenWrapperDownloader.java --- .mvn/wrapper/MavenWrapperDownloader.java | 117 ----------------------- 1 file changed, 117 deletions(-) delete mode 100644 .mvn/wrapper/MavenWrapperDownloader.java diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java deleted file mode 100644 index e76d1f3..0000000 --- a/.mvn/wrapper/MavenWrapperDownloader.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2007-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import java.net.*; -import java.io.*; -import java.nio.channels.*; -import java.util.Properties; - -public class MavenWrapperDownloader { - - private static final String WRAPPER_VERSION = "0.5.6"; - /** - * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. - */ - private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" - + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; - - /** - * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to - * use instead of the default one. - */ - private static final String MAVEN_WRAPPER_PROPERTIES_PATH = - ".mvn/wrapper/maven-wrapper.properties"; - - /** - * Path where the maven-wrapper.jar will be saved to. - */ - private static final String MAVEN_WRAPPER_JAR_PATH = - ".mvn/wrapper/maven-wrapper.jar"; - - /** - * Name of the property which should be used to override the default download url for the wrapper. - */ - private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; - - public static void main(String args[]) { - System.out.println("- Downloader started"); - File baseDirectory = new File(args[0]); - System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); - - // If the maven-wrapper.properties exists, read it and check if it contains a custom - // wrapperUrl parameter. - File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); - String url = DEFAULT_DOWNLOAD_URL; - if(mavenWrapperPropertyFile.exists()) { - FileInputStream mavenWrapperPropertyFileInputStream = null; - try { - mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); - Properties mavenWrapperProperties = new Properties(); - mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); - url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); - } catch (IOException e) { - System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); - } finally { - try { - if(mavenWrapperPropertyFileInputStream != null) { - mavenWrapperPropertyFileInputStream.close(); - } - } catch (IOException e) { - // Ignore ... - } - } - } - System.out.println("- Downloading from: " + url); - - File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); - if(!outputFile.getParentFile().exists()) { - if(!outputFile.getParentFile().mkdirs()) { - System.out.println( - "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); - } - } - System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); - try { - downloadFileFromURL(url, outputFile); - System.out.println("Done"); - System.exit(0); - } catch (Throwable e) { - System.out.println("- Error downloading"); - e.printStackTrace(); - System.exit(1); - } - } - - private static void downloadFileFromURL(String urlString, File destination) throws Exception { - if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { - String username = System.getenv("MVNW_USERNAME"); - char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); - Authenticator.setDefault(new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(username, password); - } - }); - } - URL website = new URL(urlString); - ReadableByteChannel rbc; - rbc = Channels.newChannel(website.openStream()); - FileOutputStream fos = new FileOutputStream(destination); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - fos.close(); - rbc.close(); - } - -} From cc781ba0c62242bdf4a027d83660d6b3493c6d6c Mon Sep 17 00:00:00 2001 From: sseiH <62178996+sseiH@users.noreply.github.com> Date: Sat, 21 Mar 2020 15:04:28 +0100 Subject: [PATCH 29/74] Delete maven-wrapper.jar --- .mvn/wrapper/maven-wrapper.jar | Bin 50710 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .mvn/wrapper/maven-wrapper.jar diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 2cc7d4a55c0cd0092912bf49ae38b3a9e3fd0054..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50710 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 EfAhh=DF6Tf From cee307b80bfa06d074e0841514ba3c3d061eae27 Mon Sep 17 00:00:00 2001 From: sseiH <62178996+sseiH@users.noreply.github.com> Date: Sat, 21 Mar 2020 15:04:33 +0100 Subject: [PATCH 30/74] Delete maven-wrapper.properties --- .mvn/wrapper/maven-wrapper.properties | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 .mvn/wrapper/maven-wrapper.properties diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index 642d572..0000000 --- a/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1,2 +0,0 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar From 0f9448b9ae6b3e24a11c9059b9d1df4d19415c67 Mon Sep 17 00:00:00 2001 From: sseiH <62178996+sseiH@users.noreply.github.com> Date: Sat, 21 Mar 2020 15:04:41 +0100 Subject: [PATCH 31/74] Delete .name --- .idea/.name | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .idea/.name diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index decaa25..0000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -Morning-4 \ No newline at end of file From aff5d834c2d2d9a9e28f55db17ee9899a2489ce3 Mon Sep 17 00:00:00 2001 From: sseiH <62178996+sseiH@users.noreply.github.com> Date: Sat, 21 Mar 2020 15:04:46 +0100 Subject: [PATCH 32/74] Delete compiler.xml --- .idea/compiler.xml | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 .idea/compiler.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index 30edeea..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file From 88255533d43bfeb86f95b232da63c817bf44345e Mon Sep 17 00:00:00 2001 From: sseiH <62178996+sseiH@users.noreply.github.com> Date: Sat, 21 Mar 2020 15:04:51 +0100 Subject: [PATCH 33/74] Delete encodings.xml --- .idea/encodings.xml | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .idea/encodings.xml diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index b26911b..0000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From f982ed2b0869464cd0a568334e3a21f8299b870f Mon Sep 17 00:00:00 2001 From: sseiH <62178996+sseiH@users.noreply.github.com> Date: Sat, 21 Mar 2020 15:04:56 +0100 Subject: [PATCH 34/74] Delete misc.xml --- .idea/misc.xml | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 .idea/misc.xml diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index d24ea8e..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - \ No newline at end of file From 06c686ccda71f7d5c238830067143cd856d3dbba Mon Sep 17 00:00:00 2001 From: sseiH <62178996+sseiH@users.noreply.github.com> Date: Sat, 21 Mar 2020 15:05:01 +0100 Subject: [PATCH 35/74] Delete vcs.xml --- .idea/vcs.xml | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .idea/vcs.xml diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From e58cc3ff3d1e572d31221902e9aa1bbb9676f82b Mon Sep 17 00:00:00 2001 From: eder13 Date: Sat, 21 Mar 2020 15:08:40 +0100 Subject: [PATCH 36/74] Update Readme.md --- README.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9993b9f..4819c1e 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,22 @@ Vocabulary trainer is a dictionary and training application which allows its users to study and test vocabulary in a foreign language. -### Building +### Setup ----Coming soon--- +### Requirements + +* Java installed +* JDK 8 or higher +* JetBrains IntelliJ Ultimate IDE + +### Building and Running + +* Clone/Download this repository +* Start IntelliJ and click 'Open' +* Navigate in your cloned repo folder, choose the `pom.xml` file and click 'ok' +* After prompted 'pom.xml is a project file' click 'Open as Project' +* To start the application hit the green 'play button', the spring boot application will start (see Run) +* Navigate in your Browser to the home url: `http://localhost:8080/api/example/hello-world` (this will be changed...) ### Meeting Notes From d824d99541bd6aa52de056bce17374eb11fccff7 Mon Sep 17 00:00:00 2001 From: Andreas Hiess Date: Sat, 21 Mar 2020 15:43:15 +0100 Subject: [PATCH 37/74] setup-project --- .gitignore | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/.gitignore b/.gitignore index 8da0824..90cfb56 100644 --- a/.gitignore +++ b/.gitignore @@ -69,3 +69,37 @@ fabric.properties # Android studio 3.1+ serialized cache file .idea/caches/build_file_checksums.ser + +## Import from Spring Initializr Web .gitignore + +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/** +!**/src/test/** + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ + +### VS Code ### +.vscode/ \ No newline at end of file From 0c822991e7cf4eced834ba5c57c75905cde723ce Mon Sep 17 00:00:00 2001 From: eder13 Date: Sat, 21 Mar 2020 19:16:53 +0100 Subject: [PATCH 38/74] Updated Index and Added Unit Test --- README.md | 5 +-- .../JavaSpringIdeaApplication.java | 29 ++++++++++++++- .../controllers/ExampleController.java | 21 ++++++----- .../JavaSpringIdeaApplicationTests.java | 35 ++++++++++++++++--- 4 files changed, 74 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 4819c1e..b1bfbec 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,9 @@ vocabulary in a foreign language. * Start IntelliJ and click 'Open' * Navigate in your cloned repo folder, choose the `pom.xml` file and click 'ok' * After prompted 'pom.xml is a project file' click 'Open as Project' -* To start the application hit the green 'play button', the spring boot application will start (see Run) -* Navigate in your Browser to the home url: `http://localhost:8080/api/example/hello-world` (this will be changed...) +* To start the application hit the green 'play button' (JavaSpringIdeaApplication selected), the spring boot application will start (see Run) + * Alternatively, you can also right-click on `JavapringIdeaApplication.java` and click 'Run' +* Navigate in your Browser to the home url: `http://localhost:8080 ### Meeting Notes diff --git a/src/main/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplication.java b/src/main/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplication.java index 96faff1..24b1a9d 100644 --- a/src/main/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplication.java +++ b/src/main/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplication.java @@ -1,13 +1,40 @@ package br.com.asd4m.javaspringidea; +import java.util.Arrays; + +import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; @SpringBootApplication public class JavaSpringIdeaApplication { + // Main Class public static void main(String[] args) { - SpringApplication.run(JavaSpringIdeaApplication.class, args); + + // here you can write "classic" java ... + // System.out.println("This is som text\n"); + + // Start SpringApplication + SpringApplication.run(JavaSpringIdeaApplication.class, args); } + /* + @Bean + public CommandLineRunner commandLineRunner(ApplicationContext ctx) { + return args -> { + + System.out.println("Let's inspect the beans provided by Spring Boot:"); + + String[] beanNames = ctx.getBeanDefinitionNames(); + Arrays.sort(beanNames); + for (String beanName : beanNames) { + System.out.println(beanName); + } + + }; + } + */ } diff --git a/src/main/java/br/com/asd4m/javaspringidea/controllers/ExampleController.java b/src/main/java/br/com/asd4m/javaspringidea/controllers/ExampleController.java index c2b7b5e..59707ff 100644 --- a/src/main/java/br/com/asd4m/javaspringidea/controllers/ExampleController.java +++ b/src/main/java/br/com/asd4m/javaspringidea/controllers/ExampleController.java @@ -1,7 +1,7 @@ package br.com.asd4m.javaspringidea.controllers; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; +// import org.springframework.http.ResponseEntity; +// import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -12,13 +12,18 @@ * */ -@RestController -@RequestMapping("/api/example") +@RestController // thic class means it is ready for use by Spring MVC to handle web requests +//@RequestMapping("/api/example") public class ExampleController { - @GetMapping("/hello-world") - public ResponseEntity get() { - return ResponseEntity.ok("Hello World!"); - } + //@GetMapping("/hello-world") + //public ResponseEntity get() { + // return ResponseEntity.ok("Hello World!"); + //} + // http://localhost:8080/ + @RequestMapping("/") // this maps to the index() method + public String index() { + return "Greetings from Spring Boot!"; + } } diff --git a/src/test/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplicationTests.java b/src/test/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplicationTests.java index 15ca702..8312170 100644 --- a/src/test/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplicationTests.java +++ b/src/test/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplicationTests.java @@ -1,13 +1,38 @@ package br.com.asd4m.javaspringidea; +import static org.assertj.core.api.Assertions.*; + +import java.net.URL; + +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.http.ResponseEntity; -@SpringBootTest -class JavaSpringIdeaApplicationTests { +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class JavaSpringIdeaApplicationTests { - @Test - void contextLoads() { + @LocalServerPort + private int port; + + private URL base; + + @Autowired + private TestRestTemplate template; + + @BeforeEach + public void setUp() throws Exception { + this.base = new URL("http://localhost:" + port + "/"); } -} + @Test + public void getHello() throws Exception { + ResponseEntity response = template.getForEntity(base.toString(), + String.class); + assertThat(response.getBody().equals("Greetings from Spring Boot!")); + } +} \ No newline at end of file From 812e26b6613a9ddd6bdeacbd231f39aa0d7333fb Mon Sep 17 00:00:00 2001 From: eder13 Date: Sun, 22 Mar 2020 17:36:11 +0100 Subject: [PATCH 39/74] Added MySQL Support --- README.md | 3 +- pom.xml | 13 +++++ .../controllers/ExampleController.java | 29 ---------- .../project/MainApplication.java} | 22 +++---- .../com/vocabularytrainer/project/User.java | 41 +++++++++++++ .../project/UserRepository.java | 12 ++++ .../project/controllers/Controller.java | 57 +++++++++++++++++++ src/main/resources/application.properties | 5 +- .../project/MainApplicationTests.java} | 4 +- 9 files changed, 142 insertions(+), 44 deletions(-) delete mode 100644 src/main/java/br/com/asd4m/javaspringidea/controllers/ExampleController.java rename src/main/java/{br/com/asd4m/javaspringidea/JavaSpringIdeaApplication.java => com/vocabularytrainer/project/MainApplication.java} (77%) create mode 100644 src/main/java/com/vocabularytrainer/project/User.java create mode 100644 src/main/java/com/vocabularytrainer/project/UserRepository.java create mode 100644 src/main/java/com/vocabularytrainer/project/controllers/Controller.java rename src/test/java/{br/com/asd4m/javaspringidea/JavaSpringIdeaApplicationTests.java => com/vocabularytrainer/project/MainApplicationTests.java} (92%) diff --git a/README.md b/README.md index b1bfbec..1bd283e 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,9 @@ vocabulary in a foreign language. ### Requirements -* Java installed +* Java SDK 1.8 or higher * JDK 8 or higher +* MySQL 5.6 or higher * JetBrains IntelliJ Ultimate IDE ### Building and Running diff --git a/pom.xml b/pom.xml index b00f77c..8b1da8a 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,12 @@ + + + org.springframework.boot + spring-boot-starter-data-jpa + + org.springframework.boot spring-boot-starter-web @@ -35,6 +41,13 @@ + + + mysql + mysql-connector-java + runtime + + diff --git a/src/main/java/br/com/asd4m/javaspringidea/controllers/ExampleController.java b/src/main/java/br/com/asd4m/javaspringidea/controllers/ExampleController.java deleted file mode 100644 index 59707ff..0000000 --- a/src/main/java/br/com/asd4m/javaspringidea/controllers/ExampleController.java +++ /dev/null @@ -1,29 +0,0 @@ -package br.com.asd4m.javaspringidea.controllers; - -// import org.springframework.http.ResponseEntity; -// import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * ExampleController - * - * @author ASD-Morning-4 - * - */ - -@RestController // thic class means it is ready for use by Spring MVC to handle web requests -//@RequestMapping("/api/example") -public class ExampleController { - - //@GetMapping("/hello-world") - //public ResponseEntity get() { - // return ResponseEntity.ok("Hello World!"); - //} - - // http://localhost:8080/ - @RequestMapping("/") // this maps to the index() method - public String index() { - return "Greetings from Spring Boot!"; - } -} diff --git a/src/main/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplication.java b/src/main/java/com/vocabularytrainer/project/MainApplication.java similarity index 77% rename from src/main/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplication.java rename to src/main/java/com/vocabularytrainer/project/MainApplication.java index 24b1a9d..f4acc10 100644 --- a/src/main/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplication.java +++ b/src/main/java/com/vocabularytrainer/project/MainApplication.java @@ -1,27 +1,28 @@ -package br.com.asd4m.javaspringidea; +package com.vocabularytrainer.project; -import java.util.Arrays; - -import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; + +// Show all beans (1) +/* +import java.util.Arrays; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; +import org.springframework.boot.CommandLineRunner; +*/ @SpringBootApplication -public class JavaSpringIdeaApplication { +public class MainApplication { // Main Class public static void main(String[] args) { - // here you can write "classic" java ... - // System.out.println("This is som text\n"); - // Start SpringApplication - SpringApplication.run(JavaSpringIdeaApplication.class, args); + SpringApplication.run(MainApplication.class, args); } - /* + // Show all beans (2) + /* @Bean public CommandLineRunner commandLineRunner(ApplicationContext ctx) { return args -> { @@ -33,7 +34,6 @@ public CommandLineRunner commandLineRunner(ApplicationContext ctx) { for (String beanName : beanNames) { System.out.println(beanName); } - }; } */ diff --git a/src/main/java/com/vocabularytrainer/project/User.java b/src/main/java/com/vocabularytrainer/project/User.java new file mode 100644 index 0000000..9be6e5c --- /dev/null +++ b/src/main/java/com/vocabularytrainer/project/User.java @@ -0,0 +1,41 @@ +package com.vocabularytrainer.project; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity // This tells Hibernate to make a table out of this class +public class User { + @Id + @GeneratedValue(strategy=GenerationType.AUTO) + private Integer id; + + private String name; + + private String email; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } +} diff --git a/src/main/java/com/vocabularytrainer/project/UserRepository.java b/src/main/java/com/vocabularytrainer/project/UserRepository.java new file mode 100644 index 0000000..4c355ea --- /dev/null +++ b/src/main/java/com/vocabularytrainer/project/UserRepository.java @@ -0,0 +1,12 @@ +package com.vocabularytrainer.project; + +import org.springframework.data.repository.CrudRepository; + +// This will be AUTO IMPLEMENTED by Spring into a Bean called userRepository +// CRUD refers Create, Read, Update, Delete + +public interface UserRepository extends CrudRepository { + + + +} diff --git a/src/main/java/com/vocabularytrainer/project/controllers/Controller.java b/src/main/java/com/vocabularytrainer/project/controllers/Controller.java new file mode 100644 index 0000000..afec434 --- /dev/null +++ b/src/main/java/com/vocabularytrainer/project/controllers/Controller.java @@ -0,0 +1,57 @@ +package com.vocabularytrainer.project.controllers; + +import com.vocabularytrainer.project.UserRepository; // import the clas UserRepository +import com.vocabularytrainer.project.User; // import the User statement + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; // Restcontroller, Requestmapping, RequestParameter, GetMapping ... + +import org.springframework.beans.factory.annotation.Autowired; + +/** + * ExampleController + * + * @author ASD-Morning-4 + * + */ + +@EnableAutoConfiguration +@RestController // this class means it is ready for use by Spring MVC to handle web requests + +public class Controller { + + /* Hello World Example */ + @RequestMapping("/") + public ResponseEntity get() { + return ResponseEntity.ok("Greetings from Spring Boot!"); + } + + /* The Database Example */ + @Autowired // This means to get the bean called userRepository + // Which is auto-generated by Spring, we will use it to handle the data + private UserRepository userRepository; + + @RequestMapping(value = "/add") // , method = RequestMethod.GET) // <-> //@PostMapping(path="/add", method=RequestMethod.POST) // Map ONLY POST Requests + public String addNewUser (@RequestParam String name + , @RequestParam String email) { + // @ResponseBody means the returned String is the response, not a view name + // @RequestParam means it is a parameter from the GET or POST request + + User n = new User(); + n.setName(name); + n.setEmail(email); + userRepository.save(n); + return "Saved"; + } + + // add entry with: http://localhost:8080/add?name=Alice&email=alice@mail.com + + @RequestMapping(path="/all") + public Iterable getAllUsers() { + // This returns a JSON or XML with the users + return userRepository.findAll(); + } + + // show entries (as json): http://localhost:8080/all +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8b13789..c0cf6ff 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,4 @@ - +spring.jpa.hibernate.ddl-auto=update +spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_vocabularies +spring.datasource.username=student +spring.datasource.password=student diff --git a/src/test/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplicationTests.java b/src/test/java/com/vocabularytrainer/project/MainApplicationTests.java similarity index 92% rename from src/test/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplicationTests.java rename to src/test/java/com/vocabularytrainer/project/MainApplicationTests.java index 8312170..09725a1 100644 --- a/src/test/java/br/com/asd4m/javaspringidea/JavaSpringIdeaApplicationTests.java +++ b/src/test/java/com/vocabularytrainer/project/MainApplicationTests.java @@ -1,4 +1,4 @@ -package br.com.asd4m.javaspringidea; +package com.vocabularytrainer.project; import static org.assertj.core.api.Assertions.*; @@ -14,7 +14,7 @@ import org.springframework.http.ResponseEntity; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -public class JavaSpringIdeaApplicationTests { +public class MainApplicationTests { @LocalServerPort private int port; From 4e30e451b96546cb8f03adce2f5eb2615b9b00a6 Mon Sep 17 00:00:00 2001 From: Christoph Pruell Date: Mon, 23 Mar 2020 09:49:44 +0100 Subject: [PATCH 40/74] Repo Test --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ce6fd5c..26ea537 100644 --- a/README.md +++ b/README.md @@ -23,4 +23,4 @@ ___18.03.2020___ * Read Java Spring Boot docs and setup a Spring Boot Test Project * Read MySQL docs and setup everything * Install Teamviewer for collaborative programming - * Split into groups and create branch for each Issue + * Split into groups and create branch for each Issue. From e9cb10d663485872b8e36c902633a3c6573f513c Mon Sep 17 00:00:00 2001 From: eder13 Date: Mon, 23 Mar 2020 18:42:45 +0100 Subject: [PATCH 41/74] Playing Around with Java Spring Boot and Thymeleaf --- pom.xml | 24 ++++ src/main/.DS_Store | Bin 0 -> 8196 bytes src/main/java/com/vocabularytrainer/.DS_Store | Bin 0 -> 8196 bytes .../com/vocabularytrainer/project/.DS_Store | Bin 0 -> 6148 bytes .../com/vocabularytrainer/project/User.java | 41 ------- .../project/UserRepository.java | 12 -- .../project/config/SecurityConfig.java | 71 ++++++++++++ .../project/controllers/Controller.java | 57 ---------- .../project/controllers/IssueController.java | 95 ++++++++++++++++ .../project/db/IssueRepository.java | 17 +++ .../project/entity/IssueReport.java | 105 ++++++++++++++++++ .../web/LoggingAccessDeniedHandler.java | 37 ++++++ src/main/resources/.DS_Store | Bin 0 -> 8196 bytes src/main/resources/static/style.css | 68 ++++++++++++ src/main/resources/templates/.DS_Store | Bin 0 -> 8196 bytes .../templates/error/access-denied.html | 13 +++ src/main/resources/templates/index.html | 17 +++ .../resources/templates/index/welcome.html | 10 ++ src/main/resources/templates/issues/.DS_Store | Bin 0 -> 6148 bytes .../templates/issues/issuereport_form.html | 34 ++++++ .../templates/issues/issuereport_list.html | 30 +++++ src/main/resources/templates/login.html | 60 ++++++++++ src/main/resources/templates/user/index.html | 14 +++ 23 files changed, 595 insertions(+), 110 deletions(-) create mode 100644 src/main/.DS_Store create mode 100644 src/main/java/com/vocabularytrainer/.DS_Store create mode 100644 src/main/java/com/vocabularytrainer/project/.DS_Store delete mode 100644 src/main/java/com/vocabularytrainer/project/User.java delete mode 100644 src/main/java/com/vocabularytrainer/project/UserRepository.java create mode 100644 src/main/java/com/vocabularytrainer/project/config/SecurityConfig.java delete mode 100644 src/main/java/com/vocabularytrainer/project/controllers/Controller.java create mode 100644 src/main/java/com/vocabularytrainer/project/controllers/IssueController.java create mode 100644 src/main/java/com/vocabularytrainer/project/db/IssueRepository.java create mode 100644 src/main/java/com/vocabularytrainer/project/entity/IssueReport.java create mode 100644 src/main/java/com/vocabularytrainer/project/web/LoggingAccessDeniedHandler.java create mode 100644 src/main/resources/.DS_Store create mode 100644 src/main/resources/static/style.css create mode 100644 src/main/resources/templates/.DS_Store create mode 100644 src/main/resources/templates/error/access-denied.html create mode 100644 src/main/resources/templates/index.html create mode 100644 src/main/resources/templates/index/welcome.html create mode 100644 src/main/resources/templates/issues/.DS_Store create mode 100644 src/main/resources/templates/issues/issuereport_form.html create mode 100644 src/main/resources/templates/issues/issuereport_list.html create mode 100644 src/main/resources/templates/login.html create mode 100644 src/main/resources/templates/user/index.html diff --git a/pom.xml b/pom.xml index 8b1da8a..969bbb4 100644 --- a/pom.xml +++ b/pom.xml @@ -48,6 +48,30 @@ runtime + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + + org.springframework.boot + spring-boot-devtools + + + + + org.springframework.boot + spring-boot-starter-security + + + + + org.thymeleaf.extras + thymeleaf-extras-springsecurity4 + + diff --git a/src/main/.DS_Store b/src/main/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..65836f31b5967a0087ecf853ea9e1a262ee50ebb GIT binary patch literal 8196 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 N|MC7G^6zGC{sGu;QKA3< literal 0 HcmV?d00001 diff --git a/src/main/java/com/vocabularytrainer/project/.DS_Store b/src/main/java/com/vocabularytrainer/project/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..95c38915cb7b3829b1693d256002bdaa4a2a801f GIT binary patch literal 6148 zcmeHK&2H2%5Vp5VNr;4kgak+&EcL);4_ivvYqYeSkf=yS5BzMCCSoH+c9mqiLaUV` z9)JgcD?iUscnKba2jCmqrLC5|t}5hNjlaowW-Ncs+A(8{4=33sVl$;*Ql6cC4M=p7NVWwDl$N87qBC&n`8}E?R@>}bXp&$rAiU;J3TIoy6N|S z@y=TJ+WK|RzY+Ms&A@*XkJU78l4ep5lWG*+kBcl%lj@+zn(=-vcgy@Fm(QzbNt0Kv zD0p9~5&_0e(w9X(9fh}_DA^>1%qv~b)OdYR$V^R#Y9g~*$J^rC-b

>UbMb8EIyH z&mV<%X0xsB?VcDsocF|RFzENhqpipDx$k-R9z1>VcJkrlr_W!$e*1p { - - - -} diff --git a/src/main/java/com/vocabularytrainer/project/config/SecurityConfig.java b/src/main/java/com/vocabularytrainer/project/config/SecurityConfig.java new file mode 100644 index 0000000..13bf756 --- /dev/null +++ b/src/main/java/com/vocabularytrainer/project/config/SecurityConfig.java @@ -0,0 +1,71 @@ +package com.vocabularytrainer.project.config; + +import com.vocabularytrainer.project.web.LoggingAccessDeniedHandler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private LoggingAccessDeniedHandler accessDeniedHandler; + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .antMatchers( + "/", + "/js/**", + "/css/**", + "/img/**", + "/webjars/**").permitAll() + .antMatchers("/user/**").hasRole("USER") + .anyRequest().authenticated() + .and() + .formLogin() + .loginPage("/login") + .permitAll() + .and() + .logout() + .invalidateHttpSession(true) + .clearAuthentication(true) + .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) + .logoutSuccessUrl("/login?logout") + .permitAll() + .and() + .exceptionHandling() + .accessDeniedHandler(accessDeniedHandler); + } + + // fix according: https://mkyong.com/spring-boot/spring-security-there-is-no-passwordencoder-mapped-for-the-id-null/ + @Bean + public UserDetailsService userDetailsService() { + PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); + + UserDetails user = User.withUsername("user") + .password(encoder.encode("password")) + .roles("USER").build(); + + UserDetails man = User.withUsername("manager") + .password(encoder.encode("password")) + .roles("MANAGER").build(); + + InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); + manager.createUser(user); + manager.createUser(man); + return manager; + } + +} diff --git a/src/main/java/com/vocabularytrainer/project/controllers/Controller.java b/src/main/java/com/vocabularytrainer/project/controllers/Controller.java deleted file mode 100644 index afec434..0000000 --- a/src/main/java/com/vocabularytrainer/project/controllers/Controller.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.vocabularytrainer.project.controllers; - -import com.vocabularytrainer.project.UserRepository; // import the clas UserRepository -import com.vocabularytrainer.project.User; // import the User statement - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; // Restcontroller, Requestmapping, RequestParameter, GetMapping ... - -import org.springframework.beans.factory.annotation.Autowired; - -/** - * ExampleController - * - * @author ASD-Morning-4 - * - */ - -@EnableAutoConfiguration -@RestController // this class means it is ready for use by Spring MVC to handle web requests - -public class Controller { - - /* Hello World Example */ - @RequestMapping("/") - public ResponseEntity get() { - return ResponseEntity.ok("Greetings from Spring Boot!"); - } - - /* The Database Example */ - @Autowired // This means to get the bean called userRepository - // Which is auto-generated by Spring, we will use it to handle the data - private UserRepository userRepository; - - @RequestMapping(value = "/add") // , method = RequestMethod.GET) // <-> //@PostMapping(path="/add", method=RequestMethod.POST) // Map ONLY POST Requests - public String addNewUser (@RequestParam String name - , @RequestParam String email) { - // @ResponseBody means the returned String is the response, not a view name - // @RequestParam means it is a parameter from the GET or POST request - - User n = new User(); - n.setName(name); - n.setEmail(email); - userRepository.save(n); - return "Saved"; - } - - // add entry with: http://localhost:8080/add?name=Alice&email=alice@mail.com - - @RequestMapping(path="/all") - public Iterable getAllUsers() { - // This returns a JSON or XML with the users - return userRepository.findAll(); - } - - // show entries (as json): http://localhost:8080/all -} diff --git a/src/main/java/com/vocabularytrainer/project/controllers/IssueController.java b/src/main/java/com/vocabularytrainer/project/controllers/IssueController.java new file mode 100644 index 0000000..f4f4ae9 --- /dev/null +++ b/src/main/java/com/vocabularytrainer/project/controllers/IssueController.java @@ -0,0 +1,95 @@ +package com.vocabularytrainer.project.controllers; + +import com.vocabularytrainer.project.db.IssueRepository; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; // Restcontroller, Requestmapping, RequestParameter, GetMapping ... + +// entity IssueReport Data +import com.vocabularytrainer.project.entity.IssueReport; + +import org.springframework.stereotype.Controller; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; + +/** + * ExampleController + * + * @author ASD-Morning-4 + * + */ + +@Controller +public class IssueController { + + /* setup DataBase Repository Interface */ + + IssueRepository issueRepository; + public IssueController(IssueRepository issueRepository) { + this.issueRepository = issueRepository; + } + + /* Hello World Example: Writing Plain Text */ + + /* + @RequestMapping("/") + @ResponseBody + String get() { + return "Hello World!"; + } + */ + + /* Example Loading Thymeleaf */ + + // Load Our welcome page + @GetMapping("/index") + public String getIndex(Model model) { + return "index/welcome"; + } + + // Example with a form + @GetMapping("/issuereport") // + public String getReport(Model model) { + + model.addAttribute("issuereport", new IssueReport()); + return "issues/issuereport_form"; + } + + @PostMapping("/issuereport") // + public String submitReport(IssueReport issueReport, Model model) { // here we also want to handle the data from the form + + IssueReport result = this.issueRepository.save(issueReport); + model.addAttribute("submitted", true); // Feedback for user upon retrieving the form data + // The template will show some kind of confirming msg + // will only show after form was submitted + model.addAttribute("issuereport", result); // create another variable for our html frontent path + + // for preventing sending formular again and again: + return "redirect:/issuereport"; // return "issues/issuereport_form"; + } + + @GetMapping("/issues") + public String getIssues(Model model) { + model.addAttribute("issues", this.issueRepository.findAllButPrivate()); + return "issues/issuereport_list"; + } + + /* Example Login Page Handler */ + @GetMapping("/") + public String root() { + return "index"; + } + + @GetMapping("/user") + public String userIndex() { + return "user/index"; + } + + @GetMapping("/login") + public String login() { + return "login"; + } + + @GetMapping("/access-denied") + public String accessDenied() { + return "/error/access-denied"; + } +} diff --git a/src/main/java/com/vocabularytrainer/project/db/IssueRepository.java b/src/main/java/com/vocabularytrainer/project/db/IssueRepository.java new file mode 100644 index 0000000..2f8e487 --- /dev/null +++ b/src/main/java/com/vocabularytrainer/project/db/IssueRepository.java @@ -0,0 +1,17 @@ +package com.vocabularytrainer.project.db; + +import java.util.List; + +import com.vocabularytrainer.project.entity.IssueReport; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +public interface IssueRepository extends JpaRepository { + + // Method to show everything but private + @Query(value = "SELECT i FROM IssueReport i WHERE markedAsPrivate = false") + List findAllButPrivate(); + + // this also works as a method + List findAllByEmail(String email); +} diff --git a/src/main/java/com/vocabularytrainer/project/entity/IssueReport.java b/src/main/java/com/vocabularytrainer/project/entity/IssueReport.java new file mode 100644 index 0000000..a9db175 --- /dev/null +++ b/src/main/java/com/vocabularytrainer/project/entity/IssueReport.java @@ -0,0 +1,105 @@ +package com.vocabularytrainer.project.entity; + +import javax.persistence.*; +import java.util.Date; + +@Entity // tell hibernate that this is a database table +@Table(name = "issues") // if this is not present, the class name = table name +public class IssueReport { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + // Members of the table + + // The values of the fields email, url, description, markedAsPrivate and updates will be coming + // from the form the user submitted. The others will be generated on creation or when + // the report is updated. + private int id; + private String email; + private String url; + private String description; + private boolean markedAsPrivate; + private boolean updates; + private boolean done; + private Date created; + private Date updated; + + // Constructor + public IssueReport() { + + } + + // Getters + public int getId() { + return id; + } + + public String getEmail() { + return email; + } + + public String getUrl() { + return url; + } + + public String getDescription() { + return description; + } + + public boolean isMarkedAsPrivate() { + return markedAsPrivate; + } + + public boolean isUpdates() { + return updates; + } + + public boolean isDone() { + return done; + } + + public Date getCreated() { + return created; + } + + public Date getUpdated() { + return updated; + } + + // Setters + public void setId(int id) { + this.id = id; + } + + public void setEmail(String email) { + this.email = email; + } + + public void setUrl(String url) { + this.url = url; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setMarkedAsPrivate(boolean markedAsPrivate) { + this.markedAsPrivate = markedAsPrivate; + } + + public void setUpdates(boolean updates) { + this.updates = updates; + } + + public void setDone(boolean done) { + this.done = done; + } + + public void setCreated(Date created) { + this.created = created; + } + + public void setUpdated(Date updated) { + this.updated = updated; + } +} \ No newline at end of file diff --git a/src/main/java/com/vocabularytrainer/project/web/LoggingAccessDeniedHandler.java b/src/main/java/com/vocabularytrainer/project/web/LoggingAccessDeniedHandler.java new file mode 100644 index 0000000..7d96048 --- /dev/null +++ b/src/main/java/com/vocabularytrainer/project/web/LoggingAccessDeniedHandler.java @@ -0,0 +1,37 @@ +package com.vocabularytrainer.project.web; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.stereotype.Component; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@Component +public class LoggingAccessDeniedHandler implements AccessDeniedHandler { + + private static Logger log = LoggerFactory.getLogger(LoggingAccessDeniedHandler.class); + + @Override + public void handle(HttpServletRequest request, + HttpServletResponse response, + AccessDeniedException ex) throws IOException, ServletException { + + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + + if (auth != null) { + log.info(auth.getName() + + " was trying to access protected resource: " + + request.getRequestURI()); + } + + response.sendRedirect(request.getContextPath() + "/access-denied"); + + } +} \ No newline at end of file diff --git a/src/main/resources/.DS_Store b/src/main/resources/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..82d490e3958326f1c865152ae92135b50c4cd15e GIT binary patch literal 8196 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/templates/error/access-denied.html b/src/main/resources/templates/error/access-denied.html new file mode 100644 index 0000000..ef5ead9 --- /dev/null +++ b/src/main/resources/templates/error/access-denied.html @@ -0,0 +1,13 @@ + + + + + Access Denied + + +

+

Access denied

+

Back to home page

+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html new file mode 100644 index 0000000..877b1e9 --- /dev/null +++ b/src/main/resources/templates/index.html @@ -0,0 +1,17 @@ + + + + + Index + + +
+ +

Hello Spring Security

+

This is an unsecured page, but you can access the secured pages after authenticating.

+ +
+ + \ No newline at end of file diff --git a/src/main/resources/templates/index/welcome.html b/src/main/resources/templates/index/welcome.html new file mode 100644 index 0000000..06f9944 --- /dev/null +++ b/src/main/resources/templates/index/welcome.html @@ -0,0 +1,10 @@ + + + + + Title + + +

Welcome!

+ + \ No newline at end of file diff --git a/src/main/resources/templates/issues/.DS_Store b/src/main/resources/templates/issues/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 + + + Vogella Issuereport + + + + +
+
+

Vogella Issuereport

+ + + + + + + + +
+ +
+

Your report has been submitted.

+

Find all issues here

+
+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/issues/issuereport_list.html b/src/main/resources/templates/issues/issuereport_list.html new file mode 100644 index 0000000..1b993c3 --- /dev/null +++ b/src/main/resources/templates/issues/issuereport_list.html @@ -0,0 +1,30 @@ + + + + Vogella Issuereport + + + + +
+

Issues

+
+ + + + + + + + + + + + + + + +
UrlDescriptionDoneCreated
......
+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html new file mode 100644 index 0000000..d4e72e3 --- /dev/null +++ b/src/main/resources/templates/login.html @@ -0,0 +1,60 @@ + + + + + Login + + +
+ +
+
+

Login page

+
+
+
+ Invalid username or password. +
+
+
+
+ You have been logged out. +
+
+
+ : + +
+
+ : + +
+
+
+
+ +
+
+
+
+
+
+ +

Back to home page

+ +
+ + \ No newline at end of file diff --git a/src/main/resources/templates/user/index.html b/src/main/resources/templates/user/index.html new file mode 100644 index 0000000..bc128e7 --- /dev/null +++ b/src/main/resources/templates/user/index.html @@ -0,0 +1,14 @@ + + + + + User Logged in + + +
+

This is a secured page!

+

Back to home page

+

Logout

+
+ + \ No newline at end of file From f8144e2402a3ab0006a8b9d747c70ac151684ac3 Mon Sep 17 00:00:00 2001 From: eder13 Date: Tue, 24 Mar 2020 12:02:52 +0100 Subject: [PATCH 42/74] Added new Queries --- src/main/.DS_Store | Bin 8196 -> 8196 bytes src/main/java/.DS_Store | Bin 0 -> 6148 bytes src/main/java/com/.DS_Store | Bin 0 -> 6148 bytes src/main/java/com/vocabularytrainer/.DS_Store | Bin 8196 -> 8196 bytes .../com/vocabularytrainer/project/.DS_Store | Bin 6148 -> 6148 bytes .../project/config/SecurityConfig.java | 5 ++++ .../project/controllers/IssueController.java | 25 +++++++++++++++++- .../project/db/IssueRepository.java | 8 ++++-- .../project/entity/IssueReport.java | 14 +++++++++- src/main/resources/.DS_Store | Bin 8196 -> 8196 bytes src/main/resources/templates/.DS_Store | Bin 8196 -> 8196 bytes 11 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 src/main/java/.DS_Store create mode 100644 src/main/java/com/.DS_Store diff --git a/src/main/.DS_Store b/src/main/.DS_Store index 65836f31b5967a0087ecf853ea9e1a262ee50ebb..11170ff7ef1334cc5cfe95c608a5f4042bd86a47 100644 GIT binary patch delta 94 zcmZp1XmOa}FT}>cz`)4BAi$7PoSc)CpP$3Hv2Ysu#0G)Q>>Ml{VjyW2hAf6ehBAgk ixRT900=kTxaPH(g!jhY91gEoYW|#QJviYP4J2L=f>lvN^ delta 65 zcmZp1XmOa}FUrEez`)4BAi%&-%233R%#g}ZoK(IsaWVU5b`BN}MwZQr0=kTwa|LIy VO)N0k%r5bbWwW8^HKvILh5+km5d#1K diff --git a/src/main/java/.DS_Store b/src/main/java/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..35a54bf0595027f28217af82c3d32981e121b5e7 GIT binary patch literal 6148 zcmeH~Jr2S!425mVP>H1@V-^m;4I%_5-~tF3K^+i#j?VMXLSaS~dY0@jc51bKLsN^0 z?w;4J$RHv;+$b9h6I0}!Tx68{^>MkK$MI$*w?)zl@IfZ~xlK?3DnJFO02QDDGg2TA z@_sd=XX2w!0V*&L1?>A!;KrJ4LH~3h_y_tMAK>5S|49o|DnJGPOaWc) zkNX{7D$mxB*R%R5tF~@%&@V@L`w2i|NAVi&hW%m-uqIm&6&Qa6Tm}Xz@KXg|*oF~o literal 0 HcmV?d00001 diff --git a/src/main/java/com/.DS_Store b/src/main/java/com/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..9845f5c753a386a39194689b379de9c62eddd2fa GIT binary patch literal 6148 zcmeHKIZgvX5Ud6VmPkxSIA7ogE6coq58#6UX~jwgTO!+tckwi;j{s{SvPi6Isi$Uo zx@I&LY;Oaw~aH_y{E*D<^ALxJd|EDCaq<|E-Ct-GS6-LgK;^ds9{QMlo&2ob0*fz6Ed}G=CNQ9jk05UlZ A!~g&Q delta 40 wcmZp1XmOa}&&aYdU^hP_%Vr({6~@ipf_vB|Hb`$~m-xoASwi$Z)5Hb|00Srt^Z)<= diff --git a/src/main/java/com/vocabularytrainer/project/.DS_Store b/src/main/java/com/vocabularytrainer/project/.DS_Store index 95c38915cb7b3829b1693d256002bdaa4a2a801f..3b35adcb4a96288f6a2480da9a52877c0670cb55 100644 GIT binary patch delta 96 zcmZoMXfc@JFUroqz`)4BAi%(o$&j8>oSc)CpP#dNBJ*-aL68(1Lo!1?LmopKNP4mZ qv+`y&CLcy#CWaJ-B$(>SdCaox%naoWsSHV*>zTb-HnVg58X35Pb QnC)36HrQ@v=lIJH0HcNvjsO4v diff --git a/src/main/java/com/vocabularytrainer/project/config/SecurityConfig.java b/src/main/java/com/vocabularytrainer/project/config/SecurityConfig.java index 13bf756..8685f5f 100644 --- a/src/main/java/com/vocabularytrainer/project/config/SecurityConfig.java +++ b/src/main/java/com/vocabularytrainer/project/config/SecurityConfig.java @@ -31,7 +31,11 @@ protected void configure(HttpSecurity http) throws Exception { "/css/**", "/img/**", "/webjars/**").permitAll() + + // here I can write the matchers, if a user has this role then go to this ... .antMatchers("/user/**").hasRole("USER") + + .anyRequest().authenticated() .and() .formLogin() @@ -46,6 +50,7 @@ protected void configure(HttpSecurity http) throws Exception { .permitAll() .and() .exceptionHandling() + .accessDeniedHandler(accessDeniedHandler); } diff --git a/src/main/java/com/vocabularytrainer/project/controllers/IssueController.java b/src/main/java/com/vocabularytrainer/project/controllers/IssueController.java index f4f4ae9..df0709a 100644 --- a/src/main/java/com/vocabularytrainer/project/controllers/IssueController.java +++ b/src/main/java/com/vocabularytrainer/project/controllers/IssueController.java @@ -1,6 +1,9 @@ package com.vocabularytrainer.project.controllers; import com.vocabularytrainer.project.db.IssueRepository; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.User; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; // Restcontroller, Requestmapping, RequestParameter, GetMapping ... @@ -10,6 +13,11 @@ import org.springframework.stereotype.Controller; import org.springframework.web.servlet.mvc.support.RedirectAttributes; + + +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; + /** * ExampleController * @@ -68,10 +76,25 @@ public String submitReport(IssueReport issueReport, Model model) { // here we al @GetMapping("/issues") public String getIssues(Model model) { - model.addAttribute("issues", this.issueRepository.findAllButPrivate()); + + //model.addAttribute("issues", this.issueRepository.findAllButPrivate()); + + + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + //System.out.println("User name: " + userDetails.getUsername()); + + // pass as an argument, show table entries only with this email + model.addAttribute("issues", this.issueRepository.findAllByEmail( ( userDetails.getUsername() ) )); + return "issues/issuereport_list"; } + // test@mail.com + // pass the user name as for the + + /* Example Login Page Handler */ @GetMapping("/") public String root() { diff --git a/src/main/java/com/vocabularytrainer/project/db/IssueRepository.java b/src/main/java/com/vocabularytrainer/project/db/IssueRepository.java index 2f8e487..1ef26bb 100644 --- a/src/main/java/com/vocabularytrainer/project/db/IssueRepository.java +++ b/src/main/java/com/vocabularytrainer/project/db/IssueRepository.java @@ -5,6 +5,7 @@ import com.vocabularytrainer.project.entity.IssueReport; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; public interface IssueRepository extends JpaRepository { @@ -12,6 +13,9 @@ public interface IssueRepository extends JpaRepository { @Query(value = "SELECT i FROM IssueReport i WHERE markedAsPrivate = false") List findAllButPrivate(); - // this also works as a method - List findAllByEmail(String email); + // Method to showw everything with email = input string + @Query("SELECT u FROM IssueReport u WHERE u.email = :name") + List findAllByEmail( + @Param("name") String name + ); } diff --git a/src/main/java/com/vocabularytrainer/project/entity/IssueReport.java b/src/main/java/com/vocabularytrainer/project/entity/IssueReport.java index a9db175..43c3e07 100644 --- a/src/main/java/com/vocabularytrainer/project/entity/IssueReport.java +++ b/src/main/java/com/vocabularytrainer/project/entity/IssueReport.java @@ -1,5 +1,9 @@ package com.vocabularytrainer.project.entity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; + import javax.persistence.*; import java.util.Date; @@ -72,7 +76,15 @@ public void setId(int id) { } public void setEmail(String email) { - this.email = email; + + //this.email = email; // uses that from thymeleaf variable + + //set the current user to it -> make "automatically" + + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + this.email = userDetails.getUsername(); } public void setUrl(String url) { diff --git a/src/main/resources/.DS_Store b/src/main/resources/.DS_Store index 82d490e3958326f1c865152ae92135b50c4cd15e..fb3d2c3655d4c04dfe034c945607896d8a02e6f1 100644 GIT binary patch delta 113 zcmZp1XmOa}FUrQiz`)4BAi%(o$&j22Hwr=94s7CAQfy3#SA43 zi9n2`ig7ZJz)}uVLrWb6Lj$wPI|V{GVFoZx?iQBZEFid_Z8N*XHZbO2=lb7FU~ah3;>fDN+;2m}ZL1d|XE q7Lz*=j|ej}H7p=AG%=IX5LB~85yA$MfH<=U81@9SH5JkVk$^Q#nHIPJ diff --git a/src/main/resources/templates/.DS_Store b/src/main/resources/templates/.DS_Store index 918003053333e3bfd642a4eec1f057244f21b9d2..070d01718d56f66859bc92a1b7c78df878256b76 100644 GIT binary patch delta 70 zcmZp1XmOa}&&ahgU^hP_*Jd7pX>39)45bXk45_%*HMk Gzz6`!3KU=f delta 32 mcmZp1XmOa}&&atkU^hP_=Vl&(X>1!yQW-b1OUwo`k{AK38VWc7 From 76102aca27dcf2c133b363118f0fa5643a7eef34 Mon Sep 17 00:00:00 2001 From: Andreas Hiess Date: Tue, 24 Mar 2020 19:12:52 +0100 Subject: [PATCH 43/74] setup-project --- HELP.md | 21 -- README.md | 17 +- mvnw | 310 ------------------ mvnw.cmd | 182 ---------- pom.xml | 49 --- .../ASD/Morning4/Morning4Application.java | 13 - .../controller/ExampleController.java | 18 - src/main/resources/application.properties | 1 - .../Morning4/Morning4ApplicationTests.java | 13 - 9 files changed, 15 insertions(+), 609 deletions(-) delete mode 100644 HELP.md delete mode 100644 mvnw delete mode 100644 mvnw.cmd delete mode 100644 pom.xml delete mode 100644 src/main/java/ASD/Morning4/Morning4Application.java delete mode 100644 src/main/java/ASD/Morning4/controller/ExampleController.java delete mode 100644 src/main/resources/application.properties delete mode 100644 src/test/java/ASD/Morning4/Morning4ApplicationTests.java diff --git a/HELP.md b/HELP.md deleted file mode 100644 index c106dcd..0000000 --- a/HELP.md +++ /dev/null @@ -1,21 +0,0 @@ -# Read Me First -The following was discovered as part of building this project: - -* The original package name 'ASD.Morning-4' is invalid and this project uses 'ASD.Morning4' instead. - -# Getting Started - -### Reference Documentation -For further reference, please consider the following sections: - -* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html) -* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/maven-plugin/) -* [Spring Web](https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#boot-features-developing-web-applications) - -### Guides -The following guides illustrate how to use some features concretely: - -* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/) -* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/) -* [Building REST services with Spring](https://spring.io/guides/tutorials/bookmarks/) - diff --git a/README.md b/README.md index ce6fd5c..4819c1e 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,22 @@ Vocabulary trainer is a dictionary and training application which allows its users to study and test vocabulary in a foreign language. -### Building +### Setup --Coming soon- +### Requirements + +* Java installed +* JDK 8 or higher +* JetBrains IntelliJ Ultimate IDE + +### Building and Running + +* Clone/Download this repository +* Start IntelliJ and click 'Open' +* Navigate in your cloned repo folder, choose the `pom.xml` file and click 'ok' +* After prompted 'pom.xml is a project file' click 'Open as Project' +* To start the application hit the green 'play button', the spring boot application will start (see Run) +* Navigate in your Browser to the home url: `http://localhost:8080/api/example/hello-world` (this will be changed...) ### Meeting Notes diff --git a/mvnw b/mvnw deleted file mode 100644 index a16b543..0000000 --- a/mvnw +++ /dev/null @@ -1,310 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` - fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi -else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` - fi - - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" - else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl -o "$wrapperJarPath" "$jarUrl" -f - else - curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f - fi - - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaClass=`cygpath --path --windows "$javaClass"` - fi - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR -fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` -fi - -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd deleted file mode 100644 index c8d4337..0000000 --- a/mvnw.cmd +++ /dev/null @@ -1,182 +0,0 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM https://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - -FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - if "%MVNW_VERBOSE%" == "true" ( - echo Found %WRAPPER_JAR% - ) -) else ( - if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - ) - if "%MVNW_VERBOSE%" == "true" ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - ) - - powershell -Command "&{"^ - "$webclient = new-object System.Net.WebClient;"^ - "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ - "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ - "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ - "}" - if "%MVNW_VERBOSE%" == "true" ( - echo Finished downloading %WRAPPER_JAR% - ) -) -@REM End of extension - -@REM Provide a "standardized" way to retrieve the CLI args that will -@REM work with both Windows and non-Windows executions. -set MAVEN_CMD_LINE_ARGS=%* - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml deleted file mode 100644 index b2063c5..0000000 --- a/pom.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.2.5.RELEASE - - - ASD - Morning-4 - 0.0.1-SNAPSHOT - Morning-4 - Demo project for Spring Boot - - - 11 - - - - - org.springframework.boot - spring-boot-starter-web - - - - org.springframework.boot - spring-boot-starter-test - test - - - org.junit.vintage - junit-vintage-engine - - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - diff --git a/src/main/java/ASD/Morning4/Morning4Application.java b/src/main/java/ASD/Morning4/Morning4Application.java deleted file mode 100644 index a8ad723..0000000 --- a/src/main/java/ASD/Morning4/Morning4Application.java +++ /dev/null @@ -1,13 +0,0 @@ -package ASD.Morning4; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class Morning4Application { - - public static void main(String[] args) { - SpringApplication.run(Morning4Application.class, args); - } - -} diff --git a/src/main/java/ASD/Morning4/controller/ExampleController.java b/src/main/java/ASD/Morning4/controller/ExampleController.java deleted file mode 100644 index bb5e28f..0000000 --- a/src/main/java/ASD/Morning4/controller/ExampleController.java +++ /dev/null @@ -1,18 +0,0 @@ -package ASD.Morning4.controller; - -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - - -@RestController -@RequestMapping("") -public class ExampleController { - - @GetMapping("") - public ResponseEntity get() { - return ResponseEntity.ok("Hello World!"); - } - -} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index 8b13789..0000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/test/java/ASD/Morning4/Morning4ApplicationTests.java b/src/test/java/ASD/Morning4/Morning4ApplicationTests.java deleted file mode 100644 index b96b41f..0000000 --- a/src/test/java/ASD/Morning4/Morning4ApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package ASD.Morning4; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class Morning4ApplicationTests { - - @Test - void contextLoads() { - } - -} From c825175327ffda19bd98bc115c7c93f5070a1454 Mon Sep 17 00:00:00 2001 From: eder13 Date: Tue, 24 Mar 2020 21:06:03 +0100 Subject: [PATCH 44/74] First Prototype --- pom.xml | 84 +++++----- src/main/.DS_Store | Bin 8196 -> 10244 bytes src/main/java/com/vocabularytrainer/.DS_Store | Bin 8196 -> 6148 bytes .../com/vocabularytrainer/project/.DS_Store | Bin 6148 -> 6148 bytes .../project/MainApplication.java | 40 ----- .../project/VocabularyTrainerApplication.java | 13 ++ .../project/controller/MVCController.java | 100 ++++++++++++ .../project/controllers/IssueController.java | 118 --------------- .../project/db/IssueRepository.java | 21 --- .../project/db/VocabularyAddEntries.java | 80 ++++++++++ .../project/db/VocabularyRepository.java | 27 ++++ .../project/entity/IssueReport.java | 117 -------------- .../SpringSecurityLogin.java} | 17 +-- .../web/LoggingAccessDeniedHandler.java | 37 ----- src/main/resources/.DS_Store | Bin 8196 -> 8196 bytes src/main/resources/application.properties | 4 +- src/main/resources/static/style.css | 68 --------- src/main/resources/templates/.DS_Store | Bin 8196 -> 8196 bytes .../templates/access-denied-page.html | 27 ++++ .../templates/error/access-denied.html | 13 -- src/main/resources/templates/index.html | 30 +++- .../resources/templates/index/welcome.html | 10 -- src/main/resources/templates/issues/.DS_Store | Bin 6148 -> 0 bytes .../templates/issues/issuereport_form.html | 34 ----- .../templates/issues/issuereport_list.html | 30 ---- src/main/resources/templates/login.html | 143 ++++++++++++------ .../resources/templates/user/addvoc_form.html | 51 +++++++ src/main/resources/templates/user/index.html | 46 +++++- .../project/MainApplicationTests.java | 38 ----- .../VocabularyTrainerApplicationTests.java | 13 ++ 30 files changed, 520 insertions(+), 641 deletions(-) delete mode 100644 src/main/java/com/vocabularytrainer/project/MainApplication.java create mode 100644 src/main/java/com/vocabularytrainer/project/VocabularyTrainerApplication.java create mode 100644 src/main/java/com/vocabularytrainer/project/controller/MVCController.java delete mode 100644 src/main/java/com/vocabularytrainer/project/controllers/IssueController.java delete mode 100644 src/main/java/com/vocabularytrainer/project/db/IssueRepository.java create mode 100644 src/main/java/com/vocabularytrainer/project/db/VocabularyAddEntries.java create mode 100644 src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java delete mode 100644 src/main/java/com/vocabularytrainer/project/entity/IssueReport.java rename src/main/java/com/vocabularytrainer/project/{config/SecurityConfig.java => security/SpringSecurityLogin.java} (81%) delete mode 100644 src/main/java/com/vocabularytrainer/project/web/LoggingAccessDeniedHandler.java delete mode 100644 src/main/resources/static/style.css create mode 100644 src/main/resources/templates/access-denied-page.html delete mode 100644 src/main/resources/templates/error/access-denied.html delete mode 100644 src/main/resources/templates/index/welcome.html delete mode 100644 src/main/resources/templates/issues/.DS_Store delete mode 100644 src/main/resources/templates/issues/issuereport_form.html delete mode 100644 src/main/resources/templates/issues/issuereport_list.html create mode 100644 src/main/resources/templates/user/addvoc_form.html delete mode 100644 src/test/java/com/vocabularytrainer/project/MainApplicationTests.java create mode 100644 src/test/java/com/vocabularytrainer/project/VocabularyTrainerApplicationTests.java diff --git a/pom.xml b/pom.xml index 969bbb4..ca7bcf9 100644 --- a/pom.xml +++ b/pom.xml @@ -8,45 +8,45 @@ 2.2.5.RELEASE - br.com.asd4m - java-spring-idea + com.vocabularytrainer + project 0.0.1-SNAPSHOT - java-spring-idea - Project Files for Vocabulary Trainer + vocabulary-trainer + A Vocabulary Trainer Web Application. 1.8 - - - - org.springframework.boot - spring-boot-starter-data-jpa - - - - org.springframework.boot - spring-boot-starter-web - - - - org.springframework.boot - spring-boot-starter-test - test - - - org.junit.vintage - junit-vintage-engine - - - - - - mysql - mysql-connector-java - runtime - + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + + mysql + mysql-connector-java + runtime + @@ -61,18 +61,18 @@ - - org.springframework.boot - spring-boot-starter-security - + + org.springframework.boot + spring-boot-starter-security + - - org.thymeleaf.extras - thymeleaf-extras-springsecurity4 - + + org.thymeleaf.extras + thymeleaf-extras-springsecurity4 + - + diff --git a/src/main/.DS_Store b/src/main/.DS_Store index 11170ff7ef1334cc5cfe95c608a5f4042bd86a47..f342cf74c5bcce57738c854988b98ab36322b99e 100644 GIT binary patch delta 601 zcmZp1XbF&DU|?W$DortDU{C-uIe-{M3-C-#6q~50D9Q=sFar4uN#(@_NjdpRK>n$X ziHq4cvvaU;c!H!^7_t}=8Oj(Ek(DGBo{JeCaj>!rFN`@!N@cY%3VJAxoC$FaPDjp~tSBJ1*-vmM+r|PVCP8M1 xas_T6?Fx#BjfvlxC-ch$iZDTrJS diff --git a/src/main/java/com/vocabularytrainer/.DS_Store b/src/main/java/com/vocabularytrainer/.DS_Store index ba64e95979fb9e39fd88242a937d2ba99897edc1..4f161a655e2ecc0ecebdf6969d9128322ec7cc70 100644 GIT binary patch delta 132 zcmZp1XfcprU|?W$DortDU=RQ@Ie-{MGqg=C6q~50D9Q+A12Ir6l_8m-B&9exCnn>l5HfsqP!k>jNS2a1 zEYzoSKp2yZWGa#aLWZG~Q=A?Ug(5m)K!lS$$=yk&A~_(W2xk!C4AIDlPACXRr?_P3 z&X5u^Zes*u1V$pj&+ZdgFY}no4&8Wuce7-(cVW8TK?`|`(6KKtD1GiP7<;KMM8A$pOp3UPhCy-2-b zh!}p(&eHAkkYOgTvI3 zmX3VZx;JkHN40865@S@Ux69gjX^%m-xXm?qMkBPSRcehS?dJL>&!kqUl?CcTS<|JA zPcVrTb;?p%^X1H8qKycxR~jVEkayU6*0hCcwX#;yw#w}VF>j$vJMP%C%j+@2nq zk1y2C>PAVsB<Dpl>|`t^ok8j@69U$X2(6Y$db`gspysqH5!a@FH^c8b#4c zX+;R@x)fQ*6ZeI+c>`G)U$gRPaxGDPv* zV+8*92%xk%-P}mi9PJgEAX}2^eyY51zX2h`5Nfy!*N4Y(lGlG2Qa>5lQjr`Gk}OpI Tiw^;^6z~7>{vXnB%r<`m>AhTA diff --git a/src/main/java/com/vocabularytrainer/project/.DS_Store b/src/main/java/com/vocabularytrainer/project/.DS_Store index 3b35adcb4a96288f6a2480da9a52877c0670cb55..55861b51956d8a04bfa659f3a45a8981cdc7aaef 100644 GIT binary patch delta 108 zcmZoMXfc=|#>AjHu~1l-k%57Mi6Mm{DWy0$Cn-Na2grv3CMW}>28ab1HYTiQ-28x9 qodrnTW!%ip!OsCSX7fen@640=MHD$f3KKw@CY$gmZ;laJ!3+RVd=(!6 delta 540 zcmaJ;%SyvQ6un7b69ZZyR78b{3pZUvYwb#qimn8U5ncEw6BBJ9%#>u>Af*(m@EXqOsA_Vv-@bEf_0xJyamd7nryjyk84TNF5Npd2Y zN@s{NqAKdBsvMd%9-4xRMo^}HH9Kv(wqsF$&$UHu$6@Q9({xy8%ipBJ@%JP34i1Hi z0jAcj>x9*;w#J#DE_3|YaA0z<=Q5jzW!_+R5bM9(V_c!4hCXC&)mz0G0TiNCvlFdW zp;*l8rNwq$Z { - - System.out.println("Let's inspect the beans provided by Spring Boot:"); - - String[] beanNames = ctx.getBeanDefinitionNames(); - Arrays.sort(beanNames); - for (String beanName : beanNames) { - System.out.println(beanName); - } - }; - } - */ -} diff --git a/src/main/java/com/vocabularytrainer/project/VocabularyTrainerApplication.java b/src/main/java/com/vocabularytrainer/project/VocabularyTrainerApplication.java new file mode 100644 index 0000000..6b04eb1 --- /dev/null +++ b/src/main/java/com/vocabularytrainer/project/VocabularyTrainerApplication.java @@ -0,0 +1,13 @@ +package com.vocabularytrainer.project; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class VocabularyTrainerApplication { + + public static void main(String[] args) { + SpringApplication.run(VocabularyTrainerApplication.class, args); + } + +} diff --git a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java new file mode 100644 index 0000000..f17cca1 --- /dev/null +++ b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java @@ -0,0 +1,100 @@ +package com.vocabularytrainer.project.controller; + +import com.vocabularytrainer.project.db.VocabularyAddEntries; +import com.vocabularytrainer.project.db.VocabularyRepository; // Repository Interface + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; + +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; + + +import org.springframework.security.core.Authentication; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; + + +@Controller +public class MVCController { + + /* Setup access Database Repository Interface */ + VocabularyRepository vocabularyRepository; + public MVCController(VocabularyRepository vocabularyRepository) { + this.vocabularyRepository = vocabularyRepository; + } + + /* Welcome Page */ + @GetMapping("/") + public String root() { + return "index"; + } + + /* User Interface: Dashboard */ + @GetMapping("/user") + public String userIndex(Model model) { + + // tell the thymeleaf which user is logged in + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + model.addAttribute("current_user", userDetails.getUsername()); + + // get the Query to show current vocabulary entries of user x + model.addAttribute("overview", this.vocabularyRepository.showAllVocabularyFromUserX(userDetails.getUsername())); + + return "user/index"; + } + + /* Show the Form and Let the user enter stuff */ + @GetMapping("/user/addvoc") + // Model -> Thymeleaf model to access html "variables" + public String getUserAddVocabulary(Model model) { + + + VocabularyAddEntries vocabularyAddEntries = new VocabularyAddEntries(); + + + // Thymeleaf-variable for "get-form" + model.addAttribute("addvoc", vocabularyAddEntries); + + return "user/addvoc_form"; + } + + /* Submit Data from Form using POST */ + @PostMapping("/user/addvoc") + public String submitUserAddVocabulary(VocabularyAddEntries vocabularyAddEntries, Model model) { + + model.addAttribute("submitted", true); + + // get current user + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + vocabularyAddEntries.setUser(userDetails.getUsername()); + + // save result in our Repository Interface + VocabularyAddEntries result = this.vocabularyRepository.save(vocabularyAddEntries); + + // Thymeleaf-variable for "post-form" - add it + model.addAttribute("addvoc", result); + + return "user/addvoc_form"; + } + + /* Login Page */ + @GetMapping("/login") + public String login() { + return "login"; + } + + /* Access Denied Page */ + @GetMapping("/request-denied") + public String accessDenied() { + return "access-denied-page"; + } +} diff --git a/src/main/java/com/vocabularytrainer/project/controllers/IssueController.java b/src/main/java/com/vocabularytrainer/project/controllers/IssueController.java deleted file mode 100644 index df0709a..0000000 --- a/src/main/java/com/vocabularytrainer/project/controllers/IssueController.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.vocabularytrainer.project.controllers; - -import com.vocabularytrainer.project.db.IssueRepository; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.User; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.*; // Restcontroller, Requestmapping, RequestParameter, GetMapping ... - -// entity IssueReport Data -import com.vocabularytrainer.project.entity.IssueReport; - -import org.springframework.stereotype.Controller; -import org.springframework.web.servlet.mvc.support.RedirectAttributes; - - - -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; - -/** - * ExampleController - * - * @author ASD-Morning-4 - * - */ - -@Controller -public class IssueController { - - /* setup DataBase Repository Interface */ - - IssueRepository issueRepository; - public IssueController(IssueRepository issueRepository) { - this.issueRepository = issueRepository; - } - - /* Hello World Example: Writing Plain Text */ - - /* - @RequestMapping("/") - @ResponseBody - String get() { - return "Hello World!"; - } - */ - - /* Example Loading Thymeleaf */ - - // Load Our welcome page - @GetMapping("/index") - public String getIndex(Model model) { - return "index/welcome"; - } - - // Example with a form - @GetMapping("/issuereport") // - public String getReport(Model model) { - - model.addAttribute("issuereport", new IssueReport()); - return "issues/issuereport_form"; - } - - @PostMapping("/issuereport") // - public String submitReport(IssueReport issueReport, Model model) { // here we also want to handle the data from the form - - IssueReport result = this.issueRepository.save(issueReport); - model.addAttribute("submitted", true); // Feedback for user upon retrieving the form data - // The template will show some kind of confirming msg - // will only show after form was submitted - model.addAttribute("issuereport", result); // create another variable for our html frontent path - - // for preventing sending formular again and again: - return "redirect:/issuereport"; // return "issues/issuereport_form"; - } - - @GetMapping("/issues") - public String getIssues(Model model) { - - //model.addAttribute("issues", this.issueRepository.findAllButPrivate()); - - - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - UserDetails userDetails = (UserDetails) authentication.getPrincipal(); - - //System.out.println("User name: " + userDetails.getUsername()); - - // pass as an argument, show table entries only with this email - model.addAttribute("issues", this.issueRepository.findAllByEmail( ( userDetails.getUsername() ) )); - - return "issues/issuereport_list"; - } - - // test@mail.com - // pass the user name as for the - - - /* Example Login Page Handler */ - @GetMapping("/") - public String root() { - return "index"; - } - - @GetMapping("/user") - public String userIndex() { - return "user/index"; - } - - @GetMapping("/login") - public String login() { - return "login"; - } - - @GetMapping("/access-denied") - public String accessDenied() { - return "/error/access-denied"; - } -} diff --git a/src/main/java/com/vocabularytrainer/project/db/IssueRepository.java b/src/main/java/com/vocabularytrainer/project/db/IssueRepository.java deleted file mode 100644 index 1ef26bb..0000000 --- a/src/main/java/com/vocabularytrainer/project/db/IssueRepository.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.vocabularytrainer.project.db; - -import java.util.List; - -import com.vocabularytrainer.project.entity.IssueReport; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface IssueRepository extends JpaRepository { - - // Method to show everything but private - @Query(value = "SELECT i FROM IssueReport i WHERE markedAsPrivate = false") - List findAllButPrivate(); - - // Method to showw everything with email = input string - @Query("SELECT u FROM IssueReport u WHERE u.email = :name") - List findAllByEmail( - @Param("name") String name - ); -} diff --git a/src/main/java/com/vocabularytrainer/project/db/VocabularyAddEntries.java b/src/main/java/com/vocabularytrainer/project/db/VocabularyAddEntries.java new file mode 100644 index 0000000..323b6c8 --- /dev/null +++ b/src/main/java/com/vocabularytrainer/project/db/VocabularyAddEntries.java @@ -0,0 +1,80 @@ +package com.vocabularytrainer.project.db; + +// Entity-Model for Database Table + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; + +import javax.persistence.*; + +@Entity // tells Hibernate ("database manager for java") this is a database table +@Table(name = "tabAllUserVocabularies") +public class VocabularyAddEntries { + + /* Model of Table */ + @Id // these are some options for id to be auto-increment + @GeneratedValue(strategy = GenerationType.AUTO) + private int id; + + private String user; + private String german_word; + private String engl_trans; + private int rating; // for Issue LANG_006 + private String tag; // for Issue LANG_005 ("custom tags for filtering") + + // Standard Constructor e.g. called in getUserAddVocabulary() + public VocabularyAddEntries() { + + } + + // getters/setters auto generation + // right-click->generate + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public String getGerman_word() { + return german_word; + } + + public void setGerman_word(String german_word) { + this.german_word = german_word; + } + + public String getEngl_trans() { + return engl_trans; + } + + public void setEngl_trans(String engl_trans) { + this.engl_trans = engl_trans; + } + + public int getRating() { + return rating; + } + + public void setRating(int rating) { + this.rating = rating; + } + + public String getTag() { + return tag; + } + + public void setTag(String tag) { + this.tag = tag; + } +} diff --git a/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java b/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java new file mode 100644 index 0000000..89c9a0c --- /dev/null +++ b/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java @@ -0,0 +1,27 @@ +package com.vocabularytrainer.project.db; + +import com.vocabularytrainer.project.db.VocabularyAddEntries; // database entity +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; + +// with this, we can make the connection to the database - "connection layer" +// JPA = Java Persistence API for managing relational data (=Database) +// We use JPQL (="SQL" queries in Java) to make queries +public interface VocabularyRepository extends JpaRepository { + + /* Queries */ + + @Query(value="SELECT u FROM VocabularyAddEntries u") + List showAllVocabulary(); + + @Query(value="SELECT x FROM VocabularyAddEntries x WHERE x.user = :paruser") + // using Java Template we save everything in there ad use as Data Type the table + List showAllVocabularyFromUserX( + @Param("paruser") String paruser // Parameter Handling for JPQL-Style queries + ); + + +} diff --git a/src/main/java/com/vocabularytrainer/project/entity/IssueReport.java b/src/main/java/com/vocabularytrainer/project/entity/IssueReport.java deleted file mode 100644 index 43c3e07..0000000 --- a/src/main/java/com/vocabularytrainer/project/entity/IssueReport.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.vocabularytrainer.project.entity; - -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UserDetails; - -import javax.persistence.*; -import java.util.Date; - -@Entity // tell hibernate that this is a database table -@Table(name = "issues") // if this is not present, the class name = table name -public class IssueReport { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - // Members of the table - - // The values of the fields email, url, description, markedAsPrivate and updates will be coming - // from the form the user submitted. The others will be generated on creation or when - // the report is updated. - private int id; - private String email; - private String url; - private String description; - private boolean markedAsPrivate; - private boolean updates; - private boolean done; - private Date created; - private Date updated; - - // Constructor - public IssueReport() { - - } - - // Getters - public int getId() { - return id; - } - - public String getEmail() { - return email; - } - - public String getUrl() { - return url; - } - - public String getDescription() { - return description; - } - - public boolean isMarkedAsPrivate() { - return markedAsPrivate; - } - - public boolean isUpdates() { - return updates; - } - - public boolean isDone() { - return done; - } - - public Date getCreated() { - return created; - } - - public Date getUpdated() { - return updated; - } - - // Setters - public void setId(int id) { - this.id = id; - } - - public void setEmail(String email) { - - //this.email = email; // uses that from thymeleaf variable - - //set the current user to it -> make "automatically" - - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - UserDetails userDetails = (UserDetails) authentication.getPrincipal(); - - this.email = userDetails.getUsername(); - } - - public void setUrl(String url) { - this.url = url; - } - - public void setDescription(String description) { - this.description = description; - } - - public void setMarkedAsPrivate(boolean markedAsPrivate) { - this.markedAsPrivate = markedAsPrivate; - } - - public void setUpdates(boolean updates) { - this.updates = updates; - } - - public void setDone(boolean done) { - this.done = done; - } - - public void setCreated(Date created) { - this.created = created; - } - - public void setUpdated(Date updated) { - this.updated = updated; - } -} \ No newline at end of file diff --git a/src/main/java/com/vocabularytrainer/project/config/SecurityConfig.java b/src/main/java/com/vocabularytrainer/project/security/SpringSecurityLogin.java similarity index 81% rename from src/main/java/com/vocabularytrainer/project/config/SecurityConfig.java rename to src/main/java/com/vocabularytrainer/project/security/SpringSecurityLogin.java index 8685f5f..524bf01 100644 --- a/src/main/java/com/vocabularytrainer/project/config/SecurityConfig.java +++ b/src/main/java/com/vocabularytrainer/project/security/SpringSecurityLogin.java @@ -1,9 +1,6 @@ -package com.vocabularytrainer.project.config; +package com.vocabularytrainer.project.security; -import com.vocabularytrainer.project.web.LoggingAccessDeniedHandler; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @@ -16,10 +13,7 @@ import org.springframework.security.web.util.matcher.AntPathRequestMatcher; @EnableWebSecurity -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Autowired - private LoggingAccessDeniedHandler accessDeniedHandler; +public class SpringSecurityLogin extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { @@ -32,10 +26,8 @@ protected void configure(HttpSecurity http) throws Exception { "/img/**", "/webjars/**").permitAll() - // here I can write the matchers, if a user has this role then go to this ... + // redirect here after successful login with Role USER .antMatchers("/user/**").hasRole("USER") - - .anyRequest().authenticated() .and() .formLogin() @@ -50,8 +42,7 @@ protected void configure(HttpSecurity http) throws Exception { .permitAll() .and() .exceptionHandling() - - .accessDeniedHandler(accessDeniedHandler); + .accessDeniedPage("/request-denied"); } // fix according: https://mkyong.com/spring-boot/spring-security-there-is-no-passwordencoder-mapped-for-the-id-null/ diff --git a/src/main/java/com/vocabularytrainer/project/web/LoggingAccessDeniedHandler.java b/src/main/java/com/vocabularytrainer/project/web/LoggingAccessDeniedHandler.java deleted file mode 100644 index 7d96048..0000000 --- a/src/main/java/com/vocabularytrainer/project/web/LoggingAccessDeniedHandler.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.vocabularytrainer.project.web; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.security.access.AccessDeniedException; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.web.access.AccessDeniedHandler; -import org.springframework.stereotype.Component; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -@Component -public class LoggingAccessDeniedHandler implements AccessDeniedHandler { - - private static Logger log = LoggerFactory.getLogger(LoggingAccessDeniedHandler.class); - - @Override - public void handle(HttpServletRequest request, - HttpServletResponse response, - AccessDeniedException ex) throws IOException, ServletException { - - Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - - if (auth != null) { - log.info(auth.getName() - + " was trying to access protected resource: " - + request.getRequestURI()); - } - - response.sendRedirect(request.getContextPath() + "/access-denied"); - - } -} \ No newline at end of file diff --git a/src/main/resources/.DS_Store b/src/main/resources/.DS_Store index fb3d2c3655d4c04dfe034c945607896d8a02e6f1..69fcce4eef13c509a2bab99b3ecaac7d07d361f3 100644 GIT binary patch delta 1149 zcmcJMTWrfw9LIm(x&1H3Y1ggo%vS5xbXHB*+1j83$JW{YZJDYr zOuS&?FNn(n3ok5@EWC(#@qq9meGv&SZV?Z>c<><3T90lo&dWL9?=R=%_TlWF$)T(%~U*OPVGGCrTjWn0?Zn$3!WxxOi|x_4mYVCGQv@J0PItHC9m z8M><^d2Xn@OWMhdX;s<3eqT}@OlX^xVU6#)!L)8MOKHj`r9YZf(@JMFsb~zMaI>^x zfvv8=-Ruvv=jY952B}Oc*I$_|da1FZ+AyEZGh1YNODd)grPSmIvkO9gx~*C$OM08J zAy&BKkewon3Smt>s1#pml$MB06T^GeM7+?*9?2`PxESe=#+3eI)gt)>wpQ#(7k^nS zmq{xG16<;kzQKV3C6Uzhr^b$)NCH{OO+gCNc2Z~`jnD}?MdNguF4J|Iq$#>jkLWQy zrDyb|lF_aYpbav-u_jVJePjcR>LBCaNO_oP)#jrA*R&NLh$Uum(LC zvDq%B9JW}j!R>RFx?P^Qvoz-Qx}2r;b)I;fGi!x={kFZs6O*yS@gtYaZ=wX3O;znK z;L3`&y!NeogcvilE^R0f(WBbtKtwalDYer?ZjP06HkWBBEG>7et!rGrX?|svPsstYSf_-O=w07wx9!@*p40O$6f?6fDnce#RMi1L*6t@oW})R#5G*U z3~t~K?whkYJ%5R-{y}V!#IG`wmf1PEd6trL$C`ECmW}3#-0p-@#Ebi)x}gV$wBB(& z6xp{cU<_#CkRBfFm44bGmP8QC=B>8;0;No`Gx2~4mb&svrHYF?Od!2hDo)14qV!g) zxVh{h7N@s*?qO11EJ?3E-ppm2gvdzG8@Qjz24d-afi2&Y>B5nj+sN&lX{Nc^7?ei_shd?AWZjMWmq8Z}r0&t`bxlLeCgZD_|fbfFu) z*eNRnWQ7nk4B`MrVIU%FBrt`eIELdmjk7YzIT_{Z?Nye~xV_Z&BO~!YtrkF)_@7n_ LpekF4)hGM`9)a%m diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c0cf6ff..a0904eb 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,4 +1,4 @@ spring.jpa.hibernate.ddl-auto=update -spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_vocabularies +spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_vocabularytrainer spring.datasource.username=student -spring.datasource.password=student +spring.datasource.password=student \ No newline at end of file diff --git a/src/main/resources/static/style.css b/src/main/resources/static/style.css deleted file mode 100644 index 355aa34..0000000 --- a/src/main/resources/static/style.css +++ /dev/null @@ -1,68 +0,0 @@ -*{ - padding: 0; - margin: 0; - box-sizing: border-box; -} -body{ - font-family: sans-serif; -} -.container { - width: 100vw; - height: 100vh; - padding: 100px 0; - text-align: center; -} -.container form{ - width: 100%; - height: 100%; - margin: 0 auto; - max-width: 350px; -} -.container form input[type="text"], .container form textarea{ - width: 100%; - padding: 10px; - border-radius: 3px; - border: 1px solid #b8b8b8; - font-family: inherit; - margin-bottom: 20px; -} -.container h3{ - margin-bottom: 20px; -} -.container form input[type="submit"]{ - max-width: 250px; - margin: auto; - display: block; - width: 55%; - padding: 10px; - background: darkorange; - border: 1px solid #b8b8b8; - border-radius: 3px; - margin-top: 20px; - cursor: pointer; -} -.issue_list table{ - text-align: left; - border-collapse: collapse; - border: 1px #b8b8b8 solid; - margin: auto; -} -.issue_list .desc{ - min-width: 500px; -} -.issue_list td, .issue_list th{ - border-bottom: 1px #b8b8b8 solid; - border-top: 1px #b8b8b8 solid; - padding: 5px; -} -.issue_list tr{ - height: 35px; - transition: background .25s; - -} -.issue_list tr:hover{ - background: #eee; -} -.issue_list .status.done:after{ - content: '✓'; -} \ No newline at end of file diff --git a/src/main/resources/templates/.DS_Store b/src/main/resources/templates/.DS_Store index 070d01718d56f66859bc92a1b7c78df878256b76..389d0d1049924f1b502ac3c196c59e15ca42bee5 100644 GIT binary patch literal 8196 zcmeHMTWl0n827!PZ*LBE8XKxVYVx+9F7GTY7`GyE|h$GCNauX4^t3 zY1BmHZr`k*f)z8HVq)5t2 ztnqB_0(CcKC25M>d12MoXk9$zq{njt|FO9ft>Q(a;PgBq-_9c4l|Z@ zjVBE9Hz$lXigJh9YTnbqanE#Y_mGisNmfQ{#dKxq+{*QvD({cfHSLVdPk0r?aMaY_6o3t*X#e<*-iEJK*TNH=SLSWZzPysp=rNv}Oz{bxHEoHCt4r+oi>_ zMBupfK}G34N+e*eEJEuW6t%}nBn^w{vIuM5p{TtRV$JN)K)GwTqV~}jOVd)^5{v}u zmYAvz@sal@T<_qxVbiQG)A0W4G_^yL`nk15*A2ZgS|jlD0gxF#e#+opXoL>vf_~6p z5?+Q^;S`*Px8Xdz4oACi`!e-oo zE!d77*opfvj(s?QgLoJXJc?DvB?QuF`P^~y@l(ba3#u3KMGwPkC4 z^RAYKZ@J{_Eh1Phr+gv_ruYn+XUGDZ%hh|7P5Ic|L!2|FBu*T*g0rJs-K_{@rgb&nF2h_-C` zTzP5PhFGhjFyKEsc?tjig?;bA1-L}ay9VFGPw)%;3cn$ujKx^yGp-V=uo|~vE!JZL zZpS_NFmW%2ZFm45!-M#^&%Gl!gd=F;Q)m$bIscB~G@ihd_&mOVFXBr+4__k|zJYJz zyLfI1>pGXP?tCum(oS2Op7l}ySKs=${d#(_P0wo^AIrb-PQ){|<=CUt*F5tVPa$mG zG6IF7hf;q3-<$va|CYxII|va75x9L3z@oNzTa4zHZ>QyVZH@8>WuCa-tdM>P6^kAM ksJ-xqA=Nc<hv&afy*s-28=#UL=Kufz literal 8196 zcmeI0O>Epm6oB8`{M0|BaoVQYqz&DYHcFLklr%{br44NU+Jql9u=#IFvb%N@3$MLh zdy}+js))jkQUr)UK_#dV2j~d_2ZY3d1C`){B0=H6g}(zAt{f0=X1r1JhlEr_rFvGL zH-2y4%=r1UXP*H8yK{OIKo|fdI+)Z{sx~Ri&W;TwG*{n!g?EAtR)IkJ-2;7qqVDEX-xd871BE-;Bdj~gm@k)w6z+h+9nhZ{{R{>9?Bo~W z-2r1l26YgDAOagBz;gE@Fu?{Lj7{_R+pKA)w^z@3DS+>{twp7?1nD` z#Wb%=zZ}i%CgTzr@VcJHPJDa*eT_#6OTX*KWot&+^e4My2NRlkc zQ(Aa&vAMZ58fk86T8c&%+u9nVk(TD8OG~m;aj>a#U^;#N!s5lHORtM~qW?~UQgOao zzd@}v7pc1`D@n^_J=Pd3cdkcVeJGp1`tR~rFDvSOC(4!nDQ(9bUDTu7 zT;mCY`kQk`FL}9RCJo2BX(&tYm+amXIdG_ zn)5M7XI{GYktB1={%Tb{%`81xgKC`|_~f-}ovbCKA(xgXH1*11S##x~r|7P7joPRj zku+T%wh~Fh5~^0EP0}8bN9RP?gt9|9E|p zz=!Y|d8IEiP_KpP#*qKg;tS$r8^!B_D$d>h}v>v#h{#!tk$LU~LF{B`;QKc~ie z8vSQ6G`cB`edWr@|B1$1C5(a{J9m}u-glrb+H~|-Z1wJ~yJ>5Fw6h@w*LNq2WAR}2qF+f;BJio7WT$_yJ>Y>y<}Og z9id~I4pvydWg)o>Rjdos^K_h~pN?}~#J9zKxhy1iB_HleQe^V~`G)}dD;ezn!T!$} HyqC-08U_;N diff --git a/src/main/resources/templates/access-denied-page.html b/src/main/resources/templates/access-denied-page.html new file mode 100644 index 0000000..6e5080f --- /dev/null +++ b/src/main/resources/templates/access-denied-page.html @@ -0,0 +1,27 @@ + + + + + Access Denied + + + + + + + + + + + + + + +
+

Access denied

+

lel

+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/error/access-denied.html b/src/main/resources/templates/error/access-denied.html deleted file mode 100644 index ef5ead9..0000000 --- a/src/main/resources/templates/error/access-denied.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - Access Denied - - -
-

Access denied

-

Back to home page

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index 877b1e9..d6d11f7 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -2,16 +2,32 @@ - Index + Home + + + + + + + + + + + + -
+
+ +

Vocabulary Trainer

+ +

Vocabulary trainer is a dictionary and training application which allows its + users to study and test vocabulary in a foreign language.

+ +

Please sign in here

-

Hello Spring Security

-

This is an unsecured page, but you can access the secured pages after authenticating.

-
\ No newline at end of file diff --git a/src/main/resources/templates/index/welcome.html b/src/main/resources/templates/index/welcome.html deleted file mode 100644 index 06f9944..0000000 --- a/src/main/resources/templates/index/welcome.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - Title - - -

Welcome!

- - \ No newline at end of file diff --git a/src/main/resources/templates/issues/.DS_Store b/src/main/resources/templates/issues/.DS_Store deleted file mode 100644 index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 - - - Vogella Issuereport - - - - -
-
-

Vogella Issuereport

- - - - - - - - -
- -
-

Your report has been submitted.

-

Find all issues here

-
-
- - \ No newline at end of file diff --git a/src/main/resources/templates/issues/issuereport_list.html b/src/main/resources/templates/issues/issuereport_list.html deleted file mode 100644 index 1b993c3..0000000 --- a/src/main/resources/templates/issues/issuereport_list.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - Vogella Issuereport - - - - -
-

Issues

-
- - - - - - - - - - - - - - - -
UrlDescriptionDoneCreated
......
-
- - \ No newline at end of file diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html index d4e72e3..e6f01a3 100644 --- a/src/main/resources/templates/login.html +++ b/src/main/resources/templates/login.html @@ -3,58 +3,107 @@ Login + + + + + + + + + + + + -
- -
-
-

Login page

-
-
-
- Invalid username or password. -
-
-
-
- You have been logged out. -
-
-
- : - -
-
- : - -
-
-
-
- -
-
-
-
+ +
+ +
-

Back to home page

+ +
+
+ You have been logged out. +
+
+ + +

+ + +

+

+ + +

+ + + + +

Back to Homepage

+ + \ No newline at end of file diff --git a/src/main/resources/templates/user/addvoc_form.html b/src/main/resources/templates/user/addvoc_form.html new file mode 100644 index 0000000..aaf6583 --- /dev/null +++ b/src/main/resources/templates/user/addvoc_form.html @@ -0,0 +1,51 @@ + + + + + Add Vocabulary + + + + + + + + + + + + + + + +
+ +
+
+ Your vocabularies have been updated. +
+
+ +
+ +
Add new Vocabulary
+ +
+ +
+ +
+ +
+ + +
+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/user/index.html b/src/main/resources/templates/user/index.html index bc128e7..5891ada 100644 --- a/src/main/resources/templates/user/index.html +++ b/src/main/resources/templates/user/index.html @@ -2,13 +2,51 @@ - User Logged in + Dashboard + + + + + + + + + + + + -
-

This is a secured page!

-

Back to home page

+
+ +

Welcome


+
+

Overview of your Vocabularies

+
+
+ + + + + + + + + + + + + +
German VocabularyEnglish Translation
+
+ +

Add Vocabulary

+ Add vocabulary +

Logout

+
\ No newline at end of file diff --git a/src/test/java/com/vocabularytrainer/project/MainApplicationTests.java b/src/test/java/com/vocabularytrainer/project/MainApplicationTests.java deleted file mode 100644 index 09725a1..0000000 --- a/src/test/java/com/vocabularytrainer/project/MainApplicationTests.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.vocabularytrainer.project; - -import static org.assertj.core.api.Assertions.*; - -import java.net.URL; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.http.ResponseEntity; - -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -public class MainApplicationTests { - - @LocalServerPort - private int port; - - private URL base; - - @Autowired - private TestRestTemplate template; - - @BeforeEach - public void setUp() throws Exception { - this.base = new URL("http://localhost:" + port + "/"); - } - - @Test - public void getHello() throws Exception { - ResponseEntity response = template.getForEntity(base.toString(), - String.class); - assertThat(response.getBody().equals("Greetings from Spring Boot!")); - } -} \ No newline at end of file diff --git a/src/test/java/com/vocabularytrainer/project/VocabularyTrainerApplicationTests.java b/src/test/java/com/vocabularytrainer/project/VocabularyTrainerApplicationTests.java new file mode 100644 index 0000000..372a1cb --- /dev/null +++ b/src/test/java/com/vocabularytrainer/project/VocabularyTrainerApplicationTests.java @@ -0,0 +1,13 @@ +package com.vocabularytrainer.project; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class VocabularyTrainerApplicationTests { + + @Test + void contextLoads() { + } + +} From 14777b6f5164cd2312092a47c0208a48510932d7 Mon Sep 17 00:00:00 2001 From: Alexander Beinhundner Date: Wed, 25 Mar 2020 08:53:47 +0100 Subject: [PATCH 45/74] dd --- .gitignore | 71 ----------------------------------------- .idea/.gitignore | 2 ++ .idea/ASD-Morning-4.iml | 9 ++++++ .idea/misc.xml | 6 ++++ .idea/modules.xml | 8 +++++ .idea/vcs.xml | 6 ++++ 6 files changed, 31 insertions(+), 71 deletions(-) delete mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/ASD-Morning-4.iml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 8da0824..0000000 --- a/.gitignore +++ /dev/null @@ -1,71 +0,0 @@ -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# Generated files -.idea/**/contentModel.xml - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -# .idea/artifacts -# .idea/compiler.xml -# .idea/jarRepositories.xml -# .idea/modules.xml -# .idea/*.iml -# .idea/modules -# *.iml -# *.ipr - -# CMake -cmake-build-*/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests - -# Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..5c98b42 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,2 @@ +# Default ignored files +/workspace.xml \ No newline at end of file diff --git a/.idea/ASD-Morning-4.iml b/.idea/ASD-Morning-4.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/ASD-Morning-4.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..28a804d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..0aee837 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file From b33cb02545fb83294fc1a0d4411e7becfb16ebb5 Mon Sep 17 00:00:00 2001 From: Alexander Beinhundner Date: Wed, 25 Mar 2020 08:55:36 +0100 Subject: [PATCH 46/74] clean --- .idea/.gitignore | 2 -- .idea/ASD-Morning-4.iml | 9 --------- .idea/misc.xml | 6 ------ .idea/modules.xml | 8 -------- .idea/vcs.xml | 6 ------ 5 files changed, 31 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/ASD-Morning-4.iml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 5c98b42..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Default ignored files -/workspace.xml \ No newline at end of file diff --git a/.idea/ASD-Morning-4.iml b/.idea/ASD-Morning-4.iml deleted file mode 100644 index d6ebd48..0000000 --- a/.idea/ASD-Morning-4.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 28a804d..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 0aee837..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From 3f743ae0d3c1a68e2a7901729255d1f5a19bd1e2 Mon Sep 17 00:00:00 2001 From: Christoph Pruell Date: Wed, 25 Mar 2020 10:42:55 +0100 Subject: [PATCH 47/74] Repo Test --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index ccef6df..af87b86 100644 --- a/README.md +++ b/README.md @@ -39,3 +39,18 @@ ___18.03.2020___ * Read MySQL docs and setup everything * Install Teamviewer for collaborative programming * Split into groups and create branch for each Issue. + +___25.03.2020___ + +* Setting Up the Framework for every participant. +* Setting goals for Sprint 2 + * Issues 003 - 007 +* Organizing pair-programming Teams + * Teamviewer is used for this point +* Start implementing next issues +* Planning to introduce Unit-Tests + +* Planing resume: + * Creating branches per Issue + + From f23eaf40f8322fb912a049b439c53abc7678c7ee Mon Sep 17 00:00:00 2001 From: eder13 Date: Wed, 25 Mar 2020 11:11:16 +0100 Subject: [PATCH 48/74] Update Naming --- docs/fix_cannot_build.jpeg | Bin 0 -> 83237 bytes pom.xml | 2 ++ .../project/controller/MVCController.java | 18 +++++++----------- ...AddEntries.java => VocabularyEntries.java} | 5 ++--- .../project/db/VocabularyRepository.java | 11 +++++------ src/main/resources/.DS_Store | Bin 8196 -> 8196 bytes src/main/resources/static/style.css | 4 ++++ src/main/resources/templates/user/index.html | 7 ++++++- 8 files changed, 26 insertions(+), 21 deletions(-) create mode 100644 docs/fix_cannot_build.jpeg rename src/main/java/com/vocabularytrainer/project/db/{VocabularyAddEntries.java => VocabularyEntries.java} (96%) create mode 100644 src/main/resources/static/style.css diff --git a/docs/fix_cannot_build.jpeg b/docs/fix_cannot_build.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..1cae1bd4acd4539a24019b1a65ea2846055db846 GIT binary patch literal 83237 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 PKr|&Fq@C2zKa2kjFOmZz literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml index ca7bcf9..cdb1b1a 100644 --- a/pom.xml +++ b/pom.xml @@ -67,10 +67,12 @@ + diff --git a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java index f17cca1..433841b 100644 --- a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java +++ b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java @@ -1,12 +1,11 @@ package com.vocabularytrainer.project.controller; -import com.vocabularytrainer.project.db.VocabularyAddEntries; +import com.vocabularytrainer.project.db.VocabularyEntries; import com.vocabularytrainer.project.db.VocabularyRepository; // Repository Interface import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Controller; @@ -15,10 +14,6 @@ import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.security.core.Authentication; -import org.springframework.web.servlet.mvc.support.RedirectAttributes; - - @Controller public class MVCController { @@ -56,18 +51,18 @@ public String userIndex(Model model) { public String getUserAddVocabulary(Model model) { - VocabularyAddEntries vocabularyAddEntries = new VocabularyAddEntries(); + VocabularyEntries vocabularyEntries = new VocabularyEntries(); // Thymeleaf-variable for "get-form" - model.addAttribute("addvoc", vocabularyAddEntries); + model.addAttribute("addvoc", vocabularyEntries); return "user/addvoc_form"; } /* Submit Data from Form using POST */ @PostMapping("/user/addvoc") - public String submitUserAddVocabulary(VocabularyAddEntries vocabularyAddEntries, Model model) { + public String submitUserAddVocabulary(VocabularyEntries vocabularyEntries, Model model) { model.addAttribute("submitted", true); @@ -75,14 +70,15 @@ public String submitUserAddVocabulary(VocabularyAddEntries vocabularyAddEntries, Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); UserDetails userDetails = (UserDetails) authentication.getPrincipal(); - vocabularyAddEntries.setUser(userDetails.getUsername()); + vocabularyEntries.setUser(userDetails.getUsername()); // save result in our Repository Interface - VocabularyAddEntries result = this.vocabularyRepository.save(vocabularyAddEntries); + VocabularyEntries result = this.vocabularyRepository.save(vocabularyEntries); // Thymeleaf-variable for "post-form" - add it model.addAttribute("addvoc", result); + /// TODO: Fix redirecting return "user/addvoc_form"; } diff --git a/src/main/java/com/vocabularytrainer/project/db/VocabularyAddEntries.java b/src/main/java/com/vocabularytrainer/project/db/VocabularyEntries.java similarity index 96% rename from src/main/java/com/vocabularytrainer/project/db/VocabularyAddEntries.java rename to src/main/java/com/vocabularytrainer/project/db/VocabularyEntries.java index 323b6c8..0040032 100644 --- a/src/main/java/com/vocabularytrainer/project/db/VocabularyAddEntries.java +++ b/src/main/java/com/vocabularytrainer/project/db/VocabularyEntries.java @@ -10,13 +10,12 @@ @Entity // tells Hibernate ("database manager for java") this is a database table @Table(name = "tabAllUserVocabularies") -public class VocabularyAddEntries { +public class VocabularyEntries { /* Model of Table */ @Id // these are some options for id to be auto-increment @GeneratedValue(strategy = GenerationType.AUTO) private int id; - private String user; private String german_word; private String engl_trans; @@ -24,7 +23,7 @@ public class VocabularyAddEntries { private String tag; // for Issue LANG_005 ("custom tags for filtering") // Standard Constructor e.g. called in getUserAddVocabulary() - public VocabularyAddEntries() { + public VocabularyEntries() { } diff --git a/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java b/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java index 89c9a0c..157346e 100644 --- a/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java +++ b/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java @@ -1,6 +1,5 @@ package com.vocabularytrainer.project.db; -import com.vocabularytrainer.project.db.VocabularyAddEntries; // database entity import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -10,16 +9,16 @@ // with this, we can make the connection to the database - "connection layer" // JPA = Java Persistence API for managing relational data (=Database) // We use JPQL (="SQL" queries in Java) to make queries -public interface VocabularyRepository extends JpaRepository { +public interface VocabularyRepository extends JpaRepository { /* Queries */ - @Query(value="SELECT u FROM VocabularyAddEntries u") - List showAllVocabulary(); + @Query(value="SELECT u FROM VocabularyEntries u") + List showAllVocabulary(); - @Query(value="SELECT x FROM VocabularyAddEntries x WHERE x.user = :paruser") + @Query(value="SELECT x FROM VocabularyEntries x WHERE x.user = :paruser") // using Java Template we save everything in there ad use as Data Type the table - List showAllVocabularyFromUserX( + List showAllVocabularyFromUserX( @Param("paruser") String paruser // Parameter Handling for JPQL-Style queries ); diff --git a/src/main/resources/.DS_Store b/src/main/resources/.DS_Store index 69fcce4eef13c509a2bab99b3ecaac7d07d361f3..565565c990ab86824afec2d869707e9f71ba3d0e 100644 GIT binary patch delta 76 zcmZp1XmQx!Cct=dvb#WorbKnMsiB#Uf}y2xt&T#qxw(Okf{C$NZ7nBM8XF_ge gRdr2m-OR}!1>_lLZ59;##
-

Welcome


+ +

Welcome

+

+ +

+

Overview of your Vocabularies


From bd3b76b9bed1b1e6ee86a6bcd16cdb5e8824bb63 Mon Sep 17 00:00:00 2001 From: Andreas Hiess Date: Wed, 25 Mar 2020 11:15:55 +0100 Subject: [PATCH 49/74] Merge branch 'develop' of https://github.com/sw20-tug/ASD-Morning-4 into develop # Conflicts: # .gitignore # README.md --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index a0904eb..74a307c 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,4 +1,4 @@ spring.jpa.hibernate.ddl-auto=update -spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_vocabularytrainer +spring.datasource.url=jdbc:mysql://localhost:3306/db_vocabularytrainer?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC spring.datasource.username=student spring.datasource.password=student \ No newline at end of file From 785f7c2dff67dd0c7c97a20345f0d8a817de0560 Mon Sep 17 00:00:00 2001 From: eder13 Date: Wed, 25 Mar 2020 12:39:22 +0100 Subject: [PATCH 50/74] LANG-000 Update Docs [RS, PC] --- README.md | 12 +-- docs/Documentation.md | 219 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 221 insertions(+), 10 deletions(-) create mode 100644 docs/Documentation.md diff --git a/README.md b/README.md index af87b86..336ea51 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ vocabulary in a foreign language. ### Setup +[Please see here for setup instructions](docs/Documentation.md#setup-instructions) + ### Requirements * Java SDK 1.8 or higher @@ -14,16 +16,6 @@ vocabulary in a foreign language. * MySQL 5.6 or higher * JetBrains IntelliJ Ultimate IDE -### Building and Running - -* Clone/Download this repository -* Start IntelliJ and click 'Open' -* Navigate in your cloned repo folder, choose the `pom.xml` file and click 'ok' -* After prompted 'pom.xml is a project file' click 'Open as Project' -* To start the application hit the green 'play button' (JavaSpringIdeaApplication selected), the spring boot application will start (see Run) - * Alternatively, you can also right-click on `JavapringIdeaApplication.java` and click 'Run' -* Navigate in your Browser to the home url: `http://localhost:8080 - ### Meeting Notes ___18.03.2020___ diff --git a/docs/Documentation.md b/docs/Documentation.md new file mode 100644 index 0000000..cf85149 --- /dev/null +++ b/docs/Documentation.md @@ -0,0 +1,219 @@ +# Configuring the Project + +## Setup Instructions + +### Requirements + +* Java SDK 1.8 or higher +* JDK 8 or higher +* MySQL 5.6 or higher +* JetBrains IntelliJ Ultimate IDE (optional but recommended) + * alternatively, you can skip this and just build and start the application in a terminal, typing the following: + + ``` + $ cd $PROJECT_ROOT_DIR/ + $ mvn package + $ cd target/ + $ java -jar target/project-0.0.1-SNAPSHOT.jar + ``` + + * But make sure that you edited your [MySQL configurations](#adding-mysql-to-our-project) beforehand. + +### Building and Running + +* Clone/Download this repository +* Start IntelliJ and click 'Open' +* Navigate in your cloned repo folder, choose the `pom.xml` file and click 'ok' +* After prompted 'pom.xml is a project file' click 'Open as Project' +* Before you run the project, configure [MySQL](#adding-mysql-to-our-project). +* To start the application hit the green 'play button' (VocabularyTrainerApplication selected), the spring boot application will start (see Run) + * Alternatively, you can also right-click on `VocabularyTrainerApplication.java` and click 'Run' +* Navigate in your Browser to the home url: [http://localhost:8080](http://localhost:8080) + +#### Adding MySQL to our Project + +* Download and Install MySQL [Community](https://dev.mysql.com/downloads/mysql/) and [Workbench](https://www.mysql.com/products/workbench/), setup everything +in the workbench (create user `student` and password `student` for simplicity) + and start the server (default port is 3306). + +* Add the following to `src/recources/application.properties`: + + ``` + spring.jpa.hibernate.ddl-auto=update + spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_vocabularies + spring.datasource.username=student + spring.datasource.password=student + ``` + +* (Replace `username` and `password` with your MySQL configuration if your credentials differ). + +# Project Overview + +## Project Skeleton + +__Note__: user specific files (.idea, project.iml) and directories (target/) are not included and ignored (.gitignore). +``` +src + +- main + | +- resources + | | +- templates + | | | +- index.html + | | | | + | | | +- login.html + | | | | + | | | +- access-denied-page.html + | | | | + | | | +- user + | | | +- index.html + | | | | + | | | +- addvoc_form.html + | | | + | | +- static + | | | +- style.css + | | | + | | +- application.properties + | +- java + | +-com + | +- vocabularytrainer + | +- project + | +- VocabularyTrainerApplication.java + | | + | +- db + | | +- VocabularyAddEntries.java + | | +- VocabularyRepository.java + | | + | +- controller + | | +- MVCController.java + | | + | +- security + | +- SpringSecurityLogin.java + +- test + | +- java + | +- com + | +- vocabularytrainer + | +- project + | +- VocabularyTrainerApplicationTests.java + | + +- docs + | +- Documentation.md + | | + | +- fix_cannot_build.jpeg + | + +- .gitignore + | + +- mvnw + | + +- mvnw.cmd + | + +- pom.xml + | + +- README.md + +``` + +## `pom.xml` configuration and dependencis + +```xml + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.2.5.RELEASE + + + com.vocabularytrainer + project + 0.0.1-SNAPSHOT + vocabulary-trainer + A Vocabulary Trainer Web Application. + + + 1.8 + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + + mysql + mysql-connector-java + runtime + + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + + org.springframework.boot + spring-boot-devtools + + + + + org.springframework.boot + spring-boot-starter-security + + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + +``` + +# Troubleshooting + +### Fix, if you can't build the project (after pulling) + +![img_fix_cannot_build](fix_cannot_build.jpeg "picture") + + + +### Useful Spring Boot, Thymeleaf, Bootstrap Get Started-Links + + + + From fa8f76889a475908b89bf49404625c014f9096ae Mon Sep 17 00:00:00 2001 From: eder13 Date: Wed, 25 Mar 2020 12:40:30 +0100 Subject: [PATCH 51/74] LANG-000 Update Docs [RS, PC] --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index 336ea51..352714d 100644 --- a/README.md +++ b/README.md @@ -9,13 +9,6 @@ vocabulary in a foreign language. [Please see here for setup instructions](docs/Documentation.md#setup-instructions) -### Requirements - -* Java SDK 1.8 or higher -* JDK 8 or higher -* MySQL 5.6 or higher -* JetBrains IntelliJ Ultimate IDE - ### Meeting Notes ___18.03.2020___ From f1b8a15678d3f66d0a031caccc45483604eaba7e Mon Sep 17 00:00:00 2001 From: Christoph Pruell Date: Thu, 26 Mar 2020 15:06:13 +0100 Subject: [PATCH 52/74] LANG-004 First Version [PC, WC] --- .../project/controller/MVCController.java | 18 ++++ src/main/resources/templates/login.html | 4 +- .../resources/templates/user/addvoc_form.html | 1 + src/main/resources/templates/user/index.html | 2 + .../user/study_interface_german.html | 82 +++++++++++++++++++ 5 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 src/main/resources/templates/user/study_interface_german.html diff --git a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java index 433841b..46a0bfb 100644 --- a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java +++ b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java @@ -45,6 +45,22 @@ public String userIndex(Model model) { return "user/index"; } + /* User StudyInterface: Overview */ + @GetMapping("/user/studyInterfaceGerman") + public String userStudyInterface(Model model) { + + // tell the thymeleaf which user is logged in + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + model.addAttribute("current_user", userDetails.getUsername()); + + // get the Query to show current vocabulary entries of user x + model.addAttribute("overview", this.vocabularyRepository.showAllVocabularyFromUserX(userDetails.getUsername())); + + return "user/study_interface_german"; + } + /* Show the Form and Let the user enter stuff */ @GetMapping("/user/addvoc") // Model -> Thymeleaf model to access html "variables" @@ -60,6 +76,8 @@ public String getUserAddVocabulary(Model model) { return "user/addvoc_form"; } + + /* Submit Data from Form using POST */ @PostMapping("/user/addvoc") public String submitUserAddVocabulary(VocabularyEntries vocabularyEntries, Model model) { diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html index e6f01a3..9d0c3a2 100644 --- a/src/main/resources/templates/login.html +++ b/src/main/resources/templates/login.html @@ -90,11 +90,11 @@

- +

- +

diff --git a/src/main/resources/templates/user/addvoc_form.html b/src/main/resources/templates/user/addvoc_form.html index aaf6583..4796ca3 100644 --- a/src/main/resources/templates/user/addvoc_form.html +++ b/src/main/resources/templates/user/addvoc_form.html @@ -45,6 +45,7 @@
Add new Vocabulary
+

back

diff --git a/src/main/resources/templates/user/index.html b/src/main/resources/templates/user/index.html index 320929c..0290302 100644 --- a/src/main/resources/templates/user/index.html +++ b/src/main/resources/templates/user/index.html @@ -50,6 +50,8 @@

Overview of your Vocabularies

Add Vocabulary

Add vocabulary +

Study Interface

+

Logout

diff --git a/src/main/resources/templates/user/study_interface_german.html b/src/main/resources/templates/user/study_interface_german.html new file mode 100644 index 0000000..b6aa1cc --- /dev/null +++ b/src/main/resources/templates/user/study_interface_german.html @@ -0,0 +1,82 @@ + + + + + StudyInterfaceGerman + + + + + + + + + + + + + + +
+ + +

Welcome

+

+

to your Studyinterface.

+ +
+
+ +

Click words to reveal them.

+
+
+ + + + + + + + + + + + + +
German Vocabulary
+ +
+ + + + + + + +
+ +
+
+ + +

back

+ +
+ + + \ No newline at end of file From 67cb6b7928e714ee0efd64c5f3278166c5c0acc2 Mon Sep 17 00:00:00 2001 From: Christoph Pruell Date: Thu, 26 Mar 2020 18:14:03 +0100 Subject: [PATCH 53/74] LANG-004 Working Prototype [PC, WC] --- .../project/controller/MVCController.java | 32 ++++++++- .../templates/user/study_interface.html | 32 +++++++++ .../user/study_interface_english.html | 66 +++++++++++++++++++ .../user/study_interface_german.html | 25 ++----- 4 files changed, 133 insertions(+), 22 deletions(-) create mode 100644 src/main/resources/templates/user/study_interface.html create mode 100644 src/main/resources/templates/user/study_interface_english.html diff --git a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java index 46a0bfb..99981bf 100644 --- a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java +++ b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java @@ -45,9 +45,9 @@ public String userIndex(Model model) { return "user/index"; } - /* User StudyInterface: Overview */ + /* User StudyInterface in German*/ @GetMapping("/user/studyInterfaceGerman") - public String userStudyInterface(Model model) { + public String userStudyInterfaceGerman(Model model) { // tell the thymeleaf which user is logged in Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); @@ -61,6 +61,34 @@ public String userStudyInterface(Model model) { return "user/study_interface_german"; } + @GetMapping("/user/studyInterfaceEnglish") + public String userStudyInterfaceEnglish(Model model) { + + // tell the thymeleaf which user is logged in + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + model.addAttribute("current_user", userDetails.getUsername()); + + // get the Query to show current vocabulary entries of user x + model.addAttribute("overview", this.vocabularyRepository.showAllVocabularyFromUserX(userDetails.getUsername())); + + return "user/study_interface_english"; + } + + + @GetMapping("/user/studyInterface") + public String userStudyInterface(Model model) { + + // tell the thymeleaf which user is logged in + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + model.addAttribute("current_user", userDetails.getUsername()); + + return "user/study_interface"; + } + /* Show the Form and Let the user enter stuff */ @GetMapping("/user/addvoc") // Model -> Thymeleaf model to access html "variables" diff --git a/src/main/resources/templates/user/study_interface.html b/src/main/resources/templates/user/study_interface.html new file mode 100644 index 0000000..f8d23be --- /dev/null +++ b/src/main/resources/templates/user/study_interface.html @@ -0,0 +1,32 @@ + + + + + Dashboard + + + + + + + + + + + + + + +
+ + +

Choose the displayed language!

+

+ German + English + +
+ + \ No newline at end of file diff --git a/src/main/resources/templates/user/study_interface_english.html b/src/main/resources/templates/user/study_interface_english.html new file mode 100644 index 0000000..17747bc --- /dev/null +++ b/src/main/resources/templates/user/study_interface_english.html @@ -0,0 +1,66 @@ + + + + + StudyInterfaceEnglish + + + + + + + + + + + + + + +
+ +
+
+ +

Click words to reveal them.

+
+
+ + + + + + + + + + + + + +
English Vocabulary
+ + +
+
+ + +

back

+ +
+ + + \ No newline at end of file diff --git a/src/main/resources/templates/user/study_interface_german.html b/src/main/resources/templates/user/study_interface_german.html index b6aa1cc..42d2a9b 100644 --- a/src/main/resources/templates/user/study_interface_german.html +++ b/src/main/resources/templates/user/study_interface_german.html @@ -21,10 +21,6 @@
- -

Welcome

-

-

to your Studyinterface.



@@ -52,23 +48,12 @@

Click words to reveal them.

}); - + + + + -
- - - - - - - -
- - - - +
From 9032742b87e06375e12f0eaa2a1ffd3c1b77c1f6 Mon Sep 17 00:00:00 2001 From: Christoph Pruell Date: Thu, 26 Mar 2020 18:30:38 +0100 Subject: [PATCH 54/74] LANG-004 First Version, forgot to commit index [PC, WC] --- src/main/resources/templates/user/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/user/index.html b/src/main/resources/templates/user/index.html index 0290302..bf0dca2 100644 --- a/src/main/resources/templates/user/index.html +++ b/src/main/resources/templates/user/index.html @@ -50,7 +50,7 @@

Overview of your Vocabularies

Add Vocabulary

Add vocabulary -

Study Interface

+

Study Interface

Logout

From 8d01698e22553ec473058cb7bf922a2af85fcd45 Mon Sep 17 00:00:00 2001 From: caaarinschn <62135125+caaarinschn@users.noreply.github.com> Date: Wed, 1 Apr 2020 12:09:54 +0200 Subject: [PATCH 55/74] Update README.md --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README.md b/README.md index 352714d..979df99 100644 --- a/README.md +++ b/README.md @@ -37,5 +37,35 @@ ___25.03.2020___ * Planing resume: * Creating branches per Issue + +___01.04.2020___ + + ASD Morning - Meeting #3 + Date: 01.04.2020 + Time: 08:00 - 08:50 + Type of meeting: The Retro(spective) + Attendees: Beinhundner, Felgitscher, Hiess, Loitzenbauer, + Prüll, Ranftl, Wartinger, Weinhandl + Tools used to conduct the meeting: TeamSpeak + + * things that go well: + * all closed issues are working well + + * things to improve: + * focus more on branches + * focus more on the agile workflow + * pay attention to naming conventions + * pay attention to the "coding standard" + * code should be easy to read + * useful comments + + * next deadline 29.1. 11:00 + * Unit Test Hiess & Wartinger + * LAAG_003 Loitzenbauer & Ranftl + * LAAG_004 Prüll & Weinhandl + * LAAG_005 Beinhunder & Prüll + * LAAG_006 + * LAAG_007 Felgitscher & Weinhandl + From 8b0dc3e7c93f3ff6f851d6283990de04ee4b19b3 Mon Sep 17 00:00:00 2001 From: Simon Ranftl Date: Wed, 1 Apr 2020 12:31:35 +0200 Subject: [PATCH 56/74] LANG-003 Added Edit page [LJ, RS] --- .../project/controller/MVCController.java | 38 +++++++++++++++ .../project/db/VocabularyRepository.java | 5 ++ src/main/resources/application.properties | 2 +- .../resources/templates/user/edit_vocab.html | 47 +++++++++++++++++++ src/main/resources/templates/user/index.html | 2 + 5 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/templates/user/edit_vocab.html diff --git a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java index 99981bf..f0b8a32 100644 --- a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java +++ b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java @@ -11,7 +11,10 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.ModelAndView; @Controller @@ -89,6 +92,41 @@ public String userStudyInterface(Model model) { return "user/study_interface"; } + + /* Show the All vocabularies in edit_vocab.html*/ + @GetMapping("user/editvoc") + public String getUserEditVocabulary(Model model) { + + // tell the thymeleaf which user is logged in + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + // get the Query to show current vocabulary entries of user x + model.addAttribute("overview", this.vocabularyRepository.showAllVocabularyFromUserX(userDetails.getUsername())); + + return "user/edit_vocab"; + } + + + // user/editvoc/edit+${entry.id}} + @GetMapping("/edit/{id}") + public ModelAndView showEditProductPage(@PathVariable(name = "id") int id) { + ModelAndView mav = new ModelAndView("edit_product"); + + VocabularyEntries vocabularyEntries = this.vocabularyRepository.getEntryBasedOnId(id); + + + System.out.println(vocabularyEntries.getId()); + + + // Product product = service.get(id); + //mav.addObject("product", product); + + + + return mav; + } + /* Show the Form and Let the user enter stuff */ @GetMapping("/user/addvoc") // Model -> Thymeleaf model to access html "variables" diff --git a/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java b/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java index 157346e..29ca3df 100644 --- a/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java +++ b/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java @@ -22,5 +22,10 @@ List showAllVocabularyFromUserX( @Param("paruser") String paruser // Parameter Handling for JPQL-Style queries ); + @Query(value="SELECT i FROM VocabularyEntries i WHERE i.id = :parid") + VocabularyEntries getEntryBasedOnId( + @Param("parid") int parid + ); + } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index a0904eb..640172a 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,4 +1,4 @@ spring.jpa.hibernate.ddl-auto=update -spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_vocabularytrainer +spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_vocabularytrainer?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false spring.datasource.username=student spring.datasource.password=student \ No newline at end of file diff --git a/src/main/resources/templates/user/edit_vocab.html b/src/main/resources/templates/user/edit_vocab.html new file mode 100644 index 0000000..5cfc91d --- /dev/null +++ b/src/main/resources/templates/user/edit_vocab.html @@ -0,0 +1,47 @@ + + + + + Edit Vocabularies + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
IDGerman VocabularyEnglish TranslationActions
+ Edit + +
+ + back + +
+ + + \ No newline at end of file diff --git a/src/main/resources/templates/user/index.html b/src/main/resources/templates/user/index.html index bf0dca2..b3d2e03 100644 --- a/src/main/resources/templates/user/index.html +++ b/src/main/resources/templates/user/index.html @@ -50,6 +50,8 @@

Overview of your Vocabularies

Add Vocabulary

Add vocabulary +

Edit Vocabulary

+

Study Interface

Logout

From 72f1f8c505a9e0dac2ebe5939103ce76b878062d Mon Sep 17 00:00:00 2001 From: 16loitze <62160103+16loitze@users.noreply.github.com> Date: Wed, 1 Apr 2020 12:39:45 +0200 Subject: [PATCH 57/74] Delete README.md --- README.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 README.md diff --git a/README.md b/README.md deleted file mode 100644 index deab57b..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# ASD: Morning 4 - -This is the repository for the team *ASD: Morning 4* - -Test From 248f06f51b2e68201161043397e1fd37cbc9b040 Mon Sep 17 00:00:00 2001 From: 16loitze Date: Wed, 1 Apr 2020 12:41:34 +0200 Subject: [PATCH 58/74] Initial --- README.md | 41 +++ docs/Documentation.md | 219 +++++++++++++ docs/fix_cannot_build.jpeg | Bin 0 -> 83237 bytes mvnw | 310 ++++++++++++++++++ mvnw.cmd | 182 ++++++++++ pom.xml | 88 +++++ src/main/.DS_Store | Bin 0 -> 10244 bytes src/main/java/.DS_Store | Bin 0 -> 6148 bytes src/main/java/com/.DS_Store | Bin 0 -> 6148 bytes src/main/java/com/vocabularytrainer/.DS_Store | Bin 0 -> 6148 bytes .../com/vocabularytrainer/project/.DS_Store | Bin 0 -> 6148 bytes .../project/VocabularyTrainerApplication.java | 13 + .../project/controller/MVCController.java | 180 ++++++++++ .../project/db/VocabularyEntries.java | 79 +++++ .../project/db/VocabularyRepository.java | 31 ++ .../project/security/SpringSecurityLogin.java | 67 ++++ src/main/resources/.DS_Store | Bin 0 -> 8196 bytes src/main/resources/application.properties | 4 + src/main/resources/static/style.css | 4 + src/main/resources/templates/.DS_Store | Bin 0 -> 8196 bytes .../templates/access-denied-page.html | 27 ++ src/main/resources/templates/index.html | 33 ++ src/main/resources/templates/login.html | 109 ++++++ .../resources/templates/user/addvoc_form.html | 52 +++ .../resources/templates/user/edit_vocab.html | 47 +++ src/main/resources/templates/user/index.html | 61 ++++ .../templates/user/study_interface.html | 32 ++ .../user/study_interface_english.html | 66 ++++ .../user/study_interface_german.html | 67 ++++ .../VocabularyTrainerApplicationTests.java | 13 + 30 files changed, 1725 insertions(+) create mode 100644 README.md create mode 100644 docs/Documentation.md create mode 100644 docs/fix_cannot_build.jpeg create mode 100644 mvnw create mode 100644 mvnw.cmd create mode 100644 pom.xml create mode 100644 src/main/.DS_Store create mode 100644 src/main/java/.DS_Store create mode 100644 src/main/java/com/.DS_Store create mode 100644 src/main/java/com/vocabularytrainer/.DS_Store create mode 100644 src/main/java/com/vocabularytrainer/project/.DS_Store create mode 100644 src/main/java/com/vocabularytrainer/project/VocabularyTrainerApplication.java create mode 100644 src/main/java/com/vocabularytrainer/project/controller/MVCController.java create mode 100644 src/main/java/com/vocabularytrainer/project/db/VocabularyEntries.java create mode 100644 src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java create mode 100644 src/main/java/com/vocabularytrainer/project/security/SpringSecurityLogin.java create mode 100644 src/main/resources/.DS_Store create mode 100644 src/main/resources/application.properties create mode 100644 src/main/resources/static/style.css create mode 100644 src/main/resources/templates/.DS_Store create mode 100644 src/main/resources/templates/access-denied-page.html create mode 100644 src/main/resources/templates/index.html create mode 100644 src/main/resources/templates/login.html create mode 100644 src/main/resources/templates/user/addvoc_form.html create mode 100644 src/main/resources/templates/user/edit_vocab.html create mode 100644 src/main/resources/templates/user/index.html create mode 100644 src/main/resources/templates/user/study_interface.html create mode 100644 src/main/resources/templates/user/study_interface_english.html create mode 100644 src/main/resources/templates/user/study_interface_german.html create mode 100644 src/test/java/com/vocabularytrainer/project/VocabularyTrainerApplicationTests.java diff --git a/README.md b/README.md new file mode 100644 index 0000000..352714d --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ +# ASD: Morning 4 + +## Vocabulary Trainer + +Vocabulary trainer is a dictionary and training application which allows its users to study and test +vocabulary in a foreign language. + +### Setup + +[Please see here for setup instructions](docs/Documentation.md#setup-instructions) + +### Meeting Notes + +___18.03.2020___ + +* Using Teamspeak for Voice Calls +* WhatsApp, Slack and Teamspeak chat for messaging +* Setup GitHub Workflow with IntelliJ IDE + * GitHub Login, Fork, Push, Commits, Pull Requests +* Added .gitignore and updated README.md +* Web Application using Java Spring Boot as backend server framework and MySQL database (queries vocabularies). On the Fronted-Side we use HTML. +* TODO until next week: + * Read Java Spring Boot docs and setup a Spring Boot Test Project + * Read MySQL docs and setup everything + * Install Teamviewer for collaborative programming + * Split into groups and create branch for each Issue. + +___25.03.2020___ + +* Setting Up the Framework for every participant. +* Setting goals for Sprint 2 + * Issues 003 - 007 +* Organizing pair-programming Teams + * Teamviewer is used for this point +* Start implementing next issues +* Planning to introduce Unit-Tests + +* Planing resume: + * Creating branches per Issue + + diff --git a/docs/Documentation.md b/docs/Documentation.md new file mode 100644 index 0000000..cf85149 --- /dev/null +++ b/docs/Documentation.md @@ -0,0 +1,219 @@ +# Configuring the Project + +## Setup Instructions + +### Requirements + +* Java SDK 1.8 or higher +* JDK 8 or higher +* MySQL 5.6 or higher +* JetBrains IntelliJ Ultimate IDE (optional but recommended) + * alternatively, you can skip this and just build and start the application in a terminal, typing the following: + + ``` + $ cd $PROJECT_ROOT_DIR/ + $ mvn package + $ cd target/ + $ java -jar target/project-0.0.1-SNAPSHOT.jar + ``` + + * But make sure that you edited your [MySQL configurations](#adding-mysql-to-our-project) beforehand. + +### Building and Running + +* Clone/Download this repository +* Start IntelliJ and click 'Open' +* Navigate in your cloned repo folder, choose the `pom.xml` file and click 'ok' +* After prompted 'pom.xml is a project file' click 'Open as Project' +* Before you run the project, configure [MySQL](#adding-mysql-to-our-project). +* To start the application hit the green 'play button' (VocabularyTrainerApplication selected), the spring boot application will start (see Run) + * Alternatively, you can also right-click on `VocabularyTrainerApplication.java` and click 'Run' +* Navigate in your Browser to the home url: [http://localhost:8080](http://localhost:8080) + +#### Adding MySQL to our Project + +* Download and Install MySQL [Community](https://dev.mysql.com/downloads/mysql/) and [Workbench](https://www.mysql.com/products/workbench/), setup everything +in the workbench (create user `student` and password `student` for simplicity) + and start the server (default port is 3306). + +* Add the following to `src/recources/application.properties`: + + ``` + spring.jpa.hibernate.ddl-auto=update + spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_vocabularies + spring.datasource.username=student + spring.datasource.password=student + ``` + +* (Replace `username` and `password` with your MySQL configuration if your credentials differ). + +# Project Overview + +## Project Skeleton + +__Note__: user specific files (.idea, project.iml) and directories (target/) are not included and ignored (.gitignore). +``` +src + +- main + | +- resources + | | +- templates + | | | +- index.html + | | | | + | | | +- login.html + | | | | + | | | +- access-denied-page.html + | | | | + | | | +- user + | | | +- index.html + | | | | + | | | +- addvoc_form.html + | | | + | | +- static + | | | +- style.css + | | | + | | +- application.properties + | +- java + | +-com + | +- vocabularytrainer + | +- project + | +- VocabularyTrainerApplication.java + | | + | +- db + | | +- VocabularyAddEntries.java + | | +- VocabularyRepository.java + | | + | +- controller + | | +- MVCController.java + | | + | +- security + | +- SpringSecurityLogin.java + +- test + | +- java + | +- com + | +- vocabularytrainer + | +- project + | +- VocabularyTrainerApplicationTests.java + | + +- docs + | +- Documentation.md + | | + | +- fix_cannot_build.jpeg + | + +- .gitignore + | + +- mvnw + | + +- mvnw.cmd + | + +- pom.xml + | + +- README.md + +``` + +## `pom.xml` configuration and dependencis + +```xml + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.2.5.RELEASE + + + com.vocabularytrainer + project + 0.0.1-SNAPSHOT + vocabulary-trainer + A Vocabulary Trainer Web Application. + + + 1.8 + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + + mysql + mysql-connector-java + runtime + + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + + org.springframework.boot + spring-boot-devtools + + + + + org.springframework.boot + spring-boot-starter-security + + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + +``` + +# Troubleshooting + +### Fix, if you can't build the project (after pulling) + +![img_fix_cannot_build](fix_cannot_build.jpeg "picture") + + + +### Useful Spring Boot, Thymeleaf, Bootstrap Get Started-Links + + + + diff --git a/docs/fix_cannot_build.jpeg b/docs/fix_cannot_build.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..1cae1bd4acd4539a24019b1a65ea2846055db846 GIT binary patch literal 83237 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 PKr|&Fq@C2zKa2kjFOmZz literal 0 HcmV?d00001 diff --git a/mvnw b/mvnw new file mode 100644 index 0000000..a16b543 --- /dev/null +++ b/mvnw @@ -0,0 +1,310 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..c8d4337 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,182 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..cdb1b1a --- /dev/null +++ b/pom.xml @@ -0,0 +1,88 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.2.5.RELEASE + + + com.vocabularytrainer + project + 0.0.1-SNAPSHOT + vocabulary-trainer + A Vocabulary Trainer Web Application. + + + 1.8 + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + + mysql + mysql-connector-java + runtime + + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + + org.springframework.boot + spring-boot-devtools + + + + + org.springframework.boot + spring-boot-starter-security + + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/src/main/.DS_Store b/src/main/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..f342cf74c5bcce57738c854988b98ab36322b99e GIT binary patch literal 10244 zcmeHMU2GIp6h5aEm>;0G{I?1W7Hct!bi1Xk;m7T^AVm;#3oWIz%Vq#46L0?RKF&d5M&Yi7g+xl2YoSV!&_nvdl z+3b*rXN~s7nGD#$V$c%Wy8QaZJ|I;a>BSnNj zgg}Hqgg}HqguuOk0Of36Bvr_$ju40th!B`SfPWt}y0}b+a!knJ(?M0R1t3{T>Yz}Y z@dimPl*v$z2}u?zC|pSjR}8lpDBMY}h2xT;91~Kw1BROq3}?o0hl0WEbbl=v4ww`& zsv`s<1g0Xu_wJQ&9CRpvK6(G18MZCYZ*2S;E9O+roi|^S6iHdA98Mo|N7BCT=e?Ak zJH&hYbpKc;YD2aZ9d5B$+~ua$nko8^Q6x;eV&{1I|Ah(V|mYf+NAMT!R#b2Z;&nKciKDbTdw0B zFmoQsx@4nRwk%y)xO{cpL$P?v=H&MAMOCa?S)wfKDOjGBvCaJ>mf;^esC!w{F)Zh3 zA7SSB)-#rwldJJZx!ci)%<&Z~YpT`z)KxQiNvuxl&1bA<^Ok>Vyt;}lTBE5-zd_5} z;~M;K2D>iFfn}Yhs)x9xBWF@=NK&9~Sg$JG9tF$vaNveV6s7wFJyhn&!nG-(sQYa_ zW7^D+g=hgNlyrVpai z)SZ%akXzdg!!+uW4FbOa0GaW0QUeb_Gwg(Ya1aa_fmh%)I1d-#Ew~Er!G~}YK8G*h zOBjb+@B{n|zrr8zC;SC}<9uYe3fG{9Yw=-h!B%X;cHDtGu?u%$8hf!14`Dx=cmjve zK^ITr7(R#R@OgX{&*MeBgqQJcyoT5Def$7F!jJI=euiJ+w|HBuv!X=TJ)&Q#@jGfw zypTlK@Ib9%U|PEFcwA|?yL7#^kaKkLlBLU*uUWT#LsRRP_K9a%_Vn%`*kn!xL=sF1 z7*t}&1ebsYU!yic-rgq?T#;SC(YN$2qDa z1R?}x3xPReB8{K_Z=d=9|JhnjG*5&;guq=u04qDwohh2Qv^6SU13zom=sH3dFMQmX zkbw(Tcl;4R9ex}i9LbO^JlYEUlBDPUV?qY*)DPTA&eER&(f*&q|8I%*{{a89{r^Ax CHwwxC literal 0 HcmV?d00001 diff --git a/src/main/java/.DS_Store b/src/main/java/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..35a54bf0595027f28217af82c3d32981e121b5e7 GIT binary patch literal 6148 zcmeH~Jr2S!425mVP>H1@V-^m;4I%_5-~tF3K^+i#j?VMXLSaS~dY0@jc51bKLsN^0 z?w;4J$RHv;+$b9h6I0}!Tx68{^>MkK$MI$*w?)zl@IfZ~xlK?3DnJFO02QDDGg2TA z@_sd=XX2w!0V*&L1?>A!;KrJ4LH~3h_y_tMAK>5S|49o|DnJGPOaWc) zkNX{7D$mxB*R%R5tF~@%&@V@L`w2i|NAVi&hW%m-uqIm&6&Qa6Tm}Xz@KXg|*oF~o literal 0 HcmV?d00001 diff --git a/src/main/java/com/.DS_Store b/src/main/java/com/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..9845f5c753a386a39194689b379de9c62eddd2fa GIT binary patch literal 6148 zcmeHKIZgvX5Ud6VmPkxSIA7ogE6coq58#6UX~jwgTO!+tckwi;j{s{SvPi6Isi$Uo zx@I&LY;Oaw~aH_y{E*D<^ALxJd|EDCaq<|E-CJG|f(1D?P0 zhof)Fq<|EV0#ZNEIA80CC1}80XPT z5Ss^xy>Luqgl0)4Ce^CNu%t8IDz6ugiAjf5^I>(fRfl46JI`;C4(o{;rGOMTSKv06 zORxVM`i1`goTQZ$kOKco0h_J2>lL3=wRQ41ueFW-NcWsCx*O*~;SlAR80DA?FUR+h blzGkP-0y{BV$c~6I#E9Zu8T|x{I&uoNJtfu literal 0 HcmV?d00001 diff --git a/src/main/java/com/vocabularytrainer/project/.DS_Store b/src/main/java/com/vocabularytrainer/project/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..55861b51956d8a04bfa659f3a45a8981cdc7aaef GIT binary patch literal 6148 zcmeH~JqiLr422WjLa^D=avBfd4F=H@cmdHZg)PK>j_%73qN}xtyg>3YnF-5&#m+`V zbbA{%BE5(#;HI*+Ffqk?CWD-Y>-lmT$IH|HEOR>p?`5+8bd)IxkN^pg011%5j}WkX z8@5=6GLirZkidh0eIE+kw5GOD|8yYu2mtL+c0=y71hiNIT2osnDlm;!Xtb)2Ay)Tx zXvuRmwS`8zXbvBmPga{^U>fbB1q+x~7X}g_feC?mtb4ov_wY~i|D=UW5+H#;BcR>x zu-oFL@@{>5J*ywHYI%c0{W!wQPXHEn6|dlK*e{kqYibKc1;!r%$G|`WUnOt{H0lr` literal 0 HcmV?d00001 diff --git a/src/main/java/com/vocabularytrainer/project/VocabularyTrainerApplication.java b/src/main/java/com/vocabularytrainer/project/VocabularyTrainerApplication.java new file mode 100644 index 0000000..6b04eb1 --- /dev/null +++ b/src/main/java/com/vocabularytrainer/project/VocabularyTrainerApplication.java @@ -0,0 +1,13 @@ +package com.vocabularytrainer.project; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class VocabularyTrainerApplication { + + public static void main(String[] args) { + SpringApplication.run(VocabularyTrainerApplication.class, args); + } + +} diff --git a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java new file mode 100644 index 0000000..f0b8a32 --- /dev/null +++ b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java @@ -0,0 +1,180 @@ +package com.vocabularytrainer.project.controller; + +import com.vocabularytrainer.project.db.VocabularyEntries; +import com.vocabularytrainer.project.db.VocabularyRepository; // Repository Interface + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; + +import org.springframework.security.core.userdetails.UserDetails; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.ModelAndView; + + +@Controller +public class MVCController { + + /* Setup access Database Repository Interface */ + VocabularyRepository vocabularyRepository; + public MVCController(VocabularyRepository vocabularyRepository) { + this.vocabularyRepository = vocabularyRepository; + } + + /* Welcome Page */ + @GetMapping("/") + public String root() { + return "index"; + } + + /* User Interface: Dashboard */ + @GetMapping("/user") + public String userIndex(Model model) { + + // tell the thymeleaf which user is logged in + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + model.addAttribute("current_user", userDetails.getUsername()); + + // get the Query to show current vocabulary entries of user x + model.addAttribute("overview", this.vocabularyRepository.showAllVocabularyFromUserX(userDetails.getUsername())); + + return "user/index"; + } + + /* User StudyInterface in German*/ + @GetMapping("/user/studyInterfaceGerman") + public String userStudyInterfaceGerman(Model model) { + + // tell the thymeleaf which user is logged in + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + model.addAttribute("current_user", userDetails.getUsername()); + + // get the Query to show current vocabulary entries of user x + model.addAttribute("overview", this.vocabularyRepository.showAllVocabularyFromUserX(userDetails.getUsername())); + + return "user/study_interface_german"; + } + + @GetMapping("/user/studyInterfaceEnglish") + public String userStudyInterfaceEnglish(Model model) { + + // tell the thymeleaf which user is logged in + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + model.addAttribute("current_user", userDetails.getUsername()); + + // get the Query to show current vocabulary entries of user x + model.addAttribute("overview", this.vocabularyRepository.showAllVocabularyFromUserX(userDetails.getUsername())); + + return "user/study_interface_english"; + } + + + @GetMapping("/user/studyInterface") + public String userStudyInterface(Model model) { + + // tell the thymeleaf which user is logged in + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + model.addAttribute("current_user", userDetails.getUsername()); + + return "user/study_interface"; + } + + + /* Show the All vocabularies in edit_vocab.html*/ + @GetMapping("user/editvoc") + public String getUserEditVocabulary(Model model) { + + // tell the thymeleaf which user is logged in + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + // get the Query to show current vocabulary entries of user x + model.addAttribute("overview", this.vocabularyRepository.showAllVocabularyFromUserX(userDetails.getUsername())); + + return "user/edit_vocab"; + } + + + // user/editvoc/edit+${entry.id}} + @GetMapping("/edit/{id}") + public ModelAndView showEditProductPage(@PathVariable(name = "id") int id) { + ModelAndView mav = new ModelAndView("edit_product"); + + VocabularyEntries vocabularyEntries = this.vocabularyRepository.getEntryBasedOnId(id); + + + System.out.println(vocabularyEntries.getId()); + + + // Product product = service.get(id); + //mav.addObject("product", product); + + + + return mav; + } + + /* Show the Form and Let the user enter stuff */ + @GetMapping("/user/addvoc") + // Model -> Thymeleaf model to access html "variables" + public String getUserAddVocabulary(Model model) { + + + VocabularyEntries vocabularyEntries = new VocabularyEntries(); + + + // Thymeleaf-variable for "get-form" + model.addAttribute("addvoc", vocabularyEntries); + + return "user/addvoc_form"; + } + + + + /* Submit Data from Form using POST */ + @PostMapping("/user/addvoc") + public String submitUserAddVocabulary(VocabularyEntries vocabularyEntries, Model model) { + + model.addAttribute("submitted", true); + + // get current user + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + vocabularyEntries.setUser(userDetails.getUsername()); + + // save result in our Repository Interface + VocabularyEntries result = this.vocabularyRepository.save(vocabularyEntries); + + // Thymeleaf-variable for "post-form" - add it + model.addAttribute("addvoc", result); + + /// TODO: Fix redirecting + return "user/addvoc_form"; + } + + /* Login Page */ + @GetMapping("/login") + public String login() { + return "login"; + } + + /* Access Denied Page */ + @GetMapping("/request-denied") + public String accessDenied() { + return "access-denied-page"; + } +} diff --git a/src/main/java/com/vocabularytrainer/project/db/VocabularyEntries.java b/src/main/java/com/vocabularytrainer/project/db/VocabularyEntries.java new file mode 100644 index 0000000..0040032 --- /dev/null +++ b/src/main/java/com/vocabularytrainer/project/db/VocabularyEntries.java @@ -0,0 +1,79 @@ +package com.vocabularytrainer.project.db; + +// Entity-Model for Database Table + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; + +import javax.persistence.*; + +@Entity // tells Hibernate ("database manager for java") this is a database table +@Table(name = "tabAllUserVocabularies") +public class VocabularyEntries { + + /* Model of Table */ + @Id // these are some options for id to be auto-increment + @GeneratedValue(strategy = GenerationType.AUTO) + private int id; + private String user; + private String german_word; + private String engl_trans; + private int rating; // for Issue LANG_006 + private String tag; // for Issue LANG_005 ("custom tags for filtering") + + // Standard Constructor e.g. called in getUserAddVocabulary() + public VocabularyEntries() { + + } + + // getters/setters auto generation + // right-click->generate + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public String getGerman_word() { + return german_word; + } + + public void setGerman_word(String german_word) { + this.german_word = german_word; + } + + public String getEngl_trans() { + return engl_trans; + } + + public void setEngl_trans(String engl_trans) { + this.engl_trans = engl_trans; + } + + public int getRating() { + return rating; + } + + public void setRating(int rating) { + this.rating = rating; + } + + public String getTag() { + return tag; + } + + public void setTag(String tag) { + this.tag = tag; + } +} diff --git a/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java b/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java new file mode 100644 index 0000000..29ca3df --- /dev/null +++ b/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java @@ -0,0 +1,31 @@ +package com.vocabularytrainer.project.db; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; + +// with this, we can make the connection to the database - "connection layer" +// JPA = Java Persistence API for managing relational data (=Database) +// We use JPQL (="SQL" queries in Java) to make queries +public interface VocabularyRepository extends JpaRepository { + + /* Queries */ + + @Query(value="SELECT u FROM VocabularyEntries u") + List showAllVocabulary(); + + @Query(value="SELECT x FROM VocabularyEntries x WHERE x.user = :paruser") + // using Java Template we save everything in there ad use as Data Type the table + List showAllVocabularyFromUserX( + @Param("paruser") String paruser // Parameter Handling for JPQL-Style queries + ); + + @Query(value="SELECT i FROM VocabularyEntries i WHERE i.id = :parid") + VocabularyEntries getEntryBasedOnId( + @Param("parid") int parid + ); + + +} diff --git a/src/main/java/com/vocabularytrainer/project/security/SpringSecurityLogin.java b/src/main/java/com/vocabularytrainer/project/security/SpringSecurityLogin.java new file mode 100644 index 0000000..524bf01 --- /dev/null +++ b/src/main/java/com/vocabularytrainer/project/security/SpringSecurityLogin.java @@ -0,0 +1,67 @@ +package com.vocabularytrainer.project.security; + +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +@EnableWebSecurity +public class SpringSecurityLogin extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .antMatchers( + "/", + "/js/**", + "/css/**", + "/img/**", + "/webjars/**").permitAll() + + // redirect here after successful login with Role USER + .antMatchers("/user/**").hasRole("USER") + .anyRequest().authenticated() + .and() + .formLogin() + .loginPage("/login") + .permitAll() + .and() + .logout() + .invalidateHttpSession(true) + .clearAuthentication(true) + .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) + .logoutSuccessUrl("/login?logout") + .permitAll() + .and() + .exceptionHandling() + .accessDeniedPage("/request-denied"); + } + + // fix according: https://mkyong.com/spring-boot/spring-security-there-is-no-passwordencoder-mapped-for-the-id-null/ + @Bean + public UserDetailsService userDetailsService() { + PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); + + UserDetails user = User.withUsername("user") + .password(encoder.encode("password")) + .roles("USER").build(); + + UserDetails man = User.withUsername("manager") + .password(encoder.encode("password")) + .roles("MANAGER").build(); + + InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); + manager.createUser(user); + manager.createUser(man); + return manager; + } + +} diff --git a/src/main/resources/.DS_Store b/src/main/resources/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..565565c990ab86824afec2d869707e9f71ba3d0e GIT binary patch literal 8196 zcmeI1O>Epm6vyA&q^Unhml00b(`Dl%2;94yYtnj_?Us>mYc0~nCeoQ#>aZF9}p zfg?~LP#{nsP#{nsP+&7CKx;NTgbmhx9u4Y1fk1(~QUUgUh)`iR=Gzjt-m8NuZwo-S zlHA@wZQ2KTIT7E+d|TqyOQmb_-2?im=x;HQr&Bz_PA41lZHZf+4#?91{gKh%p`bT9 zWKzdcSL2Ugo^deYDrQp(Oj z+j3RI((_)jq3LwWY|^kadm(NYEY0z*li&eC5Ct)%gqN1OJA0y$&ilKTqmiZF-i~PG zNLSDDvMAIa=k4%w7anxs9YBQ>tDVVCO513}c zxTrhHjBOUOmNVt*7hL9-1w(V^r&TATTbf~=n;}sx*EnnFd9fCM7RN0$tFP47 zDBJ48vOHBt8|Mp#yQnk^g6G}SBuldz4fUw4u`EsbSP;F)z9v~d%_4(&oobB|yun-K zR#8!faffEiJ#EqjNAV#X!)ctsSv-R}T4-Y)9lV6k;>-97zKXBm z+xQM%!|V77e$FQrDkD3}`{f$Hpw>Fb5|jSZ8A`6piuK?;3mvpAvQ}a1(wcpDvgxpDd3==qklbFOgOru87oh9hb6Lc;X@G_S0DSR5A!RPQQzKAaohHv3} z9I;jKPL`457T;eVyka76nYML~qGe=nPYimSPk{M}-~iyb`xw3RUbB=J&SaWLN(%q;|xQ#e7@hmLhcg=N|%s N^*>nuJ@W4E>TfzS;e!AG literal 0 HcmV?d00001 diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..640172a --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,4 @@ +spring.jpa.hibernate.ddl-auto=update +spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_vocabularytrainer?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false +spring.datasource.username=student +spring.datasource.password=student \ No newline at end of file diff --git a/src/main/resources/static/style.css b/src/main/resources/static/style.css new file mode 100644 index 0000000..3422e13 --- /dev/null +++ b/src/main/resources/static/style.css @@ -0,0 +1,4 @@ +/* style.css sheet for overall design settings */ +/* TODO: Add Stylings here and bind them to .html files */ + + diff --git a/src/main/resources/templates/.DS_Store b/src/main/resources/templates/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..389d0d1049924f1b502ac3c196c59e15ca42bee5 GIT binary patch literal 8196 zcmeHMTWl0n827!PZ*LBE8XKxVYVx+9F7GTY7`GyE|h$GCNauX4^t3 zY1BmHZr`k*f)z8HVq)5t2 ztnqB_0(CcKC25M>d12MoXk9$zq{njt|FO9ft>Q(a;PgBq-_9c4l|Z@ zjVBE9Hz$lXigJh9YTnbqanE#Y_mGisNmfQ{#dKxq+{*QvD({cfHSLVdPk0r?aMaY_6o3t*X#e<*-iEJK*TNH=SLSWZzPysp=rNv}Oz{bxHEoHCt4r+oi>_ zMBupfK}G34N+e*eEJEuW6t%}nBn^w{vIuM5p{TtRV$JN)K)GwTqV~}jOVd)^5{v}u zmYAvz@sal@T<_qxVbiQG)A0W4G_^yL`nk15*A2ZgS|jlD0gxF#e#+opXoL>vf_~6p z5?+Q^;S`*Px8Xdz4oACi`!e-oo zE!d77*opfvj(s?QgLoJXJc?DvB?QuF`P^~y@l(ba3#u3KMGwPkC4 z^RAYKZ@J{_Eh1Phr+gv_ruYn+XUGDZ%hh|7P5Ic|L!2|FBu*T*g0rJs-K_{@rgb&nF2h_-C` zTzP5PhFGhjFyKEsc?tjig?;bA1-L}ay9VFGPw)%;3cn$ujKx^yGp-V=uo|~vE!JZL zZpS_NFmW%2ZFm45!-M#^&%Gl!gd=F;Q)m$bIscB~G@ihd_&mOVFXBr+4__k|zJYJz zyLfI1>pGXP?tCum(oS2Op7l}ySKs=${d#(_P0wo^AIrb-PQ){|<=CUt*F5tVPa$mG zG6IF7hf;q3-<$va|CYxII|va75x9L3z@oNzTa4zHZ>QyVZH@8>WuCa-tdM>P6^kAM ksJ-xqA=Nc<hv&afy*s-28=#UL=Kufz literal 0 HcmV?d00001 diff --git a/src/main/resources/templates/access-denied-page.html b/src/main/resources/templates/access-denied-page.html new file mode 100644 index 0000000..6e5080f --- /dev/null +++ b/src/main/resources/templates/access-denied-page.html @@ -0,0 +1,27 @@ + + + + + Access Denied + + + + + + + + + + + + + + +
+

Access denied

+

lel

+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html new file mode 100644 index 0000000..d6d11f7 --- /dev/null +++ b/src/main/resources/templates/index.html @@ -0,0 +1,33 @@ + + + + + Home + + + + + + + + + + + + + + +
+ +

Vocabulary Trainer

+ +

Vocabulary trainer is a dictionary and training application which allows its + users to study and test vocabulary in a foreign language.

+ +

Please sign in here

+ +
+ + \ No newline at end of file diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html new file mode 100644 index 0000000..9d0c3a2 --- /dev/null +++ b/src/main/resources/templates/login.html @@ -0,0 +1,109 @@ + + + + + Login + + + + + + + + + + + + + + + +
+ + + +

Back to Homepage

+ +
+ + + + \ No newline at end of file diff --git a/src/main/resources/templates/user/addvoc_form.html b/src/main/resources/templates/user/addvoc_form.html new file mode 100644 index 0000000..4796ca3 --- /dev/null +++ b/src/main/resources/templates/user/addvoc_form.html @@ -0,0 +1,52 @@ + + + + + Add Vocabulary + + + + + + + + + + + + + + + +
+ +
+
+ Your vocabularies have been updated. +
+
+ +
+ +
Add new Vocabulary
+ +
+ +
+ +
+ +
+ + +

back

+
+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/user/edit_vocab.html b/src/main/resources/templates/user/edit_vocab.html new file mode 100644 index 0000000..c3bdbe4 --- /dev/null +++ b/src/main/resources/templates/user/edit_vocab.html @@ -0,0 +1,47 @@ + + + + + Edit Vocabularies + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
IDGerman VocabularyEnglish TranslationActions
+ Edit + +
+ + back + +
+ + + \ No newline at end of file diff --git a/src/main/resources/templates/user/index.html b/src/main/resources/templates/user/index.html new file mode 100644 index 0000000..b3d2e03 --- /dev/null +++ b/src/main/resources/templates/user/index.html @@ -0,0 +1,61 @@ + + + + + Dashboard + + + + + + + + + + + + + + +
+ + +

Welcome

+

+ +
+
+ +

Overview of your Vocabularies

+
+
+ + + + + + + + + + + + + +
German VocabularyEnglish Translation
+
+ +

Add Vocabulary

+ Add vocabulary + +

Edit Vocabulary

+ +

Study Interface

+ +

Logout

+ +
+ + \ No newline at end of file diff --git a/src/main/resources/templates/user/study_interface.html b/src/main/resources/templates/user/study_interface.html new file mode 100644 index 0000000..f8d23be --- /dev/null +++ b/src/main/resources/templates/user/study_interface.html @@ -0,0 +1,32 @@ + + + + + Dashboard + + + + + + + + + + + + + + +
+ + +

Choose the displayed language!

+

+ German + English + +
+ + \ No newline at end of file diff --git a/src/main/resources/templates/user/study_interface_english.html b/src/main/resources/templates/user/study_interface_english.html new file mode 100644 index 0000000..17747bc --- /dev/null +++ b/src/main/resources/templates/user/study_interface_english.html @@ -0,0 +1,66 @@ + + + + + StudyInterfaceEnglish + + + + + + + + + + + + + + +
+ +
+
+ +

Click words to reveal them.

+
+
+ + + + + + + + + + + + + +
English Vocabulary
+ + +
+
+ + +

back

+ +
+ + + \ No newline at end of file diff --git a/src/main/resources/templates/user/study_interface_german.html b/src/main/resources/templates/user/study_interface_german.html new file mode 100644 index 0000000..42d2a9b --- /dev/null +++ b/src/main/resources/templates/user/study_interface_german.html @@ -0,0 +1,67 @@ + + + + + StudyInterfaceGerman + + + + + + + + + + + + + + +
+ + +
+
+ +

Click words to reveal them.

+
+
+ + + + + + + + + + + + + +
German Vocabulary
+ + +
+
+ + +

back

+ +
+ + + \ No newline at end of file diff --git a/src/test/java/com/vocabularytrainer/project/VocabularyTrainerApplicationTests.java b/src/test/java/com/vocabularytrainer/project/VocabularyTrainerApplicationTests.java new file mode 100644 index 0000000..372a1cb --- /dev/null +++ b/src/test/java/com/vocabularytrainer/project/VocabularyTrainerApplicationTests.java @@ -0,0 +1,13 @@ +package com.vocabularytrainer.project; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class VocabularyTrainerApplicationTests { + + @Test + void contextLoads() { + } + +} From 3253c22ce524fea6de0813ce53975f6d0e3eddb4 Mon Sep 17 00:00:00 2001 From: 16loitze Date: Wed, 1 Apr 2020 12:52:39 +0200 Subject: [PATCH 59/74] Resolved Merge Conflicts --- mvnw | 310 ------------------ .../project/controller/MVCController.java | 180 ---------- .../project/db/VocabularyRepository.java | 31 -- src/main/resources/application.properties | 4 - src/main/resources/templates/user/index.html | 61 ---- 5 files changed, 586 deletions(-) delete mode 100644 mvnw delete mode 100644 src/main/java/com/vocabularytrainer/project/controller/MVCController.java delete mode 100644 src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java delete mode 100644 src/main/resources/application.properties delete mode 100644 src/main/resources/templates/user/index.html diff --git a/mvnw b/mvnw deleted file mode 100644 index a16b543..0000000 --- a/mvnw +++ /dev/null @@ -1,310 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` - fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi -else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` - fi - - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" - else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl -o "$wrapperJarPath" "$jarUrl" -f - else - curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f - fi - - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaClass=`cygpath --path --windows "$javaClass"` - fi - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR -fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` -fi - -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java deleted file mode 100644 index f0b8a32..0000000 --- a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java +++ /dev/null @@ -1,180 +0,0 @@ -package com.vocabularytrainer.project.controller; - -import com.vocabularytrainer.project.db.VocabularyEntries; -import com.vocabularytrainer.project.db.VocabularyRepository; // Repository Interface - -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; - -import org.springframework.security.core.userdetails.UserDetails; - -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.servlet.ModelAndView; - - -@Controller -public class MVCController { - - /* Setup access Database Repository Interface */ - VocabularyRepository vocabularyRepository; - public MVCController(VocabularyRepository vocabularyRepository) { - this.vocabularyRepository = vocabularyRepository; - } - - /* Welcome Page */ - @GetMapping("/") - public String root() { - return "index"; - } - - /* User Interface: Dashboard */ - @GetMapping("/user") - public String userIndex(Model model) { - - // tell the thymeleaf which user is logged in - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - UserDetails userDetails = (UserDetails) authentication.getPrincipal(); - - model.addAttribute("current_user", userDetails.getUsername()); - - // get the Query to show current vocabulary entries of user x - model.addAttribute("overview", this.vocabularyRepository.showAllVocabularyFromUserX(userDetails.getUsername())); - - return "user/index"; - } - - /* User StudyInterface in German*/ - @GetMapping("/user/studyInterfaceGerman") - public String userStudyInterfaceGerman(Model model) { - - // tell the thymeleaf which user is logged in - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - UserDetails userDetails = (UserDetails) authentication.getPrincipal(); - - model.addAttribute("current_user", userDetails.getUsername()); - - // get the Query to show current vocabulary entries of user x - model.addAttribute("overview", this.vocabularyRepository.showAllVocabularyFromUserX(userDetails.getUsername())); - - return "user/study_interface_german"; - } - - @GetMapping("/user/studyInterfaceEnglish") - public String userStudyInterfaceEnglish(Model model) { - - // tell the thymeleaf which user is logged in - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - UserDetails userDetails = (UserDetails) authentication.getPrincipal(); - - model.addAttribute("current_user", userDetails.getUsername()); - - // get the Query to show current vocabulary entries of user x - model.addAttribute("overview", this.vocabularyRepository.showAllVocabularyFromUserX(userDetails.getUsername())); - - return "user/study_interface_english"; - } - - - @GetMapping("/user/studyInterface") - public String userStudyInterface(Model model) { - - // tell the thymeleaf which user is logged in - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - UserDetails userDetails = (UserDetails) authentication.getPrincipal(); - - model.addAttribute("current_user", userDetails.getUsername()); - - return "user/study_interface"; - } - - - /* Show the All vocabularies in edit_vocab.html*/ - @GetMapping("user/editvoc") - public String getUserEditVocabulary(Model model) { - - // tell the thymeleaf which user is logged in - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - UserDetails userDetails = (UserDetails) authentication.getPrincipal(); - - // get the Query to show current vocabulary entries of user x - model.addAttribute("overview", this.vocabularyRepository.showAllVocabularyFromUserX(userDetails.getUsername())); - - return "user/edit_vocab"; - } - - - // user/editvoc/edit+${entry.id}} - @GetMapping("/edit/{id}") - public ModelAndView showEditProductPage(@PathVariable(name = "id") int id) { - ModelAndView mav = new ModelAndView("edit_product"); - - VocabularyEntries vocabularyEntries = this.vocabularyRepository.getEntryBasedOnId(id); - - - System.out.println(vocabularyEntries.getId()); - - - // Product product = service.get(id); - //mav.addObject("product", product); - - - - return mav; - } - - /* Show the Form and Let the user enter stuff */ - @GetMapping("/user/addvoc") - // Model -> Thymeleaf model to access html "variables" - public String getUserAddVocabulary(Model model) { - - - VocabularyEntries vocabularyEntries = new VocabularyEntries(); - - - // Thymeleaf-variable for "get-form" - model.addAttribute("addvoc", vocabularyEntries); - - return "user/addvoc_form"; - } - - - - /* Submit Data from Form using POST */ - @PostMapping("/user/addvoc") - public String submitUserAddVocabulary(VocabularyEntries vocabularyEntries, Model model) { - - model.addAttribute("submitted", true); - - // get current user - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - UserDetails userDetails = (UserDetails) authentication.getPrincipal(); - - vocabularyEntries.setUser(userDetails.getUsername()); - - // save result in our Repository Interface - VocabularyEntries result = this.vocabularyRepository.save(vocabularyEntries); - - // Thymeleaf-variable for "post-form" - add it - model.addAttribute("addvoc", result); - - /// TODO: Fix redirecting - return "user/addvoc_form"; - } - - /* Login Page */ - @GetMapping("/login") - public String login() { - return "login"; - } - - /* Access Denied Page */ - @GetMapping("/request-denied") - public String accessDenied() { - return "access-denied-page"; - } -} diff --git a/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java b/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java deleted file mode 100644 index 29ca3df..0000000 --- a/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.vocabularytrainer.project.db; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -import java.util.List; - -// with this, we can make the connection to the database - "connection layer" -// JPA = Java Persistence API for managing relational data (=Database) -// We use JPQL (="SQL" queries in Java) to make queries -public interface VocabularyRepository extends JpaRepository { - - /* Queries */ - - @Query(value="SELECT u FROM VocabularyEntries u") - List showAllVocabulary(); - - @Query(value="SELECT x FROM VocabularyEntries x WHERE x.user = :paruser") - // using Java Template we save everything in there ad use as Data Type the table - List showAllVocabularyFromUserX( - @Param("paruser") String paruser // Parameter Handling for JPQL-Style queries - ); - - @Query(value="SELECT i FROM VocabularyEntries i WHERE i.id = :parid") - VocabularyEntries getEntryBasedOnId( - @Param("parid") int parid - ); - - -} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index 640172a..0000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1,4 +0,0 @@ -spring.jpa.hibernate.ddl-auto=update -spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_vocabularytrainer?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false -spring.datasource.username=student -spring.datasource.password=student \ No newline at end of file diff --git a/src/main/resources/templates/user/index.html b/src/main/resources/templates/user/index.html deleted file mode 100644 index b3d2e03..0000000 --- a/src/main/resources/templates/user/index.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - Dashboard - - - - - - - - - - - - - - -
- - -

Welcome

-

- -
-
- -

Overview of your Vocabularies

-
-
- - - - - - - - - - - - - -
German VocabularyEnglish Translation
-
- -

Add Vocabulary

- Add vocabulary - -

Edit Vocabulary

- -

Study Interface

- -

Logout

- -
- - \ No newline at end of file From a7daa192756926d23412d196d74c22e9b8d8ffd3 Mon Sep 17 00:00:00 2001 From: 16loitze Date: Wed, 1 Apr 2020 12:55:43 +0200 Subject: [PATCH 60/74] Resolved Merge Conflicts --- .../resources/templates/user/edit_vocab.html | 47 ------------------- 1 file changed, 47 deletions(-) delete mode 100644 src/main/resources/templates/user/edit_vocab.html diff --git a/src/main/resources/templates/user/edit_vocab.html b/src/main/resources/templates/user/edit_vocab.html deleted file mode 100644 index c3bdbe4..0000000 --- a/src/main/resources/templates/user/edit_vocab.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - Edit Vocabularies - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
IDGerman VocabularyEnglish TranslationActions
- Edit - -
- - back - -
- - - \ No newline at end of file From 7004ca6248a015e593173159afd38debdcb110eb Mon Sep 17 00:00:00 2001 From: Simon Ranftl Date: Wed, 1 Apr 2020 13:21:15 +0200 Subject: [PATCH 61/74] LANG-003 Added Edit page [LJ, RS] --- .gitignore | 4 ++++ .../vocabularytrainer/project/controller/MVCController.java | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 090839d..065d226 100644 --- a/.gitignore +++ b/.gitignore @@ -103,3 +103,7 @@ build/ ### VS Code ### .vscode/ + + +# application.properties +src/main/resources/application.properties \ No newline at end of file diff --git a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java index f0b8a32..e6c782c 100644 --- a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java +++ b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java @@ -107,8 +107,7 @@ public String getUserEditVocabulary(Model model) { return "user/edit_vocab"; } - - // user/editvoc/edit+${entry.id}} + @GetMapping("/edit/{id}") public ModelAndView showEditProductPage(@PathVariable(name = "id") int id) { ModelAndView mav = new ModelAndView("edit_product"); From b4a40792dcc09915933f5f6db5165f0291fe59f8 Mon Sep 17 00:00:00 2001 From: Simon Ranftl Date: Wed, 1 Apr 2020 17:20:59 +0200 Subject: [PATCH 62/74] LANG-003 Added Edit page [LJ, RS] --- docs/Documentation.md | 51 +++++++++++++++---- .../project/controller/MVCController.java | 2 +- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/docs/Documentation.md b/docs/Documentation.md index cf85149..4730bb3 100644 --- a/docs/Documentation.md +++ b/docs/Documentation.md @@ -4,7 +4,7 @@ ### Requirements -* Java SDK 1.8 or higher +* Java (obviously) * JDK 8 or higher * MySQL 5.6 or higher * JetBrains IntelliJ Ultimate IDE (optional but recommended) @@ -17,10 +17,11 @@ $ java -jar target/project-0.0.1-SNAPSHOT.jar ``` - * But make sure that you edited your [MySQL configurations](#adding-mysql-to-our-project) beforehand. + * Be sure that you edited your [MySQL configurations](#adding-mysql-to-our-project) beforehand. -### Building and Running +### Building and Running in IntelliJ +* (If you don't use IntelliJ, see under [Requirements](#requirements) how you can build/run this application) * Clone/Download this repository * Start IntelliJ and click 'Open' * Navigate in your cloned repo folder, choose the `pom.xml` file and click 'ok' @@ -32,11 +33,17 @@ #### Adding MySQL to our Project -* Download and Install MySQL [Community](https://dev.mysql.com/downloads/mysql/) and [Workbench](https://www.mysql.com/products/workbench/), setup everything +* Download and Install MySQL, setup everything in the workbench (create user `student` and password `student` for simplicity) and start the server (default port is 3306). -* Add the following to `src/recources/application.properties`: +* Login into MySQL: `mysql -u student -p` + +* Create the database: `CREATE DATABASE db_vocabularytrainer;` + +* Grant access: `GRANT ALL PRIVILEGES ON * . * TO 'student'@'localhost';` + +* In the project, add the following to `src/recources/application.properties`: ``` spring.jpa.hibernate.ddl-auto=update @@ -79,7 +86,7 @@ src | +- VocabularyTrainerApplication.java | | | +- db - | | +- VocabularyAddEntries.java + | | +- VocabularyEntries.java | | +- VocabularyRepository.java | | | +- controller @@ -111,6 +118,15 @@ src ``` +## Frameworks, Templates, Technologies etc. used + +* Maven +* Spring Boot +* Thymeleaf +* MySQL +* Hibernate +* Bootstrap + ## `pom.xml` configuration and dependencis ```xml @@ -210,10 +226,27 @@ src ![img_fix_cannot_build](fix_cannot_build.jpeg "picture") +### MySQL related errors +If you get a timezone error, replace your application.entries with the following: -### Useful Spring Boot, Thymeleaf, Bootstrap Get Started-Links - - +``` +spring.jpa.hibernate.ddl-auto=update +spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_vocabularytrainer?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false +spring.datasource.username=student +spring.datasource.password=student +``` +### Useful Spring Boot, Thymeleaf, Bootstrap Get Started-Links +* [Setup IntelliJ with Spring Boot using Spring Initializr](https://medium.com/danielpadua/java-spring-boot-intellij-idea-b919b0097a0) (small correction: don't import, just open the project) +* [Basic Tutorial using Spring Boot](https://spring.io/guides/gs/spring-boot/) +* [Some Interesting IntelliJ IDE Features](https://www.jetbrains.com/help/idea/spring-boot.html) +* [Using Spring Boot Annotations and explaining how they work](https://www.javatpoint.com/spring-boot-annotations) +* [Spring Boot MySQL example](https://spring.io/guides/gs/accessing-data-mysql/) +* [Great step by step tutorial using Spring Boot, Database and Thymeleaf](https://www.vogella.com/tutorials/SpringBoot/article.html) (!!! Highly recommend !!!) +* [Thymeleaf Getting Started Refernces](https://www.javatpoint.com/spring-boot-thymeleaf-view) +* [Explaination, what a Template (like Thymeleaf) is for](https://hackernoon.com/java-template-engines-ef84cb1025a4) +* [How to use @Queries in Spring Boot](https://www.baeldung.com/spring-data-jpa-query) +* [Using Spring Boot Securityto create a Login System](https://memorynotfound.com/spring-boot-spring-security-thymeleaf-form-login-example/) +* [Bootstrap Tutorial Reference](https://www.w3schools.com/bootstrap4/) diff --git a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java index e6c782c..2d2e07b 100644 --- a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java +++ b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java @@ -107,7 +107,7 @@ public String getUserEditVocabulary(Model model) { return "user/edit_vocab"; } - + @GetMapping("/edit/{id}") public ModelAndView showEditProductPage(@PathVariable(name = "id") int id) { ModelAndView mav = new ModelAndView("edit_product"); From b68d3567c5c66380ee71b789da6c8ff7b5287983 Mon Sep 17 00:00:00 2001 From: Andreas Hiess Date: Tue, 21 Apr 2020 19:24:49 +0200 Subject: [PATCH 63/74] Merge branch 'develop' of https://github.com/sw20-tug/ASD-Morning-4 into develop # Conflicts: # .gitignore # README.md --- pom.xml | 11 ++ .../project/VocabularyTrainerConfigTests.java | 36 +++++ .../MVCControllerNoSecurityTest.java | 62 ++++++++ .../project/controller/MVCControllerTest.java | 135 ++++++++++++++++++ 4 files changed, 244 insertions(+) create mode 100644 src/test/java/com/vocabularytrainer/project/VocabularyTrainerConfigTests.java create mode 100644 src/test/java/com/vocabularytrainer/project/controller/MVCControllerNoSecurityTest.java create mode 100644 src/test/java/com/vocabularytrainer/project/controller/MVCControllerTest.java diff --git a/pom.xml b/pom.xml index cdb1b1a..83eadea 100644 --- a/pom.xml +++ b/pom.xml @@ -34,14 +34,25 @@ org.springframework.boot spring-boot-starter-test test + + + mysql mysql-connector-java diff --git a/src/test/java/com/vocabularytrainer/project/VocabularyTrainerConfigTests.java b/src/test/java/com/vocabularytrainer/project/VocabularyTrainerConfigTests.java new file mode 100644 index 0000000..129b80e --- /dev/null +++ b/src/test/java/com/vocabularytrainer/project/VocabularyTrainerConfigTests.java @@ -0,0 +1,36 @@ +package com.vocabularytrainer.project; + +import static org.junit.Assert.*; + +import com.vocabularytrainer.project.controller.MVCController; +import com.vocabularytrainer.project.db.VocabularyRepository; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; + +/** + * Tests if Spring is configured and all dependencies (db, etc.) are accessible. + */ +@SpringBootTest +public class VocabularyTrainerConfigTests { + + @Autowired + private MVCController controller; + + @Autowired + private VocabularyRepository vocabularyRepository; + + @Test + public void testLoadContext() throws Exception { + assertNotNull(this.controller); + assertNotNull(this.vocabularyRepository); + } + + + @Test + public void testSecurityContext() throws Exception { + assertNotNull(SecurityContextHolder.getContext()); + } +} diff --git a/src/test/java/com/vocabularytrainer/project/controller/MVCControllerNoSecurityTest.java b/src/test/java/com/vocabularytrainer/project/controller/MVCControllerNoSecurityTest.java new file mode 100644 index 0000000..b99cee3 --- /dev/null +++ b/src/test/java/com/vocabularytrainer/project/controller/MVCControllerNoSecurityTest.java @@ -0,0 +1,62 @@ +package com.vocabularytrainer.project.controller; + + +import com.vocabularytrainer.project.db.VocabularyEntries; +import com.vocabularytrainer.project.db.VocabularyRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.ui.Model; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +@SpringBootTest +public class MVCControllerNoSecurityTest { + + + @Autowired + private MVCController controller; + + @MockBean + private VocabularyRepository vocabularyRepository; + + @Mock + private Model model; + + + // global test variables + private static final String username = "John Test"; + + + @BeforeEach + public void beforeEach() { + // init mocks + MockitoAnnotations.initMocks(this); + + // database setup + this.vocabularyRepository.deleteAll(); + } + + + @Test + public void testGetUserAddVocabulary() { + + this.controller.getUserAddVocabulary(this.model); + + ArgumentCaptor argument = ArgumentCaptor.forClass(VocabularyEntries.class); + verify(this.model, times(1)).addAttribute(any(), argument.capture()); + + assertEquals(0, argument.getValue().getId()); + assertEquals(null, argument.getValue().getUser()); + + } + +} diff --git a/src/test/java/com/vocabularytrainer/project/controller/MVCControllerTest.java b/src/test/java/com/vocabularytrainer/project/controller/MVCControllerTest.java new file mode 100644 index 0000000..030785a --- /dev/null +++ b/src/test/java/com/vocabularytrainer/project/controller/MVCControllerTest.java @@ -0,0 +1,135 @@ +package com.vocabularytrainer.project.controller; + + +import com.vocabularytrainer.project.db.VocabularyEntries; +import com.vocabularytrainer.project.db.VocabularyRepository; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.ui.Model; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +@SpringBootTest +public class MVCControllerTest { + + + @Autowired + private MVCController controller; + + @MockBean + private VocabularyRepository vocabularyRepository; + + @Mock + private Model model; + + // security mocks start + @Mock + private SecurityContext securityContext; + @Mock + private Authentication authentication; + @Mock + private UserDetails userDetails; + // security mocks end + + + // global test variables + private static final String username = "John Test"; + + + @BeforeEach + public void beforeEach() { + // init mocks + MockitoAnnotations.initMocks(this); + + + // spring security setup + when(this.securityContext.getAuthentication()).thenReturn(this.authentication); + when(this.authentication.getPrincipal()).thenReturn(this.userDetails); + when(this.userDetails.getUsername()).thenReturn(username); + + SecurityContextHolder.setContext(this.securityContext); + + // database setup + this.vocabularyRepository.deleteAll(); + } + + /** + * Verify security context calls + */ + @AfterEach + public void afterEach() { + verify(this.securityContext, times(1)).getAuthentication(); + verify(this.authentication, times(1)).getPrincipal(); + } + + @Test + public void testUserIndexEmpty() { + this.controller.userIndex(this.model); + + verify(this.model, times(2)).addAttribute(any(), any()); + verify(this.model, times(1)).addAttribute("current_user", username); + verify(this.model, times(1)).addAttribute("overview", new ArrayList()); + } + + + @Test + public void testUserIndex() { + + //setup db start + VocabularyEntries ve = new VocabularyEntries(); + List veList = new ArrayList<>(); + veList.add(ve); + + when(this.vocabularyRepository.showAllVocabularyFromUserX(username)).thenReturn(veList); + //setup db end + + // test controller + this.controller.userIndex(this.model); + + verify(this.model, times(2)).addAttribute(any(), any()); + verify(this.model, times(1)).addAttribute("current_user", username); + verify(this.model, times(1)).addAttribute("overview", veList); + + + // verify db + verify(this.vocabularyRepository, times(1)).showAllVocabularyFromUserX(username); + + } + + + @Test + public void testSubmitUserAddVocabulary() { + + //setup db start + VocabularyEntries ve = new VocabularyEntries(); + when(this.vocabularyRepository.save(ve)).thenReturn(ve); + //setup db end + + + this.controller.submitUserAddVocabulary(ve, this.model); + + verify(this.model, times(1)).addAttribute("submitted", true); + assertEquals(username, ve.getUser()); + verify(this.vocabularyRepository, times(1)).save(ve); + + verify(this.model, times(1)).addAttribute("addvoc", ve); + } + + + +} From e0e82700a725b79b2f6c8688c7fe80bcc6420e54 Mon Sep 17 00:00:00 2001 From: - - Date: Wed, 22 Apr 2020 08:24:43 +0200 Subject: [PATCH 64/74] Meine Einstellungen zur Datenbankverbindung. --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index a0904eb..640172a 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,4 +1,4 @@ spring.jpa.hibernate.ddl-auto=update -spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_vocabularytrainer +spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_vocabularytrainer?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false spring.datasource.username=student spring.datasource.password=student \ No newline at end of file From 794b78e1c0d6d84008ff8819f967b2c8d6f84913 Mon Sep 17 00:00:00 2001 From: 16loitze <62160103+16loitze@users.noreply.github.com> Date: Wed, 22 Apr 2020 11:08:23 +0200 Subject: [PATCH 65/74] Updated the readme file --- README.md | 239 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 176 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 979df99..7b2ebb3 100644 --- a/README.md +++ b/README.md @@ -1,71 +1,184 @@ -# ASD: Morning 4 +# Protocol for Agile Meetings: Group ASD-Morning-4 -## Vocabulary Trainer +- - - - -Vocabulary trainer is a dictionary and training application which allows its users to study and test -vocabulary in a foreign language. +# Planning Meeting: Sprint 1 -### Setup +### ASD: Morning 4 - Meeting #1 -[Please see here for setup instructions](docs/Documentation.md#setup-instructions) +* Date: 18.03.2020 +* Time: 08:00 - 10:30 +* Type of meeting: Planning, Setup Github Workflow, Label Issues/Sprints +* Attendees: All +* Tools used to conduct the meeting: WhatsApp, Slack and Teamspeak -### Meeting Notes +### Purpose +* Discussed the tools we’ll use for remote work. +* Discussed the technology to use for the project. +* Development environment setup for every colleague. +* Planning: Labeling and rating all issues and assigning issues for Sprint 1. -___18.03.2020___ +### Meeting Protocol -* Using Teamspeak for Voice Calls -* WhatsApp, Slack and Teamspeak chat for messaging -* Setup GitHub Workflow with IntelliJ IDE - * GitHub Login, Fork, Push, Commits, Pull Requests -* Added .gitignore and updated README.md -* Web Application using Java Spring Boot as backend server framework and MySQL database (queries vocabularies). On the Fronted-Side we use HTML. -* TODO until next week: - * Read Java Spring Boot docs and setup a Spring Boot Test Project - * Read MySQL docs and setup everything - * Install Teamviewer for collaborative programming - * Split into groups and create branch for each Issue. - -___25.03.2020___ - -* Setting Up the Framework for every participant. -* Setting goals for Sprint 2 - * Issues 003 - 007 -* Organizing pair-programming Teams - * Teamviewer is used for this point -* Start implementing next issues -* Planning to introduce Unit-Tests - -* Planing resume: - * Creating branches per Issue +We decided to use the following software/tools: + +* Teamspeak for Voice Calls +* WhatsApp, Slack and Teamspeak chat for messaging +* Teamviewer for Pair Programming. +* Java Spring Boot with Thymeleaf, Hibernate and MySQL. + +### Commitment + +* Everyone did a test commit to ensure the workflow is guaranteed and working. + +- - - - + +# Sprint 1 Work Progress Meeting + +## ASD Morning 4 - Meeting #2 + +* Date: 25.03.2020 +* Time: 08:00 - 09:00 +* Type of meeting: Planning +* Attendees: All +* Tools used to conduct the meeting: Slack and Teamspeak + +### Purpose + +* Helping Teammates with the Framework. +* Setting up the Framework for every colleague who had issues. +* Creating the user stories and setting the goals for Issues. + +### Meeting protocol +### Troubleshooting + +* Solving common problem with SQL and Springboot. + + * Setting as maven build after pulling. + * MySQL: Timezone-problem. + +Planning + +* Setting goals for Sprint 2 + + * Issues 003 - 007 + +* Organizing pair-programming Teams + + * Teamviewer is used for this point + +* Started implementing next issues +* Unit Tests. + +Clarification + +* Discussion about Issues. + + * How to rate issues accordingly? + * Which issues are related to one and another? + +* Discussion about using branches per issues and git workflow. + +### Commitment + +* First Prototype implemented, issues closed: LANG_000, LANG_001, LANG_002 + +- - - - + +# Sprint 1 Review Meeting + +## ASD Morning 4 - Meeting #3 + +* Date: 01.04.2020 +* Time: 08:00 - 09:50 +* Type of meeting: Sprint Review, The Retrospective +* Attendees: All +* Tools used to conduct the meeting: Teamspeak, Teamviewer + +### Purpose +* Asking Questions: + + * What is TODO in next Sprint? + * Are we in time? + * What to Improve? + +* Recap of last Sprint +* Did the Group communicate enough? (especially given the circumstances of COVID) +Meeting Protocol + +_@Issue 000_ +Development environment is working fine and we think we made a great choice with the technology (Spring Boot, Thymeleaf, Hibernate, Bootstrap, MySQL). + +_@Issue 001_ +Database is also running. We can start to implement next Issues (since we are ahead of time): + +* things that go well according to all members: + + * all closed issues are working well + * Framework is perfect for our implementation + +* things to improve: + + * focus more on branches + * focus more on the agile workflow + * pay attention to naming conventions in GitHub + * pay attention to the "coding standard" -___01.04.2020___ - - ASD Morning - Meeting #3 - Date: 01.04.2020 - Time: 08:00 - 08:50 - Type of meeting: The Retro(spective) - Attendees: Beinhundner, Felgitscher, Hiess, Loitzenbauer, - Prüll, Ranftl, Wartinger, Weinhandl - Tools used to conduct the meeting: TeamSpeak - - * things that go well: - * all closed issues are working well - - * things to improve: - * focus more on branches - * focus more on the agile workflow - * pay attention to naming conventions - * pay attention to the "coding standard" - * code should be easy to read - * useful comments - - * next deadline 29.1. 11:00 - * Unit Test Hiess & Wartinger - * LAAG_003 Loitzenbauer & Ranftl - * LAAG_004 Prüll & Weinhandl - * LAAG_005 Beinhunder & Prüll - * LAAG_006 - * LAAG_007 Felgitscher & Weinhandl - - - +Also: + +* code should be easy to read +* use more comments on parts that are not obvious. + +_Agreed deadline for Sprint 2: 29.04.2020 11:00_ + +Designated Pair Programming Groups: + +* Unit Testing Hieß & Wartinger +* LANG_003 Loitzenbauer & Ranftl +* LANG_004 Prüll & Weinhandl +* LANG_005 Beinhunder & Prüll +* LANG_006 (open) +* LANG_007 Felgitscher & Weinhandl + +### Commitment + +* Sprint 1 was released. +* Added LANG_004 implementation of Study Interface. + +- - - - +  +# Planning Meeting: Sprint 2 +## ASD Morning 4 - Meeting #4 + +Date: 22.04.2020 +Time: 08:00 - 11:00 +Type of meeting: Daily Meeting, Code Review +Attendees: All +Tools used to conduct the meeting: Slack and Teamspeak + +### Purpose + +* Discussions Updates. +* How far are the Issues implemented? +* Does anyone need help? +* Starting to use Code reviews. +* Discussing Feedback + +### Meeting Protocol + +* The Pair programming worked out fine. +* Issues are almost done. +* No one needs help for now. +* Always Codereview asynchrone for pull requests. (Person not part of the Pair-Programming team) +* Synchronous reviews are done with Pair-Programming. +* After every Sprint, critical parts of the Code will be reviewed with the Once-In-A-While code review method. +* Weinhandl did the first Once-In-A-While code review for the last sprint in retrospective. +Taking Feedback from Tutors into account. +More focus on agile events and practices! + +### Commitment + +* Added Junit and Mockito Tests. + + + From 54a72afdad5a9a0c84d8a9d18f7e2d05f4d03f5f Mon Sep 17 00:00:00 2001 From: eder13 Date: Wed, 22 Apr 2020 12:06:28 +0200 Subject: [PATCH 66/74] LANG-003 added edit page [LJ, RS] --- .gitignore | 8 +++- .../project/controller/MVCController.java | 20 ++++------ .../project/db/VocabularyRepository.java | 2 - .../resources/templates/user/edit_vocab.html | 2 +- .../templates/user/edit_vocab_entry.html | 39 +++++++++++++++++++ 5 files changed, 53 insertions(+), 18 deletions(-) create mode 100644 src/main/resources/templates/user/edit_vocab_entry.html diff --git a/.gitignore b/.gitignore index 065d226..e4805eb 100644 --- a/.gitignore +++ b/.gitignore @@ -105,5 +105,9 @@ build/ .vscode/ -# application.properties -src/main/resources/application.properties \ No newline at end of file +# application.properties - depends on settings of the user etc. +src/main/resources/application.properties + + +# .DS_Store files +.DS_Store \ No newline at end of file diff --git a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java index 2d2e07b..2314616 100644 --- a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java +++ b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java @@ -64,6 +64,7 @@ public String userStudyInterfaceGerman(Model model) { return "user/study_interface_german"; } + /* User StudyInterface in English */ @GetMapping("/user/studyInterfaceEnglish") public String userStudyInterfaceEnglish(Model model) { @@ -80,6 +81,7 @@ public String userStudyInterfaceEnglish(Model model) { } + /* General StudyInterface where user selects language */ @GetMapping("/user/studyInterface") public String userStudyInterface(Model model) { @@ -107,23 +109,15 @@ public String getUserEditVocabulary(Model model) { return "user/edit_vocab"; } - - @GetMapping("/edit/{id}") - public ModelAndView showEditProductPage(@PathVariable(name = "id") int id) { - ModelAndView mav = new ModelAndView("edit_product"); + @GetMapping("user/editvoc/edit/{id}") + public String showEditProductPage(@PathVariable(name = "id") int id, Model model) { VocabularyEntries vocabularyEntries = this.vocabularyRepository.getEntryBasedOnId(id); + //System.out.println(vocabularyEntries.getId()); + model.addAttribute("edit_vocab_entry", vocabularyEntries); - System.out.println(vocabularyEntries.getId()); - - - // Product product = service.get(id); - //mav.addObject("product", product); - - - - return mav; + return "user/edit_vocab_entry"; } /* Show the Form and Let the user enter stuff */ diff --git a/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java b/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java index 29ca3df..3a465d3 100644 --- a/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java +++ b/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java @@ -26,6 +26,4 @@ List showAllVocabularyFromUserX( VocabularyEntries getEntryBasedOnId( @Param("parid") int parid ); - - } diff --git a/src/main/resources/templates/user/edit_vocab.html b/src/main/resources/templates/user/edit_vocab.html index 5cfc91d..8f4081b 100644 --- a/src/main/resources/templates/user/edit_vocab.html +++ b/src/main/resources/templates/user/edit_vocab.html @@ -32,7 +32,7 @@ - Edit + Edit diff --git a/src/main/resources/templates/user/edit_vocab_entry.html b/src/main/resources/templates/user/edit_vocab_entry.html new file mode 100644 index 0000000..344294c --- /dev/null +++ b/src/main/resources/templates/user/edit_vocab_entry.html @@ -0,0 +1,39 @@ + + + + + Edit Vocabulary Entry + + + + + + + + + + + + +
+ +
+ +         + + + + + +
+ + abort + +
+ + + \ No newline at end of file From 9010df50ddf4bacfcac5cc4d58dfe9e84e7e7b9e Mon Sep 17 00:00:00 2001 From: Alexander Beinhundner Date: Wed, 29 Apr 2020 07:49:15 +0200 Subject: [PATCH 67/74] repo reset --- .gitignore | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3f68ee9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,107 @@ +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +## Import from Spring Initializr Web .gitignore + +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/** +!**/src/test/** + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ + +### VS Code ### +.vscode/ + +src/main/resources/application.properties \ No newline at end of file From d6d131cd4b3714e416a03826cb7d3e443e881807 Mon Sep 17 00:00:00 2001 From: Alexander Beinhundner Date: Wed, 29 Apr 2020 08:07:32 +0200 Subject: [PATCH 68/74] LANG 005 --- src/main/resources/templates/user/index.html | 95 ++++++++++++++++++-- 1 file changed, 87 insertions(+), 8 deletions(-) diff --git a/src/main/resources/templates/user/index.html b/src/main/resources/templates/user/index.html index bf0dca2..696d43a 100644 --- a/src/main/resources/templates/user/index.html +++ b/src/main/resources/templates/user/index.html @@ -7,6 +7,13 @@ + + + + + + + @@ -15,10 +22,20 @@ + + +
@@ -29,21 +46,47 @@

+
+
+ +
+
+

+
+ +
+
- +
+ - - + + + + - + + - - - - + + + + + + + + +
German VocabularyEnglish TranslationGerman VocabularyEnglish TranslationTypRating
@@ -56,4 +99,40 @@

Add Vocabulary

+ + + \ No newline at end of file From 3a45a2687a03e7fbd887e051e189b863578dabb1 Mon Sep 17 00:00:00 2001 From: eder13 Date: Wed, 29 Apr 2020 09:54:33 +0200 Subject: [PATCH 69/74] LANG-003 implemented edit function [LJ, RS] --- .../project/controller/MVCController.java | 26 ++++++++++++++++++- .../templates/user/edit_vocab_entry.html | 22 +++++++++++++--- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java index 2314616..07d57fd 100644 --- a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java +++ b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java @@ -10,6 +10,7 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -112,6 +113,8 @@ public String getUserEditVocabulary(Model model) { @GetMapping("user/editvoc/edit/{id}") public String showEditProductPage(@PathVariable(name = "id") int id, Model model) { + model.addAttribute("submitted", false); + VocabularyEntries vocabularyEntries = this.vocabularyRepository.getEntryBasedOnId(id); //System.out.println(vocabularyEntries.getId()); @@ -120,6 +123,28 @@ public String showEditProductPage(@PathVariable(name = "id") int id, Model model return "user/edit_vocab_entry"; } + + @PostMapping("user/editvoc/edit/{id}") + public String submitEditedVocabularyEntry(@PathVariable(name = "id") int id, VocabularyEntries vocabularyEntries, Model model) + { + model.addAttribute("submitted", true); + + // get current user + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + vocabularyEntries.setUser(userDetails.getUsername()); + + // save result in our Repository Interface + VocabularyEntries result = this.vocabularyRepository.save(vocabularyEntries); + + // Thymeleaf-variable for "post-form" - add it + model.addAttribute("edit_vocab_entry", result); + + return "user/edit_vocab_entry"; + } + + /* Show the Form and Let the user enter stuff */ @GetMapping("/user/addvoc") // Model -> Thymeleaf model to access html "variables" @@ -136,7 +161,6 @@ public String getUserAddVocabulary(Model model) { } - /* Submit Data from Form using POST */ @PostMapping("/user/addvoc") public String submitUserAddVocabulary(VocabularyEntries vocabularyEntries, Model model) { diff --git a/src/main/resources/templates/user/edit_vocab_entry.html b/src/main/resources/templates/user/edit_vocab_entry.html index 344294c..4fa80de 100644 --- a/src/main/resources/templates/user/edit_vocab_entry.html +++ b/src/main/resources/templates/user/edit_vocab_entry.html @@ -17,21 +17,35 @@
-
+
+
+ Your vocabularies have been updated. +
+
+ +          + +
- abort +
+ back +
+ +
+ discard +
From 17f891c8fc7a76618f6148d72b9eba84f5779ca3 Mon Sep 17 00:00:00 2001 From: eder13 Date: Wed, 29 Apr 2020 10:31:37 +0200 Subject: [PATCH 70/74] LANG-013 implemented delete function [LJ, RS] --- .../project/controller/MVCController.java | 19 ++++++++++++++++++- .../resources/templates/user/edit_vocab.html | 2 +- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java index 07d57fd..92fae0d 100644 --- a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java +++ b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java @@ -125,7 +125,7 @@ public String showEditProductPage(@PathVariable(name = "id") int id, Model model @PostMapping("user/editvoc/edit/{id}") - public String submitEditedVocabularyEntry(@PathVariable(name = "id") int id, VocabularyEntries vocabularyEntries, Model model) + public String submitEditedVocabularyEntry(VocabularyEntries vocabularyEntries, Model model) { model.addAttribute("submitted", true); @@ -144,6 +144,23 @@ public String submitEditedVocabularyEntry(@PathVariable(name = "id") int id, Voc return "user/edit_vocab_entry"; } + @GetMapping("/user/editvoc/delete/{id}") + public String deleteVocabularyEntry(@PathVariable(name = "id") int id, Model model) + { + // tell the thymeleaf which user is logged in + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + VocabularyEntries vocabularyEntries = this.vocabularyRepository.getEntryBasedOnId(id); + + //System.out.println(vocabularyEntries.getId()); + + this.vocabularyRepository.delete(vocabularyEntries); + + model.addAttribute("overview", this.vocabularyRepository.showAllVocabularyFromUserX(userDetails.getUsername())); + + return "user/edit_vocab"; + } /* Show the Form and Let the user enter stuff */ @GetMapping("/user/addvoc") diff --git a/src/main/resources/templates/user/edit_vocab.html b/src/main/resources/templates/user/edit_vocab.html index 8f4081b..bf06c44 100644 --- a/src/main/resources/templates/user/edit_vocab.html +++ b/src/main/resources/templates/user/edit_vocab.html @@ -33,7 +33,7 @@ Edit - + Delete From 15ebfc0d66910b6ff6e5201acb5bb4ee04290a40 Mon Sep 17 00:00:00 2001 From: Alexander Beinhundner Date: Wed, 29 Apr 2020 11:37:46 +0200 Subject: [PATCH 71/74] LANG 005 --- .../project/controller/MVCController.java | 41 ++++- .../resources/templates/user/edit_tag.html | 57 +++++++ src/main/resources/templates/user/index.html | 20 ++- .../user/study_interface_english.html | 149 +++++++++++++++--- .../user/study_interface_german.html | 138 ++++++++++++++-- 5 files changed, 364 insertions(+), 41 deletions(-) create mode 100644 src/main/resources/templates/user/edit_tag.html diff --git a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java index 99981bf..36b33f8 100644 --- a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java +++ b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java @@ -11,6 +11,7 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -139,4 +140,42 @@ public String login() { public String accessDenied() { return "access-denied-page"; } -} + + + @GetMapping("user/edit_tag/edit/{id}") + public String showEditTagPage(@PathVariable(name = "id") int id, Model model) { + + model.addAttribute("submitted", false); + + VocabularyEntries vocabularyEntries = this.vocabularyRepository.getEntryBasedOnId(id); + + model.addAttribute("edit_tag", vocabularyEntries); + + return "user/edit_tag"; + } + + + @PostMapping("user/edit_tag/edit/{id}") + public String submitEditedTagEntry(@PathVariable(name = "id") int id, VocabularyEntries vocabularyEntries, Model model) + { + model.addAttribute("submitted", true); + + // get current user + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + vocabularyEntries.setUser(userDetails.getUsername()); + + // save result in our Repository Interface + VocabularyEntries result = this.vocabularyRepository.save(vocabularyEntries); + + // Thymeleaf-variable for "post-form" - add it + model.addAttribute("edit_tag", result); + + return "user/edit_tag"; + } + + + + +} \ No newline at end of file diff --git a/src/main/resources/templates/user/edit_tag.html b/src/main/resources/templates/user/edit_tag.html new file mode 100644 index 0000000..6339936 --- /dev/null +++ b/src/main/resources/templates/user/edit_tag.html @@ -0,0 +1,57 @@ + + + + + Edit Vocabulary Entry + + + + + + + + + + + + +
+ +
+
+ Your vocabularies have been updated. +
+
+ +
+ + + + + + + + + + + +
+ +
+ back +
+ +
+ discard +
+ +
+ + + \ No newline at end of file diff --git a/src/main/resources/templates/user/index.html b/src/main/resources/templates/user/index.html index 696d43a..5196473 100644 --- a/src/main/resources/templates/user/index.html +++ b/src/main/resources/templates/user/index.html @@ -13,12 +13,19 @@ + + + + + + + + +
@@ -25,35 +50,69 @@

Click words to reveal them.

+

Filter:

+
+
+
+ +
+
+
+
+ +

- +
+ + - - + + + + + - + - + + - + + + + + +
English Vocabulary
English Vocabulary
- - - + +
@@ -62,5 +121,55 @@

Click words to reveal them.

+ + \ No newline at end of file diff --git a/src/main/resources/templates/user/study_interface_german.html b/src/main/resources/templates/user/study_interface_german.html index 42d2a9b..f49e4f3 100644 --- a/src/main/resources/templates/user/study_interface_german.html +++ b/src/main/resources/templates/user/study_interface_german.html @@ -7,16 +7,41 @@ + + + + + + + + + + + + + + + +
@@ -27,34 +52,65 @@

Click words to reveal them.


+

Filter:

+
+
+
+ +
+
+
- + + +
+
+ + + - + - + + - + +
German VocabularyGerman Vocabulary
- - + + +
@@ -63,5 +119,53 @@

Click words to reveal them.

+ + \ No newline at end of file From 640c021700a80020df5e1dec4ebbfedea43513b9 Mon Sep 17 00:00:00 2001 From: Alexander Beinhundner Date: Wed, 29 Apr 2020 11:43:46 +0200 Subject: [PATCH 72/74] LANG 005 [BA, PC] --- .gitignore | 8 +- docs/Documentation.md | 51 ++++++++++--- .../project/controller/MVCController.java | 73 ++++++++++++++++++- .../project/db/VocabularyRepository.java | 5 +- .../resources/templates/user/edit_vocab.html | 47 ++++++++++++ .../templates/user/edit_vocab_entry.html | 53 ++++++++++++++ src/main/resources/templates/user/index.html | 2 + 7 files changed, 227 insertions(+), 12 deletions(-) create mode 100644 src/main/resources/templates/user/edit_vocab.html create mode 100644 src/main/resources/templates/user/edit_vocab_entry.html diff --git a/.gitignore b/.gitignore index 3f68ee9..e4805eb 100644 --- a/.gitignore +++ b/.gitignore @@ -104,4 +104,10 @@ build/ ### VS Code ### .vscode/ -src/main/resources/application.properties \ No newline at end of file + +# application.properties - depends on settings of the user etc. +src/main/resources/application.properties + + +# .DS_Store files +.DS_Store \ No newline at end of file diff --git a/docs/Documentation.md b/docs/Documentation.md index cf85149..4730bb3 100644 --- a/docs/Documentation.md +++ b/docs/Documentation.md @@ -4,7 +4,7 @@ ### Requirements -* Java SDK 1.8 or higher +* Java (obviously) * JDK 8 or higher * MySQL 5.6 or higher * JetBrains IntelliJ Ultimate IDE (optional but recommended) @@ -17,10 +17,11 @@ $ java -jar target/project-0.0.1-SNAPSHOT.jar ``` - * But make sure that you edited your [MySQL configurations](#adding-mysql-to-our-project) beforehand. + * Be sure that you edited your [MySQL configurations](#adding-mysql-to-our-project) beforehand. -### Building and Running +### Building and Running in IntelliJ +* (If you don't use IntelliJ, see under [Requirements](#requirements) how you can build/run this application) * Clone/Download this repository * Start IntelliJ and click 'Open' * Navigate in your cloned repo folder, choose the `pom.xml` file and click 'ok' @@ -32,11 +33,17 @@ #### Adding MySQL to our Project -* Download and Install MySQL [Community](https://dev.mysql.com/downloads/mysql/) and [Workbench](https://www.mysql.com/products/workbench/), setup everything +* Download and Install MySQL, setup everything in the workbench (create user `student` and password `student` for simplicity) and start the server (default port is 3306). -* Add the following to `src/recources/application.properties`: +* Login into MySQL: `mysql -u student -p` + +* Create the database: `CREATE DATABASE db_vocabularytrainer;` + +* Grant access: `GRANT ALL PRIVILEGES ON * . * TO 'student'@'localhost';` + +* In the project, add the following to `src/recources/application.properties`: ``` spring.jpa.hibernate.ddl-auto=update @@ -79,7 +86,7 @@ src | +- VocabularyTrainerApplication.java | | | +- db - | | +- VocabularyAddEntries.java + | | +- VocabularyEntries.java | | +- VocabularyRepository.java | | | +- controller @@ -111,6 +118,15 @@ src ``` +## Frameworks, Templates, Technologies etc. used + +* Maven +* Spring Boot +* Thymeleaf +* MySQL +* Hibernate +* Bootstrap + ## `pom.xml` configuration and dependencis ```xml @@ -210,10 +226,27 @@ src ![img_fix_cannot_build](fix_cannot_build.jpeg "picture") +### MySQL related errors +If you get a timezone error, replace your application.entries with the following: -### Useful Spring Boot, Thymeleaf, Bootstrap Get Started-Links - - +``` +spring.jpa.hibernate.ddl-auto=update +spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_vocabularytrainer?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false +spring.datasource.username=student +spring.datasource.password=student +``` +### Useful Spring Boot, Thymeleaf, Bootstrap Get Started-Links +* [Setup IntelliJ with Spring Boot using Spring Initializr](https://medium.com/danielpadua/java-spring-boot-intellij-idea-b919b0097a0) (small correction: don't import, just open the project) +* [Basic Tutorial using Spring Boot](https://spring.io/guides/gs/spring-boot/) +* [Some Interesting IntelliJ IDE Features](https://www.jetbrains.com/help/idea/spring-boot.html) +* [Using Spring Boot Annotations and explaining how they work](https://www.javatpoint.com/spring-boot-annotations) +* [Spring Boot MySQL example](https://spring.io/guides/gs/accessing-data-mysql/) +* [Great step by step tutorial using Spring Boot, Database and Thymeleaf](https://www.vogella.com/tutorials/SpringBoot/article.html) (!!! Highly recommend !!!) +* [Thymeleaf Getting Started Refernces](https://www.javatpoint.com/spring-boot-thymeleaf-view) +* [Explaination, what a Template (like Thymeleaf) is for](https://hackernoon.com/java-template-engines-ef84cb1025a4) +* [How to use @Queries in Spring Boot](https://www.baeldung.com/spring-data-jpa-query) +* [Using Spring Boot Securityto create a Login System](https://memorynotfound.com/spring-boot-spring-security-thymeleaf-form-login-example/) +* [Bootstrap Tutorial Reference](https://www.w3schools.com/bootstrap4/) diff --git a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java index 36b33f8..19d3a91 100644 --- a/src/main/java/com/vocabularytrainer/project/controller/MVCController.java +++ b/src/main/java/com/vocabularytrainer/project/controller/MVCController.java @@ -10,9 +10,12 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.ModelAndView; @Controller @@ -62,6 +65,7 @@ public String userStudyInterfaceGerman(Model model) { return "user/study_interface_german"; } + /* User StudyInterface in English */ @GetMapping("/user/studyInterfaceEnglish") public String userStudyInterfaceEnglish(Model model) { @@ -78,6 +82,7 @@ public String userStudyInterfaceEnglish(Model model) { } + /* General StudyInterface where user selects language */ @GetMapping("/user/studyInterface") public String userStudyInterface(Model model) { @@ -90,6 +95,73 @@ public String userStudyInterface(Model model) { return "user/study_interface"; } + + /* Show the All vocabularies in edit_vocab.html*/ + @GetMapping("user/editvoc") + public String getUserEditVocabulary(Model model) { + + // tell the thymeleaf which user is logged in + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + // get the Query to show current vocabulary entries of user x + model.addAttribute("overview", this.vocabularyRepository.showAllVocabularyFromUserX(userDetails.getUsername())); + + return "user/edit_vocab"; + } + + @GetMapping("user/editvoc/edit/{id}") + public String showEditProductPage(@PathVariable(name = "id") int id, Model model) { + + model.addAttribute("submitted", false); + + VocabularyEntries vocabularyEntries = this.vocabularyRepository.getEntryBasedOnId(id); + //System.out.println(vocabularyEntries.getId()); + + model.addAttribute("edit_vocab_entry", vocabularyEntries); + + return "user/edit_vocab_entry"; + } + + + @PostMapping("user/editvoc/edit/{id}") + public String submitEditedVocabularyEntry(VocabularyEntries vocabularyEntries, Model model) + { + model.addAttribute("submitted", true); + + // get current user + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + vocabularyEntries.setUser(userDetails.getUsername()); + + // save result in our Repository Interface + VocabularyEntries result = this.vocabularyRepository.save(vocabularyEntries); + + // Thymeleaf-variable for "post-form" - add it + model.addAttribute("edit_vocab_entry", result); + + return "user/edit_vocab_entry"; + } + + @GetMapping("/user/editvoc/delete/{id}") + public String deleteVocabularyEntry(@PathVariable(name = "id") int id, Model model) + { + // tell the thymeleaf which user is logged in + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + + VocabularyEntries vocabularyEntries = this.vocabularyRepository.getEntryBasedOnId(id); + + //System.out.println(vocabularyEntries.getId()); + + this.vocabularyRepository.delete(vocabularyEntries); + + model.addAttribute("overview", this.vocabularyRepository.showAllVocabularyFromUserX(userDetails.getUsername())); + + return "user/edit_vocab"; + } + /* Show the Form and Let the user enter stuff */ @GetMapping("/user/addvoc") // Model -> Thymeleaf model to access html "variables" @@ -106,7 +178,6 @@ public String getUserAddVocabulary(Model model) { } - /* Submit Data from Form using POST */ @PostMapping("/user/addvoc") public String submitUserAddVocabulary(VocabularyEntries vocabularyEntries, Model model) { diff --git a/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java b/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java index 157346e..3a465d3 100644 --- a/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java +++ b/src/main/java/com/vocabularytrainer/project/db/VocabularyRepository.java @@ -22,5 +22,8 @@ List showAllVocabularyFromUserX( @Param("paruser") String paruser // Parameter Handling for JPQL-Style queries ); - + @Query(value="SELECT i FROM VocabularyEntries i WHERE i.id = :parid") + VocabularyEntries getEntryBasedOnId( + @Param("parid") int parid + ); } diff --git a/src/main/resources/templates/user/edit_vocab.html b/src/main/resources/templates/user/edit_vocab.html new file mode 100644 index 0000000..bf06c44 --- /dev/null +++ b/src/main/resources/templates/user/edit_vocab.html @@ -0,0 +1,47 @@ + + + + + Edit Vocabularies + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
IDGerman VocabularyEnglish TranslationActions
+ Edit + Delete +
+ + back + +
+ + + \ No newline at end of file diff --git a/src/main/resources/templates/user/edit_vocab_entry.html b/src/main/resources/templates/user/edit_vocab_entry.html new file mode 100644 index 0000000..4fa80de --- /dev/null +++ b/src/main/resources/templates/user/edit_vocab_entry.html @@ -0,0 +1,53 @@ + + + + + Edit Vocabulary Entry + + + + + + + + + + + + +
+ +
+
+ Your vocabularies have been updated. +
+
+ +
+ +         + + + + + + + +
+ +
+ back +
+ +
+ discard +
+ +
+ + + \ No newline at end of file diff --git a/src/main/resources/templates/user/index.html b/src/main/resources/templates/user/index.html index 5196473..39960e7 100644 --- a/src/main/resources/templates/user/index.html +++ b/src/main/resources/templates/user/index.html @@ -104,6 +104,8 @@

Filter:

Add Vocabulary

Add vocabulary +

Edit Vocabulary

+

Study Interface

Logout

From 9ed20c92b3c0bbc402f272d10954c5aecdfea651 Mon Sep 17 00:00:00 2001 From: eder13 Date: Wed, 6 May 2020 09:05:20 +0200 Subject: [PATCH 73/74] hotfix removed .DS_Store --- src/main/.DS_Store | Bin 10244 -> 0 bytes src/main/java/.DS_Store | Bin 6148 -> 0 bytes src/main/java/com/.DS_Store | Bin 6148 -> 0 bytes src/main/java/com/vocabularytrainer/.DS_Store | Bin 6148 -> 0 bytes .../com/vocabularytrainer/project/.DS_Store | Bin 6148 -> 0 bytes src/main/resources/.DS_Store | Bin 8196 -> 0 bytes src/main/resources/templates/.DS_Store | Bin 8196 -> 0 bytes 7 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/main/.DS_Store delete mode 100644 src/main/java/.DS_Store delete mode 100644 src/main/java/com/.DS_Store delete mode 100644 src/main/java/com/vocabularytrainer/.DS_Store delete mode 100644 src/main/java/com/vocabularytrainer/project/.DS_Store delete mode 100644 src/main/resources/.DS_Store delete mode 100644 src/main/resources/templates/.DS_Store diff --git a/src/main/.DS_Store b/src/main/.DS_Store deleted file mode 100644 index f342cf74c5bcce57738c854988b98ab36322b99e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10244 zcmeHMU2GIp6h5aEm>;0G{I?1W7Hct!bi1Xk;m7T^AVm;#3oWIz%Vq#46L0?RKF&d5M&Yi7g+xl2YoSV!&_nvdl z+3b*rXN~s7nGD#$V$c%Wy8QaZJ|I;a>BSnNj zgg}Hqgg}HqguuOk0Of36Bvr_$ju40th!B`SfPWt}y0}b+a!knJ(?M0R1t3{T>Yz}Y z@dimPl*v$z2}u?zC|pSjR}8lpDBMY}h2xT;91~Kw1BROq3}?o0hl0WEbbl=v4ww`& zsv`s<1g0Xu_wJQ&9CRpvK6(G18MZCYZ*2S;E9O+roi|^S6iHdA98Mo|N7BCT=e?Ak zJH&hYbpKc;YD2aZ9d5B$+~ua$nko8^Q6x;eV&{1I|Ah(V|mYf+NAMT!R#b2Z;&nKciKDbTdw0B zFmoQsx@4nRwk%y)xO{cpL$P?v=H&MAMOCa?S)wfKDOjGBvCaJ>mf;^esC!w{F)Zh3 zA7SSB)-#rwldJJZx!ci)%<&Z~YpT`z)KxQiNvuxl&1bA<^Ok>Vyt;}lTBE5-zd_5} z;~M;K2D>iFfn}Yhs)x9xBWF@=NK&9~Sg$JG9tF$vaNveV6s7wFJyhn&!nG-(sQYa_ zW7^D+g=hgNlyrVpai z)SZ%akXzdg!!+uW4FbOa0GaW0QUeb_Gwg(Ya1aa_fmh%)I1d-#Ew~Er!G~}YK8G*h zOBjb+@B{n|zrr8zC;SC}<9uYe3fG{9Yw=-h!B%X;cHDtGu?u%$8hf!14`Dx=cmjve zK^ITr7(R#R@OgX{&*MeBgqQJcyoT5Def$7F!jJI=euiJ+w|HBuv!X=TJ)&Q#@jGfw zypTlK@Ib9%U|PEFcwA|?yL7#^kaKkLlBLU*uUWT#LsRRP_K9a%_Vn%`*kn!xL=sF1 z7*t}&1ebsYU!yic-rgq?T#;SC(YN$2qDa z1R?}x3xPReB8{K_Z=d=9|JhnjG*5&;guq=u04qDwohh2Qv^6SU13zom=sH3dFMQmX zkbw(Tcl;4R9ex}i9LbO^JlYEUlBDPUV?qY*)DPTA&eER&(f*&q|8I%*{{a89{r^Ax CHwwxC diff --git a/src/main/java/.DS_Store b/src/main/java/.DS_Store deleted file mode 100644 index 35a54bf0595027f28217af82c3d32981e121b5e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~Jr2S!425mVP>H1@V-^m;4I%_5-~tF3K^+i#j?VMXLSaS~dY0@jc51bKLsN^0 z?w;4J$RHv;+$b9h6I0}!Tx68{^>MkK$MI$*w?)zl@IfZ~xlK?3DnJFO02QDDGg2TA z@_sd=XX2w!0V*&L1?>A!;KrJ4LH~3h_y_tMAK>5S|49o|DnJGPOaWc) zkNX{7D$mxB*R%R5tF~@%&@V@L`w2i|NAVi&hW%m-uqIm&6&Qa6Tm}Xz@KXg|*oF~o diff --git a/src/main/java/com/.DS_Store b/src/main/java/com/.DS_Store deleted file mode 100644 index 9845f5c753a386a39194689b379de9c62eddd2fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKIZgvX5Ud6VmPkxSIA7ogE6coq58#6UX~jwgTO!+tckwi;j{s{SvPi6Isi$Uo zx@I&LY;Oaw~aH_y{E*D<^ALxJd|EDCaq<|E-CJG|f(1D?P0 zhof)Fq<|EV0#ZNEIA80CC1}80XPT z5Ss^xy>Luqgl0)4Ce^CNu%t8IDz6ugiAjf5^I>(fRfl46JI`;C4(o{;rGOMTSKv06 zORxVM`i1`goTQZ$kOKco0h_J2>lL3=wRQ41ueFW-NcWsCx*O*~;SlAR80DA?FUR+h blzGkP-0y{BV$c~6I#E9Zu8T|x{I&uoNJtfu diff --git a/src/main/java/com/vocabularytrainer/project/.DS_Store b/src/main/java/com/vocabularytrainer/project/.DS_Store deleted file mode 100644 index 55861b51956d8a04bfa659f3a45a8981cdc7aaef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~JqiLr422WjLa^D=avBfd4F=H@cmdHZg)PK>j_%73qN}xtyg>3YnF-5&#m+`V zbbA{%BE5(#;HI*+Ffqk?CWD-Y>-lmT$IH|HEOR>p?`5+8bd)IxkN^pg011%5j}WkX z8@5=6GLirZkidh0eIE+kw5GOD|8yYu2mtL+c0=y71hiNIT2osnDlm;!Xtb)2Ay)Tx zXvuRmwS`8zXbvBmPga{^U>fbB1q+x~7X}g_feC?mtb4ov_wY~i|D=UW5+H#;BcR>x zu-oFL@@{>5J*ywHYI%c0{W!wQPXHEn6|dlK*e{kqYibKc1;!r%$G|`WUnOt{H0lr` diff --git a/src/main/resources/.DS_Store b/src/main/resources/.DS_Store deleted file mode 100644 index 565565c990ab86824afec2d869707e9f71ba3d0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeI1O>Epm6vyA&q^Unhml00b(`Dl%2;94yYtnj_?Us>mYc0~nCeoQ#>aZF9}p zfg?~LP#{nsP#{nsP+&7CKx;NTgbmhx9u4Y1fk1(~QUUgUh)`iR=Gzjt-m8NuZwo-S zlHA@wZQ2KTIT7E+d|TqyOQmb_-2?im=x;HQr&Bz_PA41lZHZf+4#?91{gKh%p`bT9 zWKzdcSL2Ugo^deYDrQp(Oj z+j3RI((_)jq3LwWY|^kadm(NYEY0z*li&eC5Ct)%gqN1OJA0y$&ilKTqmiZF-i~PG zNLSDDvMAIa=k4%w7anxs9YBQ>tDVVCO513}c zxTrhHjBOUOmNVt*7hL9-1w(V^r&TATTbf~=n;}sx*EnnFd9fCM7RN0$tFP47 zDBJ48vOHBt8|Mp#yQnk^g6G}SBuldz4fUw4u`EsbSP;F)z9v~d%_4(&oobB|yun-K zR#8!faffEiJ#EqjNAV#X!)ctsSv-R}T4-Y)9lV6k;>-97zKXBm z+xQM%!|V77e$FQrDkD3}`{f$Hpw>Fb5|jSZ8A`6piuK?;3mvpAvQ}a1(wcpDvgxpDd3==qklbFOgOru87oh9hb6Lc;X@G_S0DSR5A!RPQQzKAaohHv3} z9I;jKPL`457T;eVyka76nYML~qGe=nPYimSPk{M}-~iyb`xw3RUbB=J&SaWLN(%q;|xQ#e7@hmLhcg=N|%s N^*>nuJ@W4E>TfzS;e!AG diff --git a/src/main/resources/templates/.DS_Store b/src/main/resources/templates/.DS_Store deleted file mode 100644 index 389d0d1049924f1b502ac3c196c59e15ca42bee5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHMTWl0n827!PZ*LBE8XKxVYVx+9F7GTY7`GyE|h$GCNauX4^t3 zY1BmHZr`k*f)z8HVq)5t2 ztnqB_0(CcKC25M>d12MoXk9$zq{njt|FO9ft>Q(a;PgBq-_9c4l|Z@ zjVBE9Hz$lXigJh9YTnbqanE#Y_mGisNmfQ{#dKxq+{*QvD({cfHSLVdPk0r?aMaY_6o3t*X#e<*-iEJK*TNH=SLSWZzPysp=rNv}Oz{bxHEoHCt4r+oi>_ zMBupfK}G34N+e*eEJEuW6t%}nBn^w{vIuM5p{TtRV$JN)K)GwTqV~}jOVd)^5{v}u zmYAvz@sal@T<_qxVbiQG)A0W4G_^yL`nk15*A2ZgS|jlD0gxF#e#+opXoL>vf_~6p z5?+Q^;S`*Px8Xdz4oACi`!e-oo zE!d77*opfvj(s?QgLoJXJc?DvB?QuF`P^~y@l(ba3#u3KMGwPkC4 z^RAYKZ@J{_Eh1Phr+gv_ruYn+XUGDZ%hh|7P5Ic|L!2|FBu*T*g0rJs-K_{@rgb&nF2h_-C` zTzP5PhFGhjFyKEsc?tjig?;bA1-L}ay9VFGPw)%;3cn$ujKx^yGp-V=uo|~vE!JZL zZpS_NFmW%2ZFm45!-M#^&%Gl!gd=F;Q)m$bIscB~G@ihd_&mOVFXBr+4__k|zJYJz zyLfI1>pGXP?tCum(oS2Op7l}ySKs=${d#(_P0wo^AIrb-PQ){|<=CUt*F5tVPa$mG zG6IF7hf;q3-<$va|CYxII|va75x9L3z@oNzTa4zHZ>QyVZH@8>WuCa-tdM>P6^kAM ksJ-xqA=Nc<hv&afy*s-28=#UL=Kufz From bde5354195789fa28abcb7d79411af8d3ca21f8d Mon Sep 17 00:00:00 2001 From: Christoph Pruell Date: Wed, 6 May 2020 09:52:59 +0200 Subject: [PATCH 74/74] Updated Readme file (06.05.20) --- README.md | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/README.md b/README.md index 7b2ebb3..6a97043 100644 --- a/README.md +++ b/README.md @@ -180,5 +180,80 @@ More focus on agile events and practices! * Added Junit and Mockito Tests. +- - - - + +# Review Meeting: Sprint 2 +## ASD Morning 4 - Meeting #5 + +* Review Meeting : Sprint 2 +* ASD Morning 4 - Meeting #4 +* Date: 29.04.2020 +* Time: 11:30 - 12:00 +* Type of meeting: Review Meeting +* Attendees: All +* Tools used to conduct the meeting: Slack and Teamspeak + + +###Purpose +* Help wanted? +* How far are the Issues implemented? +* Are there critical bugs? +* Ideas for better interaction. + +###Meeting Protocol +* Only minor issues are present. +* Most Issues are finished. +* No bugs, we know of yet. +* One minor (size 5) Issue was not completed. +* This gets bigger priority next Sprint +* Interaction is not highest priority as of now. +* Code Documentation needs to be updated! +* Commitment +* Closed all Issues that we worked on in Sprint 2 + + + + + + + + + +- - - - + +# Planning Meeting: Sprint 3 +## ASD Morning 4 - Meeting #6 + +* Date: 06.05.2020 +* Time: 08:00 - 08:45 +* Type of meeting: Planning Game +* Attendees: All +* Tools used to conduct the meeting: Slack and Teamspeak + +###Purpose + +* Forming new Pair Programming Groups +* Declare Issue size +* distribute Issues +* Assign Sprint +* Planning ahead for future Sessions + +###Meeting Protocol + +* New Ping-Pong Groups are formed. + * Kristiana + Christoph + * Alex + Simon + * Jan + Andi + * Sophie + Carina +* Issue sizes changed +* Testing mode got High Priority duo to Issue 8 and 9 +* UnitTesting needs updates! + +###Commitment + +* Hotfix for ds store! + +* Updating some documentation! +* Starting to code Issues.