From 91c731fef4bac1ee0b239577af230c3221870547 Mon Sep 17 00:00:00 2001 From: jzitnik-dev Date: Tue, 9 Dec 2025 15:40:47 +0100 Subject: [PATCH] initial commit --- .gitignore | 39 ++++++++ .idea/.gitignore | 3 + .idea/encodings.xml | 9 ++ .idea/misc.xml | 14 +++ .idea/vcs.xml | 6 ++ kontakty.txt | 3 + pom.xml | 25 +++++ quotes.txt | 9 ++ src/main/java/cz/jzitnik/Console.java | 95 +++++++++++++++++++ src/main/java/cz/jzitnik/Main.java | 9 ++ .../cz/jzitnik/annotations/CommandImpl.java | 12 +++ .../java/cz/jzitnik/annotations/Config.java | 11 +++ .../java/cz/jzitnik/annotations/Data.java | 11 +++ .../cz/jzitnik/commands/ContactCommand.java | 52 ++++++++++ .../cz/jzitnik/commands/DateTimeCommand.java | 14 +++ .../cz/jzitnik/commands/HistoryCommand.java | 20 ++++ .../cz/jzitnik/commands/QuadraticCommand.java | 44 +++++++++ .../cz/jzitnik/commands/QuoteCommand.java | 32 +++++++ .../cz/jzitnik/commands/models/Command.java | 5 + .../config/ContactRepositoryConfigImpl.java | 12 +++ .../cz/jzitnik/config/QuoteConfigImpl.java | 12 +++ .../models/ContactRepositoryConfig.java | 5 + .../cz/jzitnik/config/models/QuoteConfig.java | 5 + src/main/java/cz/jzitnik/factory/Contact.java | 25 +++++ .../jzitnik/repository/ContactRepository.java | 86 +++++++++++++++++ .../cz/jzitnik/services/ClassFactory.java | 78 +++++++++++++++ .../cz/jzitnik/services/CommandHistory.java | 19 ++++ .../cz/jzitnik/services/CommandInvoker.java | 35 +++++++ 28 files changed, 690 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/encodings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/vcs.xml create mode 100644 kontakty.txt create mode 100644 pom.xml create mode 100644 quotes.txt create mode 100644 src/main/java/cz/jzitnik/Console.java create mode 100644 src/main/java/cz/jzitnik/Main.java create mode 100644 src/main/java/cz/jzitnik/annotations/CommandImpl.java create mode 100644 src/main/java/cz/jzitnik/annotations/Config.java create mode 100644 src/main/java/cz/jzitnik/annotations/Data.java create mode 100644 src/main/java/cz/jzitnik/commands/ContactCommand.java create mode 100644 src/main/java/cz/jzitnik/commands/DateTimeCommand.java create mode 100644 src/main/java/cz/jzitnik/commands/HistoryCommand.java create mode 100644 src/main/java/cz/jzitnik/commands/QuadraticCommand.java create mode 100644 src/main/java/cz/jzitnik/commands/QuoteCommand.java create mode 100644 src/main/java/cz/jzitnik/commands/models/Command.java create mode 100644 src/main/java/cz/jzitnik/config/ContactRepositoryConfigImpl.java create mode 100644 src/main/java/cz/jzitnik/config/QuoteConfigImpl.java create mode 100644 src/main/java/cz/jzitnik/config/models/ContactRepositoryConfig.java create mode 100644 src/main/java/cz/jzitnik/config/models/QuoteConfig.java create mode 100644 src/main/java/cz/jzitnik/factory/Contact.java create mode 100644 src/main/java/cz/jzitnik/repository/ContactRepository.java create mode 100644 src/main/java/cz/jzitnik/services/ClassFactory.java create mode 100644 src/main/java/cz/jzitnik/services/CommandHistory.java create mode 100644 src/main/java/cz/jzitnik/services/CommandInvoker.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..480bdf5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ +.kotlin + +### 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 \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..c92aa37 --- /dev/null +++ b/.idea/encodings.xml @@ -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..039a9d1 --- /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/kontakty.txt b/kontakty.txt new file mode 100644 index 0000000..89c61aa --- /dev/null +++ b/kontakty.txt @@ -0,0 +1,3 @@ +Jan;Novak;1990-05-12;jan.novak@email.com;777123456 +Petra;Svobodova;1985-11-02;petra.svobodova@email.com;777654321 +Karel;Dvorak;2000-07-20;karel.dvorak@email.com;777987654 \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..38760fa --- /dev/null +++ b/pom.xml @@ -0,0 +1,25 @@ + + + 4.0.0 + + cz.jzitnik + commandmezabijejednou + 1.0-SNAPSHOT + + + 22 + 22 + UTF-8 + + + + + org.reflections + reflections + 0.10.2 + + + + \ No newline at end of file diff --git a/quotes.txt b/quotes.txt new file mode 100644 index 0000000..b1fbb9d --- /dev/null +++ b/quotes.txt @@ -0,0 +1,9 @@ +“Matematika je jazyk, kterým Bůh napsal vesmír.” – Galileo Galilei +“Neexistuje žádná krása bez harmonie.” – Plato +“Život je jako jízda na kole. Abys udržel rovnováhu, musíš se pohybovat vpřed.” – Albert Einstein +“V každém problému se skrývá řešení.” – Neznámý +“Pranostika: Na svatého Jiří přijde jaro brzy, nebo později zima zhoustne.” +E=mc^2 +F = ma +a^2 + b^2 = c^2 +∑_{i=1}^{n} i = n(n+1)/2 \ No newline at end of file diff --git a/src/main/java/cz/jzitnik/Console.java b/src/main/java/cz/jzitnik/Console.java new file mode 100644 index 0000000..861c006 --- /dev/null +++ b/src/main/java/cz/jzitnik/Console.java @@ -0,0 +1,95 @@ +package cz.jzitnik; + +import cz.jzitnik.annotations.CommandImpl; +import cz.jzitnik.commands.models.Command; +import cz.jzitnik.services.ClassFactory; +import cz.jzitnik.services.CommandHistory; +import cz.jzitnik.services.CommandInvoker; +import org.reflections.Reflections; + +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.List; +import java.util.Scanner; + +public class Console implements Runnable { + private final CommandInvoker invoker = new CommandInvoker(); + private final ClassFactory factory = new ClassFactory(); + + @Override + public void run() { + factory.load(); + loadCommands(); + Scanner sc = new Scanner(System.in); + System.out.println("Type 'help' for commands."); + + boolean running = true; + + while (running) { + System.out.print("-> "); + + String input = sc.nextLine(); + ((CommandHistory) factory.get(CommandHistory.class)).add(input); + + if (input.equals("stop")) { + running = false; + continue; + } + + if (input.equals("help")) { + HashMap commands = invoker.getCommands(); + System.out.println(commands.keySet()); + continue; + } + + String[] parts = input.split(" ", 2); + String cmd = parts[0]; + String args2 = parts.length > 1 ? parts[1] : ""; + + String result = invoker.execute(cmd, args2); + System.out.println(result); + } + + sc.close(); + } + + private void loadCommands() { + Reflections reflections = new Reflections("cz.jzitnik.commands"); + List> entityClasses = + reflections.getTypesAnnotatedWith(CommandImpl.class).stream() + .filter(Command.class::isAssignableFrom) + .map(i -> (Class) i) + .toList(); + + for (Class command : entityClasses) { + CommandImpl annotation = command.getAnnotation(CommandImpl.class); + for (var constructor : command.getDeclaredConstructors()) { + + var paramTypes = constructor.getParameterTypes(); + var params = new Object[paramTypes.length]; + boolean suitable = true; + + for (int i = 0; i < paramTypes.length; i++) { + Class type = paramTypes[i]; + if (factory.contains(type)) + params[i] = factory.get(type); + else { + suitable = false; + break; + } + } + + if (suitable) { + constructor.setAccessible(true); + try { + Command instance = (Command) constructor.newInstance(params); + invoker.register(annotation.value(), instance); + } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) { + throw new RuntimeException(e); + } + break; // Found a matching constructor, go to next class + } + } + } + } +} diff --git a/src/main/java/cz/jzitnik/Main.java b/src/main/java/cz/jzitnik/Main.java new file mode 100644 index 0000000..91a9d76 --- /dev/null +++ b/src/main/java/cz/jzitnik/Main.java @@ -0,0 +1,9 @@ +package cz.jzitnik; + + +public class Main { + public static void main(String[] args) { + Console console = new Console(); + console.run(); + } +} diff --git a/src/main/java/cz/jzitnik/annotations/CommandImpl.java b/src/main/java/cz/jzitnik/annotations/CommandImpl.java new file mode 100644 index 0000000..d2d0287 --- /dev/null +++ b/src/main/java/cz/jzitnik/annotations/CommandImpl.java @@ -0,0 +1,12 @@ +package cz.jzitnik.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface CommandImpl { + String value(); +} diff --git a/src/main/java/cz/jzitnik/annotations/Config.java b/src/main/java/cz/jzitnik/annotations/Config.java new file mode 100644 index 0000000..b9e1667 --- /dev/null +++ b/src/main/java/cz/jzitnik/annotations/Config.java @@ -0,0 +1,11 @@ +package cz.jzitnik.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface Config { +} diff --git a/src/main/java/cz/jzitnik/annotations/Data.java b/src/main/java/cz/jzitnik/annotations/Data.java new file mode 100644 index 0000000..af18d90 --- /dev/null +++ b/src/main/java/cz/jzitnik/annotations/Data.java @@ -0,0 +1,11 @@ +package cz.jzitnik.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface Data { +} diff --git a/src/main/java/cz/jzitnik/commands/ContactCommand.java b/src/main/java/cz/jzitnik/commands/ContactCommand.java new file mode 100644 index 0000000..5430f6e --- /dev/null +++ b/src/main/java/cz/jzitnik/commands/ContactCommand.java @@ -0,0 +1,52 @@ +package cz.jzitnik.commands; + +import cz.jzitnik.annotations.CommandImpl; +import cz.jzitnik.commands.models.Command; +import cz.jzitnik.factory.Contact; +import cz.jzitnik.repository.ContactRepository; + +@CommandImpl("contacts ") +public class ContactCommand implements Command { + + private final ContactRepository cm; + + public ContactCommand(ContactRepository cm) { + this.cm = cm; + } + + @Override + public String execute(String args) { + // `args` ve formátu: + // add;jmeno;prijmeni;datum;email;telefon + // delete;telefon + // searchln;prijmeni + // searchph;telefon + // edit;staryTelefon;jmeno;prijmeni;datum;email;telefon + + String[] p = args.split(";"); + return switch (p[0]) { + case "add" -> { + Contact c = new Contact(); + c.firstName = p[1]; + c.lastName = p[2]; + c.birthdate = p[3]; + c.email = p[4]; + c.phone = p[5]; + yield cm.add(c); + } + case "delete" -> cm.delete(p[1]); + case "searchln" -> cm.searchLastName(p[1]); + case "searchph" -> cm.searchPhone(p[1]); + case "edit" -> { + Contact c = new Contact(); + c.firstName = p[2]; + c.lastName = p[3]; + c.birthdate = p[4]; + c.email = p[5]; + c.phone = p[6]; + yield cm.edit(p[1], c); + } + default -> String.join("\n", cm.getContacts().stream().map(Contact::toString).toList()); + }; + } +} diff --git a/src/main/java/cz/jzitnik/commands/DateTimeCommand.java b/src/main/java/cz/jzitnik/commands/DateTimeCommand.java new file mode 100644 index 0000000..1953349 --- /dev/null +++ b/src/main/java/cz/jzitnik/commands/DateTimeCommand.java @@ -0,0 +1,14 @@ +package cz.jzitnik.commands; + +import cz.jzitnik.annotations.CommandImpl; +import cz.jzitnik.commands.models.Command; + +import java.time.LocalDateTime; + +@CommandImpl("datetime") +public class DateTimeCommand implements Command { + @Override + public String execute(String args) { + return LocalDateTime.now().toString(); + } +} diff --git a/src/main/java/cz/jzitnik/commands/HistoryCommand.java b/src/main/java/cz/jzitnik/commands/HistoryCommand.java new file mode 100644 index 0000000..ce9ec65 --- /dev/null +++ b/src/main/java/cz/jzitnik/commands/HistoryCommand.java @@ -0,0 +1,20 @@ +package cz.jzitnik.commands; + +import cz.jzitnik.annotations.CommandImpl; +import cz.jzitnik.commands.models.Command; +import cz.jzitnik.services.CommandHistory; + +@CommandImpl("history") +public class HistoryCommand implements Command { + + private final CommandHistory history; + + public HistoryCommand(CommandHistory h) { + this.history = h; + } + + @Override + public String execute(String args) { + return String.join("\n", history.getAll()); + } +} diff --git a/src/main/java/cz/jzitnik/commands/QuadraticCommand.java b/src/main/java/cz/jzitnik/commands/QuadraticCommand.java new file mode 100644 index 0000000..c951167 --- /dev/null +++ b/src/main/java/cz/jzitnik/commands/QuadraticCommand.java @@ -0,0 +1,44 @@ +package cz.jzitnik.commands; + +import cz.jzitnik.annotations.CommandImpl; +import cz.jzitnik.commands.models.Command; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@CommandImpl("quadratic Ax^2+Bx+C") +public class QuadraticCommand implements Command { + + @Override + public String execute(String eq) { + try { + eq = eq.replace(" ", ""); + + Pattern p = Pattern.compile("([+-]?\\d*)x\\^2([+-]\\d*)x([+-]\\d+)"); + Matcher m = p.matcher(eq); + + if (!m.matches()) { + return "Neplatný formát. Example: 4x^2+3x-2"; + } + + double A = m.group(1).equals("") || m.group(1).equals("+") ? 1 : + m.group(1).equals("-") ? -1 : Double.parseDouble(m.group(1)); + double B = Double.parseDouble(m.group(2)); + double C = Double.parseDouble(m.group(3)); + + double D = B * B - 4 * A * C; + + if (D < 0) { + return "Žádné reálné kořeny."; + } + + double x1 = (-B + Math.sqrt(D)) / (2 * A); + double x2 = (-B - Math.sqrt(D)) / (2 * A); + + return "Kořeny: " + x1 + ", " + x2; + + } catch (Exception e) { + return "Error parsing equation."; + } + } +} diff --git a/src/main/java/cz/jzitnik/commands/QuoteCommand.java b/src/main/java/cz/jzitnik/commands/QuoteCommand.java new file mode 100644 index 0000000..e1bc4c6 --- /dev/null +++ b/src/main/java/cz/jzitnik/commands/QuoteCommand.java @@ -0,0 +1,32 @@ +package cz.jzitnik.commands; + +import cz.jzitnik.annotations.CommandImpl; +import cz.jzitnik.commands.models.Command; +import cz.jzitnik.config.models.QuoteConfig; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; +import java.util.Random; + +@CommandImpl("quotes") +public class QuoteCommand implements Command { + + private final List quotes; + + public QuoteCommand(QuoteConfig config) { + List temp; + try { + temp = Files.readAllLines(Paths.get(config.getFilePath())); + } catch (Exception e) { + temp = List.of("No quotes found."); + } + quotes = temp; + } + + @Override + public String execute(String args) { + Random r = new Random(); + return quotes.get(r.nextInt(quotes.size())); + } +} diff --git a/src/main/java/cz/jzitnik/commands/models/Command.java b/src/main/java/cz/jzitnik/commands/models/Command.java new file mode 100644 index 0000000..1c1ddfa --- /dev/null +++ b/src/main/java/cz/jzitnik/commands/models/Command.java @@ -0,0 +1,5 @@ +package cz.jzitnik.commands.models; + +public interface Command { + String execute(String args); +} diff --git a/src/main/java/cz/jzitnik/config/ContactRepositoryConfigImpl.java b/src/main/java/cz/jzitnik/config/ContactRepositoryConfigImpl.java new file mode 100644 index 0000000..04dcaac --- /dev/null +++ b/src/main/java/cz/jzitnik/config/ContactRepositoryConfigImpl.java @@ -0,0 +1,12 @@ +package cz.jzitnik.config; + +import cz.jzitnik.annotations.Config; +import cz.jzitnik.config.models.ContactRepositoryConfig; + +@Config +public class ContactRepositoryConfigImpl implements ContactRepositoryConfig { + @Override + public String getFilePath() { + return "kontakty.txt"; + } +} diff --git a/src/main/java/cz/jzitnik/config/QuoteConfigImpl.java b/src/main/java/cz/jzitnik/config/QuoteConfigImpl.java new file mode 100644 index 0000000..63a08cf --- /dev/null +++ b/src/main/java/cz/jzitnik/config/QuoteConfigImpl.java @@ -0,0 +1,12 @@ +package cz.jzitnik.config; + +import cz.jzitnik.annotations.Config; +import cz.jzitnik.config.models.QuoteConfig; + +@Config +public class QuoteConfigImpl implements QuoteConfig { + @Override + public String getFilePath() { + return "quotes.txt"; + } +} diff --git a/src/main/java/cz/jzitnik/config/models/ContactRepositoryConfig.java b/src/main/java/cz/jzitnik/config/models/ContactRepositoryConfig.java new file mode 100644 index 0000000..52a787e --- /dev/null +++ b/src/main/java/cz/jzitnik/config/models/ContactRepositoryConfig.java @@ -0,0 +1,5 @@ +package cz.jzitnik.config.models; + +public interface ContactRepositoryConfig { + String getFilePath(); +} diff --git a/src/main/java/cz/jzitnik/config/models/QuoteConfig.java b/src/main/java/cz/jzitnik/config/models/QuoteConfig.java new file mode 100644 index 0000000..6291013 --- /dev/null +++ b/src/main/java/cz/jzitnik/config/models/QuoteConfig.java @@ -0,0 +1,5 @@ +package cz.jzitnik.config.models; + +public interface QuoteConfig { + String getFilePath(); +} diff --git a/src/main/java/cz/jzitnik/factory/Contact.java b/src/main/java/cz/jzitnik/factory/Contact.java new file mode 100644 index 0000000..31216ba --- /dev/null +++ b/src/main/java/cz/jzitnik/factory/Contact.java @@ -0,0 +1,25 @@ +package cz.jzitnik.factory; + +public class Contact { + public String firstName; + public String lastName; + public String birthdate; + public String email; + public String phone; + + @Override + public String toString() { + return firstName + ";" + lastName + ";" + birthdate + ";" + email + ";" + phone; + } + + public static Contact fromString(String s) { + String[] p = s.split(";"); + Contact c = new Contact(); + c.firstName = p[0]; + c.lastName = p[1]; + c.birthdate = p[2]; + c.email = p[3]; + c.phone = p[4]; + return c; + } +} diff --git a/src/main/java/cz/jzitnik/repository/ContactRepository.java b/src/main/java/cz/jzitnik/repository/ContactRepository.java new file mode 100644 index 0000000..1db7ef4 --- /dev/null +++ b/src/main/java/cz/jzitnik/repository/ContactRepository.java @@ -0,0 +1,86 @@ +package cz.jzitnik.repository; + +import cz.jzitnik.annotations.Data; +import cz.jzitnik.config.models.ContactRepositoryConfig; +import cz.jzitnik.factory.Contact; + +import java.io.*; +import java.util.*; + +@Data +public class ContactRepository { + + private final String filePath; + private final List contacts = new ArrayList<>(); + + public List getContacts() { + return contacts; + } + + public ContactRepository(ContactRepositoryConfig config) { + this.filePath = config.getFilePath(); + load(); + } + + private void load() { + try { + File f = new File(filePath); + if (!f.exists()) return; + + try (Scanner sc = new Scanner(f)) { + while (sc.hasNextLine()) { + contacts.add(Contact.fromString(sc.nextLine())); + } + } + } catch (Exception ignored) {} + } + + private void save() { + try (PrintWriter pw = new PrintWriter(filePath)) { + for (Contact c : contacts) pw.println(c); + } catch (Exception ignored) {} + } + + public String add(Contact c) { + contacts.add(c); + save(); + return "Contact added."; + } + + public String edit(String phone, Contact updated) { + for (Contact c : contacts) { + if (c.phone.equals(phone)) { + c.firstName = updated.firstName; + c.lastName = updated.lastName; + c.birthdate = updated.birthdate; + c.email = updated.email; + c.phone = updated.phone; + save(); + return "Contact updated."; + } + } + return "Contact not found."; + } + + public String delete(String phone) { + boolean removed = contacts.removeIf(c -> c.phone.equals(phone)); + save(); + return removed ? "Contact removed." : "Contact not found."; + } + + public String searchLastName(String ln) { + StringBuilder sb = new StringBuilder(); + contacts.stream() + .filter(c -> c.lastName.equalsIgnoreCase(ln)) + .forEach(c -> sb.append(c).append("\n")); + return sb.length() == 0 ? "Not found." : sb.toString(); + } + + public String searchPhone(String ph) { + StringBuilder sb = new StringBuilder(); + contacts.stream() + .filter(c -> c.phone.equals(ph)) + .forEach(c -> sb.append(c).append("\n")); + return sb.length() == 0 ? "Not found." : sb.toString(); + } +} diff --git a/src/main/java/cz/jzitnik/services/ClassFactory.java b/src/main/java/cz/jzitnik/services/ClassFactory.java new file mode 100644 index 0000000..3531a22 --- /dev/null +++ b/src/main/java/cz/jzitnik/services/ClassFactory.java @@ -0,0 +1,78 @@ +package cz.jzitnik.services; + +import cz.jzitnik.annotations.Config; +import cz.jzitnik.annotations.Data; +import org.reflections.Reflections; + +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Set; + +public class ClassFactory { + private final HashMap, Object> instances = new HashMap<>(); + + public HashMap, Object> getInstances() { + return instances; + } + + public boolean contains(Class clazz) { + return instances.keySet().stream().anyMatch(clazzIn -> clazz.isAssignableFrom(clazzIn)); + } + + public Object get(Class clazz) { + for (Class clazzInDb : instances.keySet()) { + if (clazz.isAssignableFrom(clazzInDb)) { + return instances.get(clazzInDb); + } + } + + return null; + } + + public void load() { + Reflections reflections = new Reflections("cz.jzitnik"); + + Set> configs = reflections.getTypesAnnotatedWith(Config.class); + + for (Class config : configs) { + try { + var instance = config.getDeclaredConstructor().newInstance(); + instances.put(config, instance); + } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + Set> entityClasses = reflections.getTypesAnnotatedWith(Data.class); + + for (Class clazz : entityClasses) { + for (var constructor : clazz.getDeclaredConstructors()) { + + var paramTypes = constructor.getParameterTypes(); + var params = new Object[paramTypes.length]; + boolean suitable = true; + + for (int i = 0; i < paramTypes.length; i++) { + Class type = paramTypes[i]; + if (contains(type)) + params[i] = get(type); + else { + suitable = false; + break; + } + } + + if (suitable) { + constructor.setAccessible(true); + try { + Object instance = constructor.newInstance(params); + instances.put(clazz, instance); + } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) { + throw new RuntimeException(e); + } + break; // Found a matching constructor, go to next class + } + } + } + } +} diff --git a/src/main/java/cz/jzitnik/services/CommandHistory.java b/src/main/java/cz/jzitnik/services/CommandHistory.java new file mode 100644 index 0000000..d88c296 --- /dev/null +++ b/src/main/java/cz/jzitnik/services/CommandHistory.java @@ -0,0 +1,19 @@ +package cz.jzitnik.services; + +import cz.jzitnik.annotations.Data; + +import java.util.ArrayList; +import java.util.List; + +@Data +public class CommandHistory { + private final List list = new ArrayList<>(); + + public void add(String cmd) { + list.add(cmd); + } + + public List getAll() { + return list; + } +} diff --git a/src/main/java/cz/jzitnik/services/CommandInvoker.java b/src/main/java/cz/jzitnik/services/CommandInvoker.java new file mode 100644 index 0000000..0cd5cb5 --- /dev/null +++ b/src/main/java/cz/jzitnik/services/CommandInvoker.java @@ -0,0 +1,35 @@ +package cz.jzitnik.services; + +import cz.jzitnik.commands.models.Command; + +import java.util.HashMap; + +public class CommandInvoker { + private final HashMap commands = new HashMap<>(); + + public HashMap getCommands() { + return commands; + } + + private Command get(String name) { + for (String cmd : commands.keySet()) { + if ((cmd + " ").split(" ")[0].equals(name)) { + return commands.get(cmd); + } + } + + return null; + } + + public void register(String name, Command cmd) { + commands.put(name, cmd); + } + + public String execute(String name, String args) { + Command cmd = get(name); + if (cmd != null) { + return cmd.execute(args); + } + return "Unknown command."; + } +}