From c2351ccf104164f89ce0e7911d351636855edc45 Mon Sep 17 00:00:00 2001 From: Oscar Nidemar Date: Fri, 14 Nov 2025 13:57:07 +0100 Subject: [PATCH 1/2] awaitin judgment --- .github/dependabot.yml | 2 +- .gitignore | 1 + .mvn/wrapper/maven-wrapper.properties | 2 +- pom.xml | 20 ++++- .../java/com/example/HelloController.java | 36 ++++++++- src/main/java/com/example/HelloModel.java | 59 +++++++++++++- src/main/java/com/example/ManyParameters.java | 19 +++++ .../com/example/ManyParametersBuilder.java | 38 +++++++++ src/main/java/com/example/NtfyConnection.java | 13 +++ .../java/com/example/NtfyConnectionImpl.java | 80 +++++++++++++++++++ src/main/java/com/example/NtfyMessageDto.java | 16 ++++ src/main/java/com/example/Singelton.java | 14 ++++ src/main/java/module-info.java | 4 + .../resources/com/example/hello-view.fxml | 18 +++-- src/test/java/com/example/HelloModelTest.java | 40 ++++++++++ .../java/com/example/NtfyConnectionSpy.java | 19 +++++ 16 files changed, 366 insertions(+), 15 deletions(-) create mode 100644 src/main/java/com/example/ManyParameters.java create mode 100644 src/main/java/com/example/ManyParametersBuilder.java create mode 100644 src/main/java/com/example/NtfyConnection.java create mode 100644 src/main/java/com/example/NtfyConnectionImpl.java create mode 100644 src/main/java/com/example/NtfyMessageDto.java create mode 100644 src/main/java/com/example/Singelton.java create mode 100644 src/test/java/com/example/HelloModelTest.java create mode 100644 src/test/java/com/example/NtfyConnectionSpy.java diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0a2c2802..a79a873b 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -18,4 +18,4 @@ updates: groups: maven-deps: patterns: - - "*" + - "*" \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6ac465db..ea4f5ae6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ target/ /.idea/ +target/.env diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index c0bcafe9..30c47d27 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,3 +1,3 @@ wrapperVersion=3.3.4 distributionType=only-script -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip \ No newline at end of file diff --git a/pom.xml b/pom.xml index c40f667e..f410eea0 100644 --- a/pom.xml +++ b/pom.xml @@ -45,6 +45,22 @@ javafx-fxml ${javafx.version} + + io.github.cdimascio + dotenv-java + 3.2.0 + + + tools.jackson.core + jackson-databind + 3.0.1 + + + org.wiremock + wiremock + 4.0.0-beta.15 + test + @@ -55,7 +71,7 @@ com.example.HelloFX - + javafx true @@ -65,4 +81,4 @@ - + \ No newline at end of file diff --git a/src/main/java/com/example/HelloController.java b/src/main/java/com/example/HelloController.java index fdd160a0..cd9f35c6 100644 --- a/src/main/java/com/example/HelloController.java +++ b/src/main/java/com/example/HelloController.java @@ -1,22 +1,52 @@ package com.example; +import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.Label; +import javafx.scene.control.ListView; +import javafx.scene.control.TextField; +import javafx.stage.FileChooser; + +import java.io.File; /** * Controller layer: mediates between the view (FXML) and the model. */ public class HelloController { - private final HelloModel model = new HelloModel(); + private final HelloModel model = new HelloModel(new NtfyConnectionImpl()); + + @FXML + private ListView messageView; @FXML private Label messageLabel; + @FXML + private TextField messageInput; + @FXML private void initialize() { - if (messageLabel != null) { - messageLabel.setText(model.getGreeting()); + messageLabel.setText(model.getGreeting()); + messageView.setItems(model.getMessages()); + + // Bind textfältet till modellen + messageInput.textProperty().bindBidirectional(model.messageToSendProperty()); + + // Skicka meddelande när användaren trycker Enter + messageInput.setOnAction(event -> { + model.sendMessage(); + messageInput.clear(); // töm fältet efter skick + }); + } + @FXML + private void attachFile(ActionEvent event) { + FileChooser fileChooser = new FileChooser(); + fileChooser.setTitle("Select file to send"); + File file = fileChooser.showOpenDialog(messageView.getScene().getWindow()); + if (file != null) { + model.sendFile(file.toPath()); } } + } diff --git a/src/main/java/com/example/HelloModel.java b/src/main/java/com/example/HelloModel.java index 385cfd10..9c2676a5 100644 --- a/src/main/java/com/example/HelloModel.java +++ b/src/main/java/com/example/HelloModel.java @@ -1,9 +1,57 @@ package com.example; +import javafx.application.Platform; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import java.nio.file.Path; + /** * Model layer: encapsulates application data and business logic. */ public class HelloModel { + + private final NtfyConnection connection; + + private final ObservableList messages = FXCollections.observableArrayList(); + private final StringProperty messageToSend = new SimpleStringProperty(); + + public HelloModel(NtfyConnection connection) { + this.connection = connection; + receiveMessage(); + } + + public ObservableList getMessages() { + return messages; + } + + public String getMessageToSend() { + return messageToSend.get(); + } + + public StringProperty messageToSendProperty() { + return messageToSend; + } + + public void setMessageToSend(String message) { + messageToSend.set(message); + } + private static void runOnFx(Runnable task) { + try { + if (Platform.isFxApplicationThread()) task.run(); + else Platform.runLater(task); + } catch (IllegalStateException notInitialized) { + // JavaFX toolkit not initialized (e.g., unit tests): run inline + task.run(); + } + } + public void sendFile(Path filePath) { + connection.sendFile(filePath); + } + + + /** * Returns a greeting based on the current Java and JavaFX versions. */ @@ -12,4 +60,13 @@ public String getGreeting() { String javafxVersion = System.getProperty("javafx.version"); return "Hello, JavaFX " + javafxVersion + ", running on Java " + javaVersion + "."; } -} + + public void sendMessage() { + connection.send(messageToSend.get()); + + } + + public void receiveMessage() { + connection.receive(m -> runOnFx(() -> messages.add(m))); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/ManyParameters.java b/src/main/java/com/example/ManyParameters.java new file mode 100644 index 00000000..9efe0e71 --- /dev/null +++ b/src/main/java/com/example/ManyParameters.java @@ -0,0 +1,19 @@ +package com.example; + +public class ManyParameters { + + public ManyParameters(String computerName, int timeout, + String method, int size, byte[] data) { + + } + + + static void main() { + ManyParametersBuilder builder = new ManyParametersBuilder(); + builder + .setComputerName("localhost") //Fluent API + .setTimeout(10) + .setSize(0) + .createManyParameters(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/ManyParametersBuilder.java b/src/main/java/com/example/ManyParametersBuilder.java new file mode 100644 index 00000000..fd49920d --- /dev/null +++ b/src/main/java/com/example/ManyParametersBuilder.java @@ -0,0 +1,38 @@ +package com.example; + +public class ManyParametersBuilder { + private String computerName; + private int timeout = 0; + private String method; + private int size = 0; + private byte[] data = null; + + public ManyParametersBuilder setComputerName(String computerName) { + this.computerName = computerName; + return this; + } + + public ManyParametersBuilder setTimeout(int timeout) { + this.timeout = timeout; + return this; + } + + public ManyParametersBuilder setMethod(String method) { + this.method = method; + return this; + } + + public ManyParametersBuilder setSize(int size) { + this.size = size; + return this; + } + + public ManyParametersBuilder setData(byte[] data) { + this.data = data; + return this; + } + + public ManyParameters createManyParameters() { + return new ManyParameters(computerName, timeout, method, size, data); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/NtfyConnection.java b/src/main/java/com/example/NtfyConnection.java new file mode 100644 index 00000000..de7d7035 --- /dev/null +++ b/src/main/java/com/example/NtfyConnection.java @@ -0,0 +1,13 @@ +package com.example; + +import java.nio.file.Path; +import java.util.function.Consumer; + +public interface NtfyConnection { + + public boolean send(String message); + + public void receive(Consumer messageHandler); + boolean sendFile(Path filePath); + +} \ No newline at end of file diff --git a/src/main/java/com/example/NtfyConnectionImpl.java b/src/main/java/com/example/NtfyConnectionImpl.java new file mode 100644 index 00000000..f2621bf0 --- /dev/null +++ b/src/main/java/com/example/NtfyConnectionImpl.java @@ -0,0 +1,80 @@ +package com.example; + +import io.github.cdimascio.dotenv.Dotenv; +import tools.jackson.databind.ObjectMapper; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.file.Path; +import java.util.Map; +import java.util.Objects; +import java.util.function.Consumer; + +public class NtfyConnectionImpl implements NtfyConnection { + + private final HttpClient http = HttpClient.newHttpClient(); + private final String hostName; + private final ObjectMapper mapper = new ObjectMapper(); + + public NtfyConnectionImpl() { + Dotenv dotenv = Dotenv.load(); + hostName = Objects.requireNonNull(dotenv.get("HOST_NAME")); + } + + public NtfyConnectionImpl(String hostName) { + this.hostName = hostName; + } + + + + @Override + public boolean send(String message) { + try { + String json = mapper.writeValueAsString(Map.of("message", message)); + HttpRequest httpRequest = HttpRequest.newBuilder() + .POST(HttpRequest.BodyPublishers.ofString(json)) + .header("Content-Type", "application/json") + .uri(URI.create(hostName + "/mytopic")) + .build(); + http.send(httpRequest, HttpResponse.BodyHandlers.discarding()); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + public boolean sendFile(Path filePath) { + try { + HttpRequest httpRequest = HttpRequest.newBuilder() + .POST(HttpRequest.BodyPublishers.ofFile(filePath)) + .header("Content-Type", "application/octet-stream") + .uri(URI.create(hostName + "/mytopic")) + .build(); + http.send(httpRequest, HttpResponse.BodyHandlers.discarding()); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + + + @Override + public void receive(Consumer messageHandler) { + HttpRequest httpRequest = HttpRequest.newBuilder() + .GET() + .uri(URI.create(hostName + "/mytopic/json")) + .build(); + + http.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofLines()) + .thenAccept(response -> response.body() + .map(s -> + mapper.readValue(s, NtfyMessageDto.class)) + .filter(message -> message.event().equals("message")) + .peek(System.out::println) + .forEach(messageHandler)); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/NtfyMessageDto.java b/src/main/java/com/example/NtfyMessageDto.java new file mode 100644 index 00000000..a2f2fec2 --- /dev/null +++ b/src/main/java/com/example/NtfyMessageDto.java @@ -0,0 +1,16 @@ +package com.example; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) +public record NtfyMessageDto( + String id, + long time, + String event, + String topic, + String message, + Attachment attachment // nytt fält +) { + @JsonIgnoreProperties(ignoreUnknown = true) + public record Attachment(String name, String type, long size, String url) { } +} diff --git a/src/main/java/com/example/Singelton.java b/src/main/java/com/example/Singelton.java new file mode 100644 index 00000000..b3685a01 --- /dev/null +++ b/src/main/java/com/example/Singelton.java @@ -0,0 +1,14 @@ +package com.example; + +public class Singelton { + + private final static Singelton instance = new Singelton(); + + private Singelton(){ + + } + + public static Singelton getInstance(){ + return instance; + } +} \ No newline at end of file diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 71574a27..89e041cb 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,6 +1,10 @@ module hellofx { requires javafx.controls; requires javafx.fxml; + requires io.github.cdimascio.dotenv.java; + requires java.net.http; + requires tools.jackson.databind; + requires javafx.graphics; opens com.example to javafx.fxml; exports com.example; diff --git a/src/main/resources/com/example/hello-view.fxml b/src/main/resources/com/example/hello-view.fxml index 20a7dc82..4cdb2e32 100644 --- a/src/main/resources/com/example/hello-view.fxml +++ b/src/main/resources/com/example/hello-view.fxml @@ -1,9 +1,13 @@ - - - - - - + + + + + + +