From 5c898e3ff77adbad821080ca89cbfec2a5b1ffb7 Mon Sep 17 00:00:00 2001 From: jez04 <david.jezek@post.cz> Date: Thu, 28 Mar 2024 16:19:08 +0100 Subject: [PATCH] Initial code --- .gitignore | 18 +++ pom.xml | 150 ++++++++++++++++++ src/main/java/cz/vsb/fei/java2/lab06/App.java | 78 +++++++++ .../java/cz/vsb/fei/java2/lab06/Tools.java | 83 ++++++++++ .../fei/java2/lab06/entities/BaseEntity.java | 26 +++ .../cz/vsb/fei/java2/lab06/entities/Car.java | 68 ++++++++ .../java2/lab06/entities/JuridicalPerson.java | 46 ++++++ .../fei/java2/lab06/entities/LegalPerson.java | 36 +++++ .../fei/java2/lab06/entities/Motorbike.java | 71 +++++++++ .../java2/lab06/entities/NaturalPerson.java | 42 +++++ .../vsb/fei/java2/lab06/entities/Route.java | 60 +++++++ .../vsb/fei/java2/lab06/entities/Truck.java | 71 +++++++++ .../vsb/fei/java2/lab06/entities/Vehicle.java | 68 ++++++++ .../lab06/repositories/BaseRepository.java | 51 ++++++ src/main/java/module-info.java | 15 ++ src/main/resources/META-INF/persistence.xml | 54 +++++++ src/main/resources/log4j2.xml | 13 ++ .../java/cz/vsb/fei/java2/lab06/AppTest.java | 19 +++ 18 files changed, 969 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/cz/vsb/fei/java2/lab06/App.java create mode 100644 src/main/java/cz/vsb/fei/java2/lab06/Tools.java create mode 100644 src/main/java/cz/vsb/fei/java2/lab06/entities/BaseEntity.java create mode 100644 src/main/java/cz/vsb/fei/java2/lab06/entities/Car.java create mode 100644 src/main/java/cz/vsb/fei/java2/lab06/entities/JuridicalPerson.java create mode 100644 src/main/java/cz/vsb/fei/java2/lab06/entities/LegalPerson.java create mode 100644 src/main/java/cz/vsb/fei/java2/lab06/entities/Motorbike.java create mode 100644 src/main/java/cz/vsb/fei/java2/lab06/entities/NaturalPerson.java create mode 100644 src/main/java/cz/vsb/fei/java2/lab06/entities/Route.java create mode 100644 src/main/java/cz/vsb/fei/java2/lab06/entities/Truck.java create mode 100644 src/main/java/cz/vsb/fei/java2/lab06/entities/Vehicle.java create mode 100644 src/main/java/cz/vsb/fei/java2/lab06/repositories/BaseRepository.java create mode 100644 src/main/java/module-info.java create mode 100644 src/main/resources/META-INF/persistence.xml create mode 100644 src/main/resources/log4j2.xml create mode 100644 src/test/java/cz/vsb/fei/java2/lab06/AppTest.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..06fab23 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# Eclipse +.classpath +.project +.settings/ + +# Intellij +.idea/ +*.iml +*.iws + +# Mac +.DS_Store + +# Maven +log/ +target/ + +db/ \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..f81e798 --- /dev/null +++ b/pom.xml @@ -0,0 +1,150 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>cz.vsb.fei.java2</groupId> + <artifactId>lab06</artifactId> + <version>0.0.1-SNAPSHOT</version> + + <name>lab06</name> + + <packaging>jar</packaging> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <maven.compiler.release>21</maven.compiler.release> + <JavaFX.version>22-ea+16</JavaFX.version> + <JUnit.version>5.10.1</JUnit.version> + <log4j.version>2.22.1</log4j.version> + <lombok.version>1.18.30</lombok.version> + </properties> + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.junit</groupId> + <artifactId>junit-bom</artifactId> + <version>${JUnit.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + + <dependencies> + <dependency> + <groupId>org.openjfx</groupId> + <artifactId>javafx-controls</artifactId> + <version>${JavaFX.version}</version> + </dependency> + <dependency> + <groupId>org.openjfx</groupId> + <artifactId>javafx-fxml</artifactId> + <version>${JavaFX.version}</version> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + <version>${log4j.version}</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-api</artifactId> + <version>${log4j.version}</version> + </dependency> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <version>${lombok.version}</version> + <scope>provided</scope> + </dependency> + + <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core --> + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-core</artifactId> + <version>6.4.4.Final</version> + </dependency> + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-jpamodelgen</artifactId> + <scope>provided</scope> + <version>6.4.4.Final</version> + </dependency> + + <!-- https://mvnrepository.com/artifact/com.h2database/h2 --> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <version>2.2.224</version> + </dependency> + + <!-- + https://mvnrepository.com/artifact/jakarta.persistence/jakarta.persistence-api --> + <dependency> + <groupId>jakarta.persistence</groupId> + <artifactId>jakarta.persistence-api</artifactId> + <version>3.1.0</version> + </dependency> + + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.12.1</version> + <configuration> + <annotationProcessorPaths> + <path> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <version>${lombok.version}</version> + </path> + <path> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-jpamodelgen</artifactId> + <version>6.4.4.Final</version> + </path> + </annotationProcessorPaths> + </configuration> + <executions> + <execution> + <id>process</id> + <phase>generate-sources</phase> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <version>3.5.0</version> + <configuration> + <sources> + <source>target/generated-sources/annotations</source> + </sources> + </configuration> + <executions> + <execution> + <id>add-source</id> + <phase>process-resources</phase> + <goals> + <goal>add-source</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <version>3.2.1</version> + </plugin> + </plugins> + </build> + +</project> diff --git a/src/main/java/cz/vsb/fei/java2/lab06/App.java b/src/main/java/cz/vsb/fei/java2/lab06/App.java new file mode 100644 index 0000000..9f04b57 --- /dev/null +++ b/src/main/java/cz/vsb/fei/java2/lab06/App.java @@ -0,0 +1,78 @@ +package cz.vsb.fei.java2.lab06; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.List; + +import org.h2.tools.Server; + +import cz.vsb.fei.java2.lab06.entities.Car; +import cz.vsb.fei.java2.lab06.entities.LegalPerson; +import cz.vsb.fei.java2.lab06.entities.Route; +import cz.vsb.fei.java2.lab06.entities.Vehicle; +import cz.vsb.fei.java2.lab06.repositories.PersonRepsository; +import cz.vsb.fei.java2.lab06.repositories.RouteRepsository; +import cz.vsb.fei.java2.lab06.repositories.VehicleRepsository; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; +import lombok.extern.log4j.Log4j2; + +/** + * Class <b>App</b> - extends class Application and it is an entry point of the + * program + * + * @author Java I + */ +@Log4j2 +public class App { + + public static void main(String[] args) { + log.info("Launching Java application."); + + EntityManagerFactory emf = Persistence.createEntityManagerFactory("java2"); + EntityManager em = emf.createEntityManager(); + + + //TODO: Create repositories + + //TODO: generate vehicles and persons + + //TODO: add existing person to existing vehicle as owner + + //TODO: generate new vehicle with new owner + + //TODO: generate routes and assign vehicles + // clear entity manager cache - start again with clear cache + em.clear(); + + //TODO: list routes, persons and vehicles + + em.close(); + startDBWebServerAndWait(); + } + + private static void startDBWebServerAndWait() { + // Start HTTP server for access H2 DB for look inside + try { + Server server = Server.createWebServer(); + log.info(server.getURL()); + server.start(); + log.info("Waitnig for Key press (ENTER)"); + waitForKeyPress(); + log.info("Ending DB web server BYE."); + server.stop(); + } catch (SQLException e) { + log.error("Cannot create DB web server.", e); + } + } + + private static void waitForKeyPress() { + try { + System.in.read(); + } catch (IOException e) { + log.error("Cannot read input from keyboard.", e); + } + } + +} \ No newline at end of file diff --git a/src/main/java/cz/vsb/fei/java2/lab06/Tools.java b/src/main/java/cz/vsb/fei/java2/lab06/Tools.java new file mode 100644 index 0000000..3ae8635 --- /dev/null +++ b/src/main/java/cz/vsb/fei/java2/lab06/Tools.java @@ -0,0 +1,83 @@ +package cz.vsb.fei.java2.lab06; + +import java.time.LocalDate; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +public class Tools { + + public static final Random RANDOM = new Random(); + + public static final List<String> FIRST_NAMES = Collections + .unmodifiableList(Arrays.asList("Petr", "Marie", "Jan", "Jana", "Tomáš", "KateÅ™ina", "Lukáš", "Tereza", + "Martin", "Veronika", "David", "Eva", "Jakub", "Lucie", "Michal", "Anna", "Adam", "Monika", "Tom", + "Klára", "Robert", "Kristýna", "Marek", "Simona", "Filip", "Petra", "OndÅ™ej", "Lenka", "MatÄ›j", + "Markéta", "Pavel", "Hana", "Jakub", "Adéla", "Daniel", "Barbora", "Lukáš", "EliÅ¡ka", "Josef")); + public static final List<String> LAST_NAMES = Collections.unmodifiableList(Arrays.asList("Novák", "Svoboda", + "Novotný", "Dvořák", "ÄŒerný", "Procházková", "KuÄera", "Veselý", "Horák", "NÄ›mec", "Pokorný", "MareÅ¡", + "PospÃÅ¡ilová", "Hájek", "JelÃnek", "Král", "RůžiÄka", "BeneÅ¡", "Fiala", "SedláÄek", "KřÞ", "NÄ›mcová", + "VlÄek", "Kolář", "BartoÅ¡", "BÃlý", "Veselá", "KovaÅ™Ãk", "Havelka", "Malý", "Urban", "Kopecký", "Vlach", + "Å imek", "KoneÄný", "Doležal", "Šťastný", "KopeÄná", "Holub", "PospÃchal")); + + public static final List<String> STREETS = Collections.unmodifiableList( + Arrays.asList("Panská", "HlavnÃ", "Ulice Nová", "NámÄ›stà Svobody", "HÅ™bitovnÃ", "RevoluÄnÃ", "Sadová", + "Jiráskova", "Å kolnÃ", "Vinohradská", "Komenského", "MÃrová", "KřÞová", "Masarykova", + "TÅ™Ãda Svobody", "Karlova", "Dlouhá", "Žižkova", "Purkyňova", "Rybářská", "Sokolská", "RybnÃÄek", + "Vrchlického", "Å tefánikova", "Veselá", "Lipová", "Na Hrázi", "Výšinná", "Nová Cesta", "ÄŒeská")); + public static final List<String> CITIES = Collections.unmodifiableList( + Arrays.asList("Praha", "Brno", "Ostrava", "Plzeň", "Liberec", "Olomouc", "ÄŒeské BudÄ›jovice", + "Hradec Králové", "Ústà nad Labem", "Pardubice", "ZlÃn", "Karlovy Vary", "Jihlava", "Tábor", + "HavÃÅ™ov", "ÄŒeský TěšÃn", "Mladá Boleslav", "Trutnov", "PÅ™erov", "Kladno", "Opava", "Frýdek-MÃstek", + "DÄ›ÄÃn", "Karviná", "Jablonec nad Nisou", "TÅ™ebÃÄ", "ŽÄár nad Sázavou", "KolÃn", "Uherské HradiÅ¡tÄ›", + "Znojmo", "ProstÄ›jov", "Litoměřice", "KroměřÞ", "Chomutov", "PÅ™Ãbram", "PÅ™Ãbram", "Cheb", + "Teplice", "Uherský Brod", "Sokolov", "BÅ™eclav", "LitvÃnov", "Klatovy", "VsetÃn", "Nový JiÄÃn")); + + public static final List<String> POST_NUMBER = Collections + .unmodifiableList(Arrays.asList("10000", "11000", "12000", "13000", "14000", "15000", "16000", "17000", + "18000", "19000", "20000", "21000", "22000", "23000", "24000", "25000", "26000", "27000", "28000", + "29000", "30000", "31000", "32000", "33000", "34000", "35000", "36000", "37000", "38000", "39000")); + + public static final List<String> COMPANY_NAMES = Collections.unmodifiableList(Arrays.asList("Inova", "Sprint", + "Polaris", "Forte", "Nexus", "Vertex", "Synergie", "Horizon", "Astra", "Axiom", "Optima", "Integra", + "Evolve", "Apex", "Dynasty", "Eclipse", "Paragon", "Fusion", "Oasis", "Equinox", "Voyage", "Genesis", + "Zenith", "Elite", "Harmony", "Stratos", "Aurora", "Quantum", "Spectrum")); + + public static String generateCompanyName() { + StringBuilder name = new StringBuilder(); + int numberOfWords = RANDOM.nextInt(2) + 1; + for (int j = 0; j < numberOfWords; j++) { + name.append(randomElementFrom(COMPANY_NAMES)); + if (j < numberOfWords - 1) { + name.append(" "); + } + } + return name.toString(); + } + + public static String generateAddress() { + return String.format("%s %d, %s, %s", randomElementFrom(STREETS), RANDOM.nextInt(99) + 1, + randomElementFrom(CITIES), randomElementFrom(POST_NUMBER)); + } + + public static <T> T randomElementFrom(List<T> list) { + return randomElementFrom(list, RANDOM); + } + + public static <T> T randomElementFrom(List<T> list, Random r) { + if (list.isEmpty()) { + return null; + } + return list.get(r.nextInt(list.size())); + } + + public static LocalDate generatePreviousDate() { + return LocalDate.of(LocalDate.now().getYear() - RANDOM.nextInt(80), RANDOM.nextInt(12) + 1, 1) + .plusDays(RANDOM.nextInt(31)); + } + + private Tools() { + /* hide public one - nothing to do */ + } +} diff --git a/src/main/java/cz/vsb/fei/java2/lab06/entities/BaseEntity.java b/src/main/java/cz/vsb/fei/java2/lab06/entities/BaseEntity.java new file mode 100644 index 0000000..1156a70 --- /dev/null +++ b/src/main/java/cz/vsb/fei/java2/lab06/entities/BaseEntity.java @@ -0,0 +1,26 @@ +package cz.vsb.fei.java2.lab06.entities; + +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.MappedSuperclass; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; + +/** + * Implementation of design pattern layer supertype + * https://martinfowler.com/eaaCatalog/layerSupertype.html + */ +@EqualsAndHashCode(onlyExplicitlyIncluded = true) +@ToString +@MappedSuperclass +public abstract class BaseEntity { + + @EqualsAndHashCode.Include + @Getter + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + +} diff --git a/src/main/java/cz/vsb/fei/java2/lab06/entities/Car.java b/src/main/java/cz/vsb/fei/java2/lab06/entities/Car.java new file mode 100644 index 0000000..9d02118 --- /dev/null +++ b/src/main/java/cz/vsb/fei/java2/lab06/entities/Car.java @@ -0,0 +1,68 @@ +package cz.vsb.fei.java2.lab06.entities; + +import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.DESTINATION; +import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.START; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Random; +import java.util.stream.Collectors; + +import cz.vsb.fei.java2.lab06.Tools; +import cz.vsb.fei.java2.lab06.entities.Route.RoutePartType; +import jakarta.persistence.Entity; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString(callSuper = true) +public class Car extends Vehicle { + + private static final List<String> COLORS = Collections.unmodifiableList((Arrays.asList("ÄŒerná perla", + "Diamantová bÃlá", "Lunárnà stÅ™Ãbro", "Kosmická Å¡edá", "Azure modrá", "Rubinová Äervená", + "SmaragdovÄ› zelená", "Kávová krémová", "SluneÄnà oranžová", "Zlatá svÃtilna", "Ametystová fialová", + "Růžová sváteÄnÃ", "Temná oceánská modÅ™", "MÄ›sÃÄnÄ› Å¡edá", "ŽárivÄ› rudá", "Lesklá zelená", + "Hluboká Äokoládová", "MyslÃnská oranžová", "SluneÄnà žlutá", "Å eÅ™ÃkovÄ› fialová"))); + + private int numberOfSeats; + private String color; + + @Override + public String planeRoute(String start, String destination) { + List<RoutePartType> route = new ArrayList<>(); + Random r = new Random(Objects.hash(start, destination)); + int count = r.nextInt(20) + 5; + route.add(START); + List<RoutePartType> parts = new ArrayList<>(Arrays.asList(RoutePartType.values())); + parts.remove(START); + parts.remove(DESTINATION); + for (int i = 0; i < count; i++) { + route.add(parts.get(r.nextInt(parts.size()))); + } + route.add(DESTINATION); + return route.stream().map(RoutePartType::getSign).collect(Collectors.joining()); + } + + @Override + public boolean isRouteAcceptable(String routeDescription) { + return true; + } + + public Car(String registartionNumber, int maxSpeed, String producerName, int numberOfSeats, String color) { + super(registartionNumber, maxSpeed, producerName); + this.numberOfSeats = numberOfSeats; + this.color = color; + } + + public static Car generate() { + return new Car(generateRegistrationNumber(), Tools.RANDOM.nextInt(100) + 120, + Tools.randomElementFrom(PRODUCERS), Tools.RANDOM.nextInt(5) + 2, Tools.randomElementFrom(COLORS)); + } + +} diff --git a/src/main/java/cz/vsb/fei/java2/lab06/entities/JuridicalPerson.java b/src/main/java/cz/vsb/fei/java2/lab06/entities/JuridicalPerson.java new file mode 100644 index 0000000..67bf5d7 --- /dev/null +++ b/src/main/java/cz/vsb/fei/java2/lab06/entities/JuridicalPerson.java @@ -0,0 +1,46 @@ +package cz.vsb.fei.java2.lab06.entities; + +import java.util.Arrays; + +import cz.vsb.fei.java2.lab06.Tools; +import jakarta.persistence.Entity; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString(callSuper = true) +public class JuridicalPerson extends LegalPerson { + + private String companyName; + private CompanyType type; + + public JuridicalPerson(String companyName, String address, CompanyType type) { + super(address); + this.companyName = companyName; + this.type = type; + } + + @AllArgsConstructor + @Getter + public enum CompanyType { + SPOLECNOST_S_RUCENIM_OMEYENZM("s.r.o."), AKCIOVA_SPOLECNOST("a.s."), ZAPSANY_SPOLEK("z.s."), + KOMANDITNI_SPOLECNOST("k.s."), VEREJNA_OBCHODNI_SPOLECNOST("v.o.s."), EVROPSKA_AKCIOVA_SPOLECNOST("SE"); + + private String description; + } + + @Override + public String getFullName() { + return String.format("%s %s", getCompanyName(), getType().getDescription()); + } + + public static JuridicalPerson generate() { + return new JuridicalPerson(Tools.generateCompanyName(), Tools.generateAddress(), + Tools.randomElementFrom(Arrays.asList(CompanyType.values()))); + } + +} diff --git a/src/main/java/cz/vsb/fei/java2/lab06/entities/LegalPerson.java b/src/main/java/cz/vsb/fei/java2/lab06/entities/LegalPerson.java new file mode 100644 index 0000000..c35daad --- /dev/null +++ b/src/main/java/cz/vsb/fei/java2/lab06/entities/LegalPerson.java @@ -0,0 +1,36 @@ +package cz.vsb.fei.java2.lab06.entities; + +import java.util.Set; + +import cz.vsb.fei.java2.lab06.Tools; +import jakarta.persistence.Entity; +import jakarta.persistence.OneToMany; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString(callSuper = true) +public abstract class LegalPerson extends BaseEntity { + + private String address; + + @ToString.Exclude + private Set<Vehicle> ownedVewhicles; + + protected LegalPerson(String address) { + this.address = address; + } + + public abstract String getFullName(); + + public static LegalPerson generate() { + if (Tools.RANDOM.nextBoolean()) { + return JuridicalPerson.generate(); + } else { + return NaturalPerson.generate(); + } + } +} diff --git a/src/main/java/cz/vsb/fei/java2/lab06/entities/Motorbike.java b/src/main/java/cz/vsb/fei/java2/lab06/entities/Motorbike.java new file mode 100644 index 0000000..14d6074 --- /dev/null +++ b/src/main/java/cz/vsb/fei/java2/lab06/entities/Motorbike.java @@ -0,0 +1,71 @@ +package cz.vsb.fei.java2.lab06.entities; + +import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.CROSSROAD; +import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.DESTINATION; +import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.SPEED_UP; +import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.*; +import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.START; +import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.STRAIGHT; +import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.TURN_LEFT; +import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.TURN_RIGHT; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Random; +import java.util.Set; +import java.util.stream.Collectors; + +import cz.vsb.fei.java2.lab06.Tools; +import cz.vsb.fei.java2.lab06.entities.Route.RoutePartType; +import jakarta.persistence.Entity; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString(callSuper = true) +public class Motorbike extends Vehicle { + + private boolean storageBox; + + private static Set<RoutePartType> allowedRouteParts = Collections.unmodifiableSet(new HashSet<>(Arrays + .asList(SLOW_DOWN, SPEED_UP, ROUNDABOUT, CROSSROAD, DESTINATION, START, STRAIGHT, TURN_LEFT, TURN_RIGHT))); + + public Motorbike(String registartionNumber, int maxSpeed, String producerName, boolean storageBox) { + super(registartionNumber, maxSpeed, producerName); + this.storageBox = storageBox; + } + + @Override + public String planeRoute(String start, String destination) { + List<RoutePartType> route = new ArrayList<>(); + Random r = new Random(Objects.hash(start, destination)); + int count = r.nextInt(30) + 8; + route.add(START); + List<RoutePartType> parts = Arrays.asList(CROSSROAD, SPEED_UP, SPEED_UP, SPEED_UP, SPEED_UP, SPEED_UP, SPEED_UP, + SPEED_UP, SPEED_UP, STRAIGHT, STRAIGHT, STRAIGHT, STRAIGHT, STRAIGHT, STRAIGHT, STRAIGHT, STRAIGHT, + STRAIGHT, STRAIGHT, STRAIGHT, STRAIGHT, STRAIGHT, TURN_LEFT, TURN_RIGHT); + for (int i = 0; i < count; i++) { + route.add(Tools.randomElementFrom(parts, r)); + } + route.add(DESTINATION); + return route.stream().map(RoutePartType::getSign).collect(Collectors.joining()); + } + + @Override + public boolean isRouteAcceptable(String routeDescription) { + return RoutePartType.parse(routeDescription).stream().allMatch(part -> allowedRouteParts.contains(part)); + } + + public static Motorbike generateMotorbike() { + return new Motorbike(generateRegistrationNumber(), Tools.RANDOM.nextInt(150) + 180, + Tools.randomElementFrom(PRODUCERS), Tools.RANDOM.nextBoolean()); + } + +} diff --git a/src/main/java/cz/vsb/fei/java2/lab06/entities/NaturalPerson.java b/src/main/java/cz/vsb/fei/java2/lab06/entities/NaturalPerson.java new file mode 100644 index 0000000..4f4cc52 --- /dev/null +++ b/src/main/java/cz/vsb/fei/java2/lab06/entities/NaturalPerson.java @@ -0,0 +1,42 @@ +package cz.vsb.fei.java2.lab06.entities; + +import java.time.LocalDate; + +import cz.vsb.fei.java2.lab06.Tools; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString(callSuper = true) +public class NaturalPerson extends LegalPerson { + + @Column(nullable = false) + private String firstName; + @Column(nullable = false) + private String lastName; + + private LocalDate dayOfBirth; + + public NaturalPerson(String firstName, String lastName, String address, LocalDate dayOfBirth) { + super(address); + this.firstName = firstName; + this.lastName = lastName; + this.dayOfBirth = dayOfBirth; + } + + @Override + public String getFullName() { + return String.format("%s %s", getFirstName(), getLastName()); + } + + public static NaturalPerson generate() { + return new NaturalPerson(Tools.randomElementFrom(Tools.FIRST_NAMES), Tools.randomElementFrom(Tools.LAST_NAMES), + Tools.generateAddress(), Tools.generatePreviousDate()); + } + +} diff --git a/src/main/java/cz/vsb/fei/java2/lab06/entities/Route.java b/src/main/java/cz/vsb/fei/java2/lab06/entities/Route.java new file mode 100644 index 0000000..d9d1267 --- /dev/null +++ b/src/main/java/cz/vsb/fei/java2/lab06/entities/Route.java @@ -0,0 +1,60 @@ +package cz.vsb.fei.java2.lab06.entities; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import cz.vsb.fei.java2.lab06.Tools; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.ManyToMany; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@AllArgsConstructor +@ToString(callSuper = true) +public class Route extends BaseEntity { + + private String start; + private String destination; + private String description; + + private List<Vehicle> assignedCars; + + public static Route generate() { + return new Route(Tools.randomElementFrom(Tools.CITIES), Tools.randomElementFrom(Tools.CITIES), null, + new ArrayList<Vehicle>()); + } + + @AllArgsConstructor + @Getter + public enum RoutePartType { + START("↦"), STRAIGHT("âž™"), TURN_LEFT("â¬"), TURN_RIGHT("↴"), U_TURN("⮌"), CROSSROAD("⤨"), ROUNDABOUT("â¥"), + SLOW_DOWN("â‡"), SPEED_UP("↠"), DESTINATION("⇥"); + + private String sign; + + public static RoutePartType of(String part) { + for (RoutePartType type : values()) { + if (Objects.equals(type.getSign(), part)) { + return type; + } + } + return null; + } + + public static List<RoutePartType> parse(String s) { + List<RoutePartType> result = new ArrayList<>(s.length()); + for (int i = 0; i < s.length(); i++) { + result.add(of(String.valueOf(s.charAt(i)))); + } + return result; + } + } + +} diff --git a/src/main/java/cz/vsb/fei/java2/lab06/entities/Truck.java b/src/main/java/cz/vsb/fei/java2/lab06/entities/Truck.java new file mode 100644 index 0000000..913d587 --- /dev/null +++ b/src/main/java/cz/vsb/fei/java2/lab06/entities/Truck.java @@ -0,0 +1,71 @@ +package cz.vsb.fei.java2.lab06.entities; + +import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.CROSSROAD; +import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.DESTINATION; +import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.SLOW_DOWN; +import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.START; +import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.STRAIGHT; +import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.TURN_LEFT; +import static cz.vsb.fei.java2.lab06.entities.Route.RoutePartType.TURN_RIGHT; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Random; +import java.util.Set; +import java.util.stream.Collectors; + +import cz.vsb.fei.java2.lab06.Tools; +import cz.vsb.fei.java2.lab06.entities.Route.RoutePartType; +import jakarta.persistence.Entity; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString(callSuper = true) +public class Truck extends Vehicle { + + private static Set<RoutePartType> allowedRouteParts = Collections.unmodifiableSet( + new HashSet<>(Arrays.asList(SLOW_DOWN, CROSSROAD, DESTINATION, START, STRAIGHT, TURN_LEFT, TURN_RIGHT))); + + private int maxLoadVolume; + private int maxLoadWeight; + + public Truck(String registartionNumber, int maxSpeed, String producerName, int maxLoadVolume, int maxLoadWeight) { + super(registartionNumber, maxSpeed, producerName); + this.maxLoadVolume = maxLoadVolume; + this.maxLoadWeight = maxLoadWeight; + } + + @Override + public String planeRoute(String start, String destination) { + List<RoutePartType> route = new ArrayList<>(); + Random r = new Random(Objects.hash(start, destination)); + int count = r.nextInt(30) + 8; + route.add(START); + List<RoutePartType> parts = Arrays.asList(CROSSROAD, SLOW_DOWN, STRAIGHT, STRAIGHT, STRAIGHT, STRAIGHT, + STRAIGHT, TURN_LEFT, TURN_LEFT, TURN_LEFT, TURN_RIGHT, TURN_RIGHT, TURN_RIGHT); + for (int i = 0; i < count; i++) { + route.add(Tools.randomElementFrom(parts, r)); + } + route.add(DESTINATION); + return route.stream().map(RoutePartType::getSign).collect(Collectors.joining()); + } + + @Override + public boolean isRouteAcceptable(String routeDescription) { + return RoutePartType.parse(routeDescription).stream().allMatch(part -> allowedRouteParts.contains(part)); + } + + public static Truck generate() { + return new Truck(generateRegistrationNumber(), Tools.RANDOM.nextInt(100) + 80, + Tools.randomElementFrom(PRODUCERS), Tools.RANDOM.nextInt(500), Tools.RANDOM.nextInt(1000)); + } + +} diff --git a/src/main/java/cz/vsb/fei/java2/lab06/entities/Vehicle.java b/src/main/java/cz/vsb/fei/java2/lab06/entities/Vehicle.java new file mode 100644 index 0000000..b8b0c74 --- /dev/null +++ b/src/main/java/cz/vsb/fei/java2/lab06/entities/Vehicle.java @@ -0,0 +1,68 @@ +package cz.vsb.fei.java2.lab06.entities; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import cz.vsb.fei.java2.lab06.Tools; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.ManyToOne; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString(callSuper = true) +public abstract class Vehicle extends BaseEntity { + + protected static final List<String> PRODUCERS = Collections.unmodifiableList(Arrays.asList("Toyota", "Volkswagen", + "BMW", "Mercedes-Benz", "Ford", "Audi", "Honda", "Chevrolet", "Nissan", "Hyundai", "Kia", "Tesla", "Subaru", + "Mazda", "Fiat", "Volvo", "Peugeot", "Renault", "Porsche", "Jaguar", "Land Rover", "Mitsubishi", "Suzuki", + "Citroën", "Dodge", "Jeep", "Chrysler", "Lexus", "Infiniti", "Acura", "Buick", "Cadillac", "Lincoln", "GMC", + "Alfa Romeo", "Mini", "Smart", "Dacia", "Seat", "Å koda")); + + protected String registartionNumber; + + private int maxSpeed; + + private String producerName; + + private LegalPerson owner; + + @ToString.Exclude + private List<Route> planedRoute; + + protected Vehicle(String registartionNumber, int maxSpeed, String producerName) { + super(); + this.registartionNumber = registartionNumber; + this.maxSpeed = maxSpeed; + this.producerName = producerName; + } + + public abstract String planeRoute(String start, String destination); + + public abstract boolean isRouteAcceptable(String routeDescription); + + public static String generateRegistrationNumber() { + return String.format("%d%c%d-%04d", Tools.RANDOM.nextInt(9) + 1, Tools.RANDOM.nextInt('Z' - 'A') + 'A', + Tools.RANDOM.nextInt(9) + 1, Tools.RANDOM.nextInt(9999) + 1); + } + + public static Vehicle generate() { + switch (Tools.RANDOM.nextInt(3)) { + case 0: + return Car.generate(); + case 1: + return Truck.generate(); + case 2: + return Motorbike.generateMotorbike(); + default: + return null; + } + } +} diff --git a/src/main/java/cz/vsb/fei/java2/lab06/repositories/BaseRepository.java b/src/main/java/cz/vsb/fei/java2/lab06/repositories/BaseRepository.java new file mode 100644 index 0000000..42e64c1 --- /dev/null +++ b/src/main/java/cz/vsb/fei/java2/lab06/repositories/BaseRepository.java @@ -0,0 +1,51 @@ +package cz.vsb.fei.java2.lab06.repositories; + +import java.util.List; + +import cz.vsb.fei.java2.lab06.entities.BaseEntity; +import jakarta.persistence.EntityManager; + +public class BaseRepository<T extends BaseEntity> { + + protected EntityManager em; + private Class<T> clazz; + + public BaseRepository(EntityManager em, Class<T> clazz) { + this.em = em; + this.clazz = clazz; + } + + public T find(Long id) { + return em.find(clazz, id); + } + + public List<T> findAll() { + return em.createQuery(String.format("SELECT e FROM %s e", clazz.getName()), clazz).getResultList(); + } + + public T saveInTranasction(T entity) { + em.getTransaction().begin(); + entity = save(entity); + em.getTransaction().commit(); + return entity; + } + + public T save(T entity) { + if (entity.getId() == null || entity.getId() == 0) { + em.persist(entity); + } else { + entity = em.merge(entity); + } + return entity; + } + + public void remove(T entity) { + em.remove(entity); + } + + public void removeInTransaction(T entity) { + em.getTransaction().begin(); + remove(entity); + em.getTransaction().commit(); + } +} diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java new file mode 100644 index 0000000..d7baa2d --- /dev/null +++ b/src/main/java/module-info.java @@ -0,0 +1,15 @@ +module cz.vsb.fei.java2.lab05 { + requires transitive javafx.controls; + requires javafx.fxml; + opens cz.vsb.fei.java2.lab06 to javafx.fxml; + exports cz.vsb.fei.java2.lab06; + + requires static lombok; + requires org.apache.logging.log4j; + + requires jakarta.persistence; + requires jakarta.annotation; + requires com.h2database; + opens cz.vsb.fei.java2.lab06.entities; + requires org.hibernate.orm.core; +} \ No newline at end of file diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml new file mode 100644 index 0000000..010c3ff --- /dev/null +++ b/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- JBoss, Home of Professional Open Source Copyright 2013, Red Hat, Inc. + and/or its affiliates, and individual contributors by the @authors tag. See + the copyright.txt in the distribution for a full listing of individual contributors. + 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 http://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. --> +<persistence version="2.0" + xmlns="http://java.sun.com/xml/ns/persistence" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://java.sun.com/xml/ns/persistence + http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> + <persistence-unit name="java2" + transaction-type="RESOURCE_LOCAL"> + <!-- <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> --> + + <!-- If you are running in a production environment, add a managed data + source, this example data source is just for development and testing! --> + <properties> + <!-- Properties for JPA (for any provider) --> + <!-- DB Apache Derby <property name="jakarta.persistence.jdbc.url" value="jdbc:derby:db/lab05;create=true" + /> <property name="jakarta.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" + /> --> + + <property name="jakarta.persistence.jdbc.url" + value="jdbc:h2:file:./db/java2" /> + <!-- In memory DB no store to disk <property name="jakarta.persistence.jdbc.url" + value="jdbc:h2:mem:java2" /> --> + <property name="jakarta.persistence.jdbc.driver" + value="org.h2.Driver" /> + + <property name="jakarta.persistence.jdbc.user" value="app" /> + <property name="jakarta.persistence.jdbc.password" + value="app" /> + <property + name="jakarta.persistence.schema-generation.database.action" + value="create"></property> + + <!-- Properties for Hibernate --> + <!-- property name="hibernate.enable_lazy_load_no_trans" + value="true" /--> + <property name="hibernate.show_sql" value="false" /> + <property name="hibernate.format_sql" value="true" /> + <!-- <property name="hibernate.hbm2ddl.auto" value="update" /> --> + + </properties> + </persistence-unit> + +</persistence> diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml new file mode 100644 index 0000000..acb3514 --- /dev/null +++ b/src/main/resources/log4j2.xml @@ -0,0 +1,13 @@ +<Configuration> + <Appenders> + <Console name="Console"> + <PatternLayout + pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /> + </Console> + </Appenders> + <Loggers> + <Root level="info"> + <AppenderRef ref="Console"></AppenderRef> + </Root> + </Loggers> +</Configuration> diff --git a/src/test/java/cz/vsb/fei/java2/lab06/AppTest.java b/src/test/java/cz/vsb/fei/java2/lab06/AppTest.java new file mode 100644 index 0000000..7203982 --- /dev/null +++ b/src/test/java/cz/vsb/fei/java2/lab06/AppTest.java @@ -0,0 +1,19 @@ +package cz.vsb.fei.java2.lab06; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +/** + * Unit test for simple App. + */ +class AppTest { + + /** + * Rigorous Test :-) + */ + @Test + void shouldAnswerWithTrue() { + assertTrue(true); + } +} -- GitLab