initial commit
This commit is contained in:
39
.gitignore
vendored
Normal file
39
.gitignore
vendored
Normal file
@@ -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
|
||||||
3
.idea/.gitignore
generated
vendored
Normal file
3
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
9
.idea/encodings.xml
generated
Normal file
9
.idea/encodings.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Encoding">
|
||||||
|
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$USER_HOME$/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$USER_HOME$/src/main/resources" charset="UTF-8" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
14
.idea/misc.xml
generated
Normal file
14
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
|
<component name="MavenProjectsManager">
|
||||||
|
<option name="originalFiles">
|
||||||
|
<list>
|
||||||
|
<option value="$PROJECT_DIR$/pom.xml" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_22" default="true" project-jdk-name="22" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
3
kontakty.txt
Normal file
3
kontakty.txt
Normal file
@@ -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
|
||||||
25
pom.xml
Normal file
25
pom.xml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>cz.jzitnik</groupId>
|
||||||
|
<artifactId>commandmezabijejednou</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>22</maven.compiler.source>
|
||||||
|
<maven.compiler.target>22</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.reflections</groupId>
|
||||||
|
<artifactId>reflections</artifactId>
|
||||||
|
<version>0.10.2</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
||||||
9
quotes.txt
Normal file
9
quotes.txt
Normal file
@@ -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
|
||||||
95
src/main/java/cz/jzitnik/Console.java
Normal file
95
src/main/java/cz/jzitnik/Console.java
Normal file
@@ -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<String, Command> 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<? extends Class<? extends Command>> entityClasses =
|
||||||
|
reflections.getTypesAnnotatedWith(CommandImpl.class).stream()
|
||||||
|
.filter(Command.class::isAssignableFrom)
|
||||||
|
.map(i -> (Class<? extends Command>) i)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
for (Class<? extends Command> 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/main/java/cz/jzitnik/Main.java
Normal file
9
src/main/java/cz/jzitnik/Main.java
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package cz.jzitnik;
|
||||||
|
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Console console = new Console();
|
||||||
|
console.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/main/java/cz/jzitnik/annotations/CommandImpl.java
Normal file
12
src/main/java/cz/jzitnik/annotations/CommandImpl.java
Normal file
@@ -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();
|
||||||
|
}
|
||||||
11
src/main/java/cz/jzitnik/annotations/Config.java
Normal file
11
src/main/java/cz/jzitnik/annotations/Config.java
Normal file
@@ -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 {
|
||||||
|
}
|
||||||
11
src/main/java/cz/jzitnik/annotations/Data.java
Normal file
11
src/main/java/cz/jzitnik/annotations/Data.java
Normal file
@@ -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 {
|
||||||
|
}
|
||||||
52
src/main/java/cz/jzitnik/commands/ContactCommand.java
Normal file
52
src/main/java/cz/jzitnik/commands/ContactCommand.java
Normal file
@@ -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 <operation;parameters>")
|
||||||
|
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());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/main/java/cz/jzitnik/commands/DateTimeCommand.java
Normal file
14
src/main/java/cz/jzitnik/commands/DateTimeCommand.java
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/main/java/cz/jzitnik/commands/HistoryCommand.java
Normal file
20
src/main/java/cz/jzitnik/commands/HistoryCommand.java
Normal file
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
44
src/main/java/cz/jzitnik/commands/QuadraticCommand.java
Normal file
44
src/main/java/cz/jzitnik/commands/QuadraticCommand.java
Normal file
@@ -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.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
32
src/main/java/cz/jzitnik/commands/QuoteCommand.java
Normal file
32
src/main/java/cz/jzitnik/commands/QuoteCommand.java
Normal file
@@ -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<String> quotes;
|
||||||
|
|
||||||
|
public QuoteCommand(QuoteConfig config) {
|
||||||
|
List<String> 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()));
|
||||||
|
}
|
||||||
|
}
|
||||||
5
src/main/java/cz/jzitnik/commands/models/Command.java
Normal file
5
src/main/java/cz/jzitnik/commands/models/Command.java
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package cz.jzitnik.commands.models;
|
||||||
|
|
||||||
|
public interface Command {
|
||||||
|
String execute(String args);
|
||||||
|
}
|
||||||
@@ -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";
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/main/java/cz/jzitnik/config/QuoteConfigImpl.java
Normal file
12
src/main/java/cz/jzitnik/config/QuoteConfigImpl.java
Normal file
@@ -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";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package cz.jzitnik.config.models;
|
||||||
|
|
||||||
|
public interface ContactRepositoryConfig {
|
||||||
|
String getFilePath();
|
||||||
|
}
|
||||||
5
src/main/java/cz/jzitnik/config/models/QuoteConfig.java
Normal file
5
src/main/java/cz/jzitnik/config/models/QuoteConfig.java
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package cz.jzitnik.config.models;
|
||||||
|
|
||||||
|
public interface QuoteConfig {
|
||||||
|
String getFilePath();
|
||||||
|
}
|
||||||
25
src/main/java/cz/jzitnik/factory/Contact.java
Normal file
25
src/main/java/cz/jzitnik/factory/Contact.java
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
86
src/main/java/cz/jzitnik/repository/ContactRepository.java
Normal file
86
src/main/java/cz/jzitnik/repository/ContactRepository.java
Normal file
@@ -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<Contact> contacts = new ArrayList<>();
|
||||||
|
|
||||||
|
public List<Contact> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
78
src/main/java/cz/jzitnik/services/ClassFactory.java
Normal file
78
src/main/java/cz/jzitnik/services/ClassFactory.java
Normal file
@@ -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<Class<?>, Object> instances = new HashMap<>();
|
||||||
|
|
||||||
|
public HashMap<Class<?>, 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<Class<?>> 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<Class<?>> 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/main/java/cz/jzitnik/services/CommandHistory.java
Normal file
19
src/main/java/cz/jzitnik/services/CommandHistory.java
Normal file
@@ -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<String> list = new ArrayList<>();
|
||||||
|
|
||||||
|
public void add(String cmd) {
|
||||||
|
list.add(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getAll() {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/main/java/cz/jzitnik/services/CommandInvoker.java
Normal file
35
src/main/java/cz/jzitnik/services/CommandInvoker.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package cz.jzitnik.services;
|
||||||
|
|
||||||
|
import cz.jzitnik.commands.models.Command;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class CommandInvoker {
|
||||||
|
private final HashMap<String, Command> commands = new HashMap<>();
|
||||||
|
|
||||||
|
public HashMap<String, Command> 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.";
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user