From ee2c9687a4d4cc19ad87d18dc4023f736d7d9cd2 Mon Sep 17 00:00:00 2001 From: Anton Micke Date: Wed, 5 Feb 2025 17:42:09 +0100 Subject: [PATCH] Initial commit --- .gitignore | 41 +++++++ pom.xml | 115 ++++++++++++++++++ .../kickerelo/KickerEloApplication.java | 20 +++ .../kickerelo/kickerelo/KickerEloService.java | 73 +++++++++++ .../org/kickerelo/kickerelo/MainView.java | 70 +++++++++++ .../kickerelo/NoSuchPlayerException.java | 7 ++ .../kickerelo/data/Ergebnis1vs1.java | 75 ++++++++++++ .../kickerelo/data/Ergebnis2vs2.java | 97 +++++++++++++++ .../org/kickerelo/kickerelo/data/Spieler.java | 45 +++++++ .../repository/Ergebnis1vs1Repository.java | 9 ++ .../repository/Ergebnis2vs2Repository.java | 9 ++ .../repository/SpielerRepository.java | 12 ++ src/main/resources/application.properties | 6 + 13 files changed, 579 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/org/kickerelo/kickerelo/KickerEloApplication.java create mode 100644 src/main/java/org/kickerelo/kickerelo/KickerEloService.java create mode 100644 src/main/java/org/kickerelo/kickerelo/MainView.java create mode 100644 src/main/java/org/kickerelo/kickerelo/NoSuchPlayerException.java create mode 100644 src/main/java/org/kickerelo/kickerelo/data/Ergebnis1vs1.java create mode 100644 src/main/java/org/kickerelo/kickerelo/data/Ergebnis2vs2.java create mode 100644 src/main/java/org/kickerelo/kickerelo/data/Spieler.java create mode 100644 src/main/java/org/kickerelo/kickerelo/repository/Ergebnis1vs1Repository.java create mode 100644 src/main/java/org/kickerelo/kickerelo/repository/Ergebnis2vs2Repository.java create mode 100644 src/main/java/org/kickerelo/kickerelo/repository/SpielerRepository.java create mode 100644 src/main/resources/application.properties diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fac9f1f --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store + +### Vaadin ### +/src/main/frontend/generated/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..8a728ed --- /dev/null +++ b/pom.xml @@ -0,0 +1,115 @@ + + + 4.0.0 + + org.kickerelo + KickerELO + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 3.4.2 + + + + + 23 + 23 + UTF-8 + 24.6.4 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.vaadin + vaadin-spring-boot-starter + + + + + com.h2database + h2 + runtime + + + org.springframework.boot + spring-boot-starter-tomcat + provided + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + com.vaadin + vaadin-bom + ${vaadin.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + production + + + com.vaadin + vaadin-core + + + com.vaadin + vaadin-dev + + + + + + + + + com.vaadin + vaadin-maven-plugin + ${vaadin.version} + + + frontend + compile + + prepare-frontend + build-frontend + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/org/kickerelo/kickerelo/KickerEloApplication.java b/src/main/java/org/kickerelo/kickerelo/KickerEloApplication.java new file mode 100644 index 0000000..8e4a000 --- /dev/null +++ b/src/main/java/org/kickerelo/kickerelo/KickerEloApplication.java @@ -0,0 +1,20 @@ +package org.kickerelo.kickerelo; + +import com.vaadin.flow.component.page.AppShellConfigurator; +import com.vaadin.flow.theme.Theme; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + + +@SpringBootApplication +@EntityScan(basePackages = "org.kickerelo.kickerelo.data") +@EnableJpaRepositories +@Theme("my-theme") +public class KickerEloApplication implements AppShellConfigurator { + public static void main(String[] args) { + SpringApplication.run(KickerEloApplication.class, args); + } + +} diff --git a/src/main/java/org/kickerelo/kickerelo/KickerEloService.java b/src/main/java/org/kickerelo/kickerelo/KickerEloService.java new file mode 100644 index 0000000..0edfe88 --- /dev/null +++ b/src/main/java/org/kickerelo/kickerelo/KickerEloService.java @@ -0,0 +1,73 @@ +package org.kickerelo.kickerelo; + +import org.kickerelo.kickerelo.data.Ergebnis1vs1; +import org.kickerelo.kickerelo.data.Ergebnis2vs2; +import org.kickerelo.kickerelo.data.Spieler; +import org.kickerelo.kickerelo.repository.Ergebnis1vs1Repository; +import org.kickerelo.kickerelo.repository.Ergebnis2vs2Repository; +import org.kickerelo.kickerelo.repository.SpielerRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class KickerEloService { + @Autowired + private Ergebnis1vs1Repository ergebnis1vs1Repository; + @Autowired + private Ergebnis2vs2Repository ergebnis2vs2Repository; + @Autowired + private SpielerRepository spielerRepository; + + public List getSpielerNamen() { + return spielerRepository.findAll().stream().map(Spieler::getName).toList(); + } + + public void enterResult1vs1(String gewinnerName, String verliererName, + short toreVerlierer) { + + Spieler gewinner = spielerRepository.findByName(gewinnerName) + .orElseThrow(() -> new NoSuchPlayerException(gewinnerName)); + + Spieler verlierer = spielerRepository.findByName(verliererName) + .orElseThrow(() -> new NoSuchPlayerException(verliererName)); + + + Ergebnis1vs1 ergebnis = new Ergebnis1vs1(gewinner, verlierer, toreVerlierer); + + ergebnis1vs1Repository.save(ergebnis); + + // Compute the new ELO and update the Spieler entities + } + + public void enterResult2vs2(String gewinnerNameVorn, String gewinnerNameHinten, + String verliererNameVorn, String verliererNameHinten, + short toreVerlierer) { + + Spieler gewinnerVorn = spielerRepository.findByName(gewinnerNameVorn) + .orElseThrow(() -> new NoSuchPlayerException(gewinnerNameVorn)); + + Spieler gewinnerHinten = spielerRepository.findByName(gewinnerNameHinten) + .orElseThrow(() -> new NoSuchPlayerException(gewinnerNameHinten)); + + Spieler verliererVorn = spielerRepository.findByName(verliererNameVorn) + .orElseThrow(() -> new NoSuchPlayerException(verliererNameVorn)); + + Spieler verliererHinten = spielerRepository.findByName(verliererNameHinten) + .orElseThrow(() -> new NoSuchPlayerException(verliererNameHinten)); + + Ergebnis2vs2 ergebnis = new Ergebnis2vs2(gewinnerVorn, gewinnerHinten, verliererVorn, verliererHinten, toreVerlierer); + + ergebnis2vs2Repository.save(ergebnis); + + // Compute the new ELO, update the Spieler entitities + } + + public void addSpieler(String name) { + Spieler spieler = new Spieler(); + spieler.setName(name); + spieler.setElo(1500); + spielerRepository.save(spieler); + } +} diff --git a/src/main/java/org/kickerelo/kickerelo/MainView.java b/src/main/java/org/kickerelo/kickerelo/MainView.java new file mode 100644 index 0000000..bf52851 --- /dev/null +++ b/src/main/java/org/kickerelo/kickerelo/MainView.java @@ -0,0 +1,70 @@ +package org.kickerelo.kickerelo; + +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.notification.Notification; +import com.vaadin.flow.component.notification.NotificationVariant; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.IntegerField; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.router.Route; + +/** + * A sample Vaadin view class. + *

+ * To implement a Vaadin view just extend any Vaadin component and use @Route + * annotation to announce it in a URL as a Spring managed bean. + *

+ * A new instance of this class is created for every new user and every browser + * tab/window. + *

+ * The main view contains a text field for getting the user name and a button + * that shows a greeting message in a notification. + */ +@Route +public class MainView extends VerticalLayout { + + /** + * Construct a new Vaadin view. + */ + + public MainView(KickerEloService eloService) { + + + TextField spielername = new TextField("Spielername"); + spielername.addClassName("bordered"); + + // Button click listeners can be defined as lambda expressions + Button button = new Button("Spieler hinzufügen", e -> { + eloService.addSpieler(spielername.getValue()); + Notification.show("Spieler gespeichert").addThemeVariants(NotificationVariant.LUMO_SUCCESS); + }); + + button.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + + ComboBox winnerSelect = new ComboBox<>("Gewinner"); + winnerSelect.setItems(eloService.getSpielerNamen()); + winnerSelect.setPlaceholder("Spieler auswählen"); + + ComboBox loserSelect = new ComboBox<>("Verlierer"); + loserSelect.setItems(eloService.getSpielerNamen()); + loserSelect.setPlaceholder("Spieler auswählen"); + + IntegerField loserGoals = new IntegerField("Tore des Verlierers"); + loserGoals.setMin(0); + loserGoals.setMax(9); + loserGoals.setValue(0); + loserGoals.setStepButtonsVisible(true); + + Button saveButton = new Button("Speichern", e -> + eloService.enterResult1vs1(winnerSelect.getValue(), loserSelect.getValue(), loserGoals.getValue().shortValue())); + + + // Use custom CSS classes to apply styling. This is defined in + // styles.css. + addClassName("centered-content"); + + add(spielername, button, winnerSelect, loserSelect, loserGoals, saveButton); + } +} \ No newline at end of file diff --git a/src/main/java/org/kickerelo/kickerelo/NoSuchPlayerException.java b/src/main/java/org/kickerelo/kickerelo/NoSuchPlayerException.java new file mode 100644 index 0000000..2fbbe3f --- /dev/null +++ b/src/main/java/org/kickerelo/kickerelo/NoSuchPlayerException.java @@ -0,0 +1,7 @@ +package org.kickerelo.kickerelo; + +public class NoSuchPlayerException extends RuntimeException { + public NoSuchPlayerException(String message) { + super(message); + } +} diff --git a/src/main/java/org/kickerelo/kickerelo/data/Ergebnis1vs1.java b/src/main/java/org/kickerelo/kickerelo/data/Ergebnis1vs1.java new file mode 100644 index 0000000..28e0c91 --- /dev/null +++ b/src/main/java/org/kickerelo/kickerelo/data/Ergebnis1vs1.java @@ -0,0 +1,75 @@ +package org.kickerelo.kickerelo.data; + +import jakarta.persistence.*; + +import java.time.LocalDateTime; + +@Entity +public class Ergebnis1vs1 { + @Id + @Column(name = "ID") + private long id; + + @ManyToOne + @JoinColumn(name = "GEWINNER") + private Spieler gewinner; + + @ManyToOne + @JoinColumn(name = "VERLIERER") + private Spieler verlierer; + + @Column(name = "TORE_VERLIERER") + private short toreVerlierer; + + @Column(name = "ZEITPUNKT") + private LocalDateTime timestamp; + + public Ergebnis1vs1() { + } + + public Ergebnis1vs1(Spieler gewinner, Spieler verlierer, short toreVerlierer) { + this.gewinner = gewinner; + this.verlierer = verlierer; + this.toreVerlierer = toreVerlierer; + } + + public Spieler getVerlierer() { + return verlierer; + } + + public void setVerlierer(Spieler verlierer) { + this.verlierer = verlierer; + } + + public Spieler getGewinner() { + return gewinner; + } + + public void setGewinner(Spieler gewinner) { + this.gewinner = gewinner; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public short getToreVerlierer() { + return toreVerlierer; + } + + public void setToreVerlierer(short toreVerlierer) { + this.toreVerlierer = toreVerlierer; + } + + public LocalDateTime getTimestamp() { + return timestamp; + } + + public void setTimestamp(LocalDateTime timestamp) { + this.timestamp = timestamp; + } +} diff --git a/src/main/java/org/kickerelo/kickerelo/data/Ergebnis2vs2.java b/src/main/java/org/kickerelo/kickerelo/data/Ergebnis2vs2.java new file mode 100644 index 0000000..75f3d53 --- /dev/null +++ b/src/main/java/org/kickerelo/kickerelo/data/Ergebnis2vs2.java @@ -0,0 +1,97 @@ +package org.kickerelo.kickerelo.data; + +import jakarta.persistence.*; + +import java.time.LocalDateTime; + +@Entity +public class Ergebnis2vs2 { + @Id + @Column(name = "ID") + private long id; + + @ManyToOne + @JoinColumn(name = "GEWINNER_VORN") + private Spieler gewinnerVorn; + + @ManyToOne + @JoinColumn(name = "GEWINNER_HINTEN") + private Spieler gewinnerHinten; + + @ManyToOne + @JoinColumn(name = "VERLIERER_VORN") + private Spieler verliererVorn; + + @ManyToOne + @JoinColumn(name = "VERLIERER_HINTEN") + private Spieler verliererHinten; + + @Column(name = "TORE_VERLIERER") + private short toreVerlierer; + + @Column(name = "ZEITPUNKT") + private LocalDateTime timestamp; + + public Ergebnis2vs2() { + } + + public Ergebnis2vs2(Spieler gewinnerVorn, Spieler gewinnerHinten, Spieler verliererVorn, Spieler verliererHinten, short toreVerlierer) { + this.gewinnerVorn = gewinnerVorn; + this.gewinnerHinten = gewinnerHinten; + this.verliererVorn = verliererVorn; + this.verliererHinten = verliererHinten; + this.toreVerlierer = toreVerlierer; + } + + public long getId() { + return id; + } + + public short getToreVerlierer() { + return toreVerlierer; + } + + public void setToreVerlierer(short toreVerlierer) { + this.toreVerlierer = toreVerlierer; + } + + public LocalDateTime getTimestamp() { + return timestamp; + } + + public void setTimestamp(LocalDateTime timestamp) { + this.timestamp = timestamp; + } + + public Spieler getVerliererHinten() { + return verliererHinten; + } + + public void setVerliererHinten(Spieler verliererHinten) { + this.verliererHinten = verliererHinten; + } + + public Spieler getVerliererVorn() { + return verliererVorn; + } + + public void setVerliererVorn(Spieler verliererVorn) { + this.verliererVorn = verliererVorn; + } + + public Spieler getGewinnerHinten() { + return gewinnerHinten; + } + + public void setGewinnerHinten(Spieler gewinnerHinten) { + this.gewinnerHinten = gewinnerHinten; + } + + public Spieler getGewinnerVorn() { + return gewinnerVorn; + } + + public void setGewinnerVorn(Spieler gewinnerVorn) { + this.gewinnerVorn = gewinnerVorn; + } +} diff --git a/src/main/java/org/kickerelo/kickerelo/data/Spieler.java b/src/main/java/org/kickerelo/kickerelo/data/Spieler.java new file mode 100644 index 0000000..d4946f0 --- /dev/null +++ b/src/main/java/org/kickerelo/kickerelo/data/Spieler.java @@ -0,0 +1,45 @@ +package org.kickerelo.kickerelo.data; + +import jakarta.persistence.*; + +@Entity +@Table(name = "SPIELER") +public class Spieler { + @Id + @Column(name = "ID", unique = true, nullable = false) + @GeneratedValue + private int id; + + @Column(name = "NAME", nullable = false, unique = true) + private String name; + + @Column(name = "ELO", nullable = false) + private float elo; + + public Spieler() { + } + + public void setId(int id) { + this.id = id; + } + + public int getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public float getElo() { + return elo; + } + + public void setElo(float elo) { + this.elo = elo; + } +} diff --git a/src/main/java/org/kickerelo/kickerelo/repository/Ergebnis1vs1Repository.java b/src/main/java/org/kickerelo/kickerelo/repository/Ergebnis1vs1Repository.java new file mode 100644 index 0000000..6332e2d --- /dev/null +++ b/src/main/java/org/kickerelo/kickerelo/repository/Ergebnis1vs1Repository.java @@ -0,0 +1,9 @@ +package org.kickerelo.kickerelo.repository; + +import org.kickerelo.kickerelo.data.Ergebnis1vs1; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface Ergebnis1vs1Repository extends JpaRepository { +} diff --git a/src/main/java/org/kickerelo/kickerelo/repository/Ergebnis2vs2Repository.java b/src/main/java/org/kickerelo/kickerelo/repository/Ergebnis2vs2Repository.java new file mode 100644 index 0000000..3e9c3f9 --- /dev/null +++ b/src/main/java/org/kickerelo/kickerelo/repository/Ergebnis2vs2Repository.java @@ -0,0 +1,9 @@ +package org.kickerelo.kickerelo.repository; + +import org.kickerelo.kickerelo.data.Ergebnis2vs2; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface Ergebnis2vs2Repository extends JpaRepository { +} diff --git a/src/main/java/org/kickerelo/kickerelo/repository/SpielerRepository.java b/src/main/java/org/kickerelo/kickerelo/repository/SpielerRepository.java new file mode 100644 index 0000000..833de58 --- /dev/null +++ b/src/main/java/org/kickerelo/kickerelo/repository/SpielerRepository.java @@ -0,0 +1,12 @@ +package org.kickerelo.kickerelo.repository; + +import org.kickerelo.kickerelo.data.Spieler; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface SpielerRepository extends JpaRepository { + Optional findByName(String name); +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..38b2b4d --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,6 @@ +server.port=${PORT:8080} +logging.level.org.atmosphere = warn +spring.mustache.check-template-location = false + +# Launch the default browser when starting the application in development mode +vaadin.launch-browser=true