Skip to content

Lab3#31

Closed
Michalis-Dragoutas wants to merge 4 commits intomainfrom
lab3
Closed

Lab3#31
Michalis-Dragoutas wants to merge 4 commits intomainfrom
lab3

Conversation

@Michalis-Dragoutas
Copy link

@Michalis-Dragoutas Michalis-Dragoutas commented Nov 16, 2025

Summary by CodeRabbit

  • New Features

    • Interactive chat UI: message list with formatted timestamps and sender-aligned layout
    • Send messages from an input field and receive real-time updates
    • Emoji picker button for quick emoji insertion
    • Environment-based configuration for messaging host
  • Chores

    • Added JSON handling and dotenv configuration libraries
    • .env now ignored in repository settings

@coderabbitai
Copy link

coderabbitai bot commented Nov 16, 2025

Walkthrough

Adds a JavaFX chat UI and messaging model that posts and polls an HTTP backend. Introduces dotenv and Jackson dependencies, a NtfyMessageDto record, FXML/ListView and emoji/send controls, builder and singleton utilities, .env ignore entry, and module/POM updates.

Changes

Cohort / File(s) Summary
Config & Build
\.gitignore, pom.xml, src/main/java/module-info.java
Added .env to .gitignore. Added Maven dependencies: io.github.cdimascio:dotenv-java:3.2.0 and com.fasterxml.jackson.core:jackson-databind:3.0.1. Updated module declaration to require dotenv, java.net.http, and Jackson databind.
Model & DTO
src/main/java/com/example/HelloModel.java, src/main/java/com/example/NtfyMessageDto.java
New HelloModel: HttpClient-based send/receive, Dotenv config, ObservableList of messages, async POST and polling GET with SSE parsing and FX thread updates. New NtfyMessageDto record with JSON ignore-unknown and formatted toString().
UI Controller & FXML
src/main/java/com/example/HelloController.java, src/main/java/com/example/HelloFX.java, src/main/resources/com/example/hello-view.fxml
HelloController gains ListView<NtfyMessageDto> messageView, TextField messageField, Button emojiButton, emoji menu handler, and sendMessage action. FXML switched StackPane→VBox, adds messageView, input HBox with emoji button, text field, and Send button. HelloFX imports dotenv.
Utilities / Builders
src/main/java/com/example/ManyParameters.java, src/main/java/com/example/ManyParametersBuilder.java, src/main/java/com/example/Singelton.java
Added ManyParameters and ManyParametersBuilder (fluent setters, createManyParameters). Added Singelton class with eager static instance and public getInstance() (no private constructor).

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Controller as HelloController
    participant Model as HelloModel
    participant Server as HTTP Server
    participant UI as JavaFX ListView

    User->>Controller: Click Send / sendMessage()
    Controller->>Model: sendMessage(text)
    Model->>Model: create local NtfyMessageDto, mark senderMe
    Model->>UI: add to ObservableList (Platform.runLater)
    UI->>UI: render local message

    par Async publish & poll
        Model->>Server: POST /{topic} (publish)
        Server-->>Model: HTTP response
    and Poll loop
        Model->>Server: GET /{topic}/json (SSE)
        Server-->>Model: SSE lines
        Model->>Model: parse lines → NtfyMessageDto (filter event="message")
        alt remote message
            Model->>UI: add to ObservableList (Platform.runLater)
            UI->>UI: render received message
        else local echo
            Model->>Model: ignore (senderMe toggle)
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay close attention to HelloModel: HTTP polling, SSE parsing, error handling, and correct use of Platform.runLater().
  • Verify FXML IDs/action names match controller fields and methods.
  • Inspect NtfyMessageDto time formatting for epoch-second handling.
  • Review Singelton and ManyParameters for intended constructors/visibility and API correctness.

Poem

🐰 A little rabbit hops and sings,
New messages arrive on wings,
Emojis tumble, ListViews grow,
Env files hide while JSON flows—
Code hops forward, bright and spry! 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Lab3' is vague and generic, failing to convey meaningful information about the changeset's primary purpose or content. Use a descriptive title that summarizes the main change, such as 'Add chat UI with emoji support and network messaging' or 'Implement message sending with HTTP-based Ntfy integration'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb0bbc7 and 0f993aa.

📒 Files selected for processing (2)
  • src/main/java/com/example/HelloModel.java (2 hunks)
  • src/main/resources/com/example/hello-view.fxml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/resources/com/example/hello-view.fxml
  • src/main/java/com/example/HelloModel.java

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (8)
src/main/java/com/example/ManyParameters.java (1)

11-16: Unused return value from builder.

The createManyParameters() call creates an object but the result is not assigned or used. Consider storing it in a variable if this is meant to be functional code.

Apply this diff if the object should be used:

-        ManyParametersBuilder builder= new ManyParametersBuilder();
-        builder
+        ManyParameters params = new ManyParametersBuilder()
                 .setComputerName("localhost")
                 .setTimeout(10)
                 .setSize(0)
                 .createManyParameters();
src/main/java/com/example/ManyParametersBuilder.java (2)

8-8: Redundant null initialization.

Reference types in Java default to null, so the explicit initialization is unnecessary.

Apply this diff to simplify:

-    private byte[] data = null;
+    private byte[] data;

35-37: Consider validating required fields before construction.

The builder doesn't validate that required fields (e.g., computerName, method) are set before creating the object. This could lead to NullPointerException or invalid object states.

Consider adding validation:

     public ManyParameters createManyParameters() {
+        if (computerName == null || computerName.isEmpty()) {
+            throw new IllegalStateException("computerName is required");
+        }
+        if (method == null || method.isEmpty()) {
+            throw new IllegalStateException("method is required");
+        }
         return new ManyParameters(computerName, timeout, method, size, data);
     }

Additionally, if the defensive copy suggestion for setData() is not applied, make a defensive copy here:

public ManyParameters createManyParameters() {
    // ... validation ...
    return new ManyParameters(computerName, timeout, method, size, 
        data != null ? data.clone() : null);
}
pom.xml (1)

48-57: Dotenv and Jackson 3 dependencies look correct; consider centralizing Jackson version

  • io.github.cdimascio:dotenv-java:3.2.0 matches the current upstream recommendation for the pure Java dotenv library. (github.com)
  • tools.jackson.core:jackson-databind:3.0.1 uses the new Jackson 3 coordinates and is a valid artifact; 3.0.2 is available as a patch update. (mvnrepository.com)

To make future upgrades easier (and to keep jackson-* modules in sync if you add more later), consider introducing a <jackson.version> property or BOM instead of hard-coding the version here.

Please double‑check in your environment that 3.0.1 is the intended Jackson version (vs. the newer 3.0.2) and that dependency resolution works as expected (e.g., via mvn dependency:tree).

src/main/java/com/example/Singelton.java (1)

3-9: Complete the singleton pattern (and consider fixing the class name)

Right now the pattern is only partially enforced:

  • Because there is no explicit constructor, the default constructor is public and callers can still create additional instances via new Singelton().
  • To make this a proper singleton, add a private Singelton() constructor so getInstance() is the only way to obtain an instance.
  • Optional: rename the class to Singleton before it spreads through the codebase to avoid confusion and spelling issues in usages.

Example:

-public  class Singelton {
-
-    private final static   Singelton instance= new Singelton();
+public class Singelton {
+
+    private static final Singelton instance = new Singelton();
+
+    private Singelton() {}
src/main/java/com/example/NtfyMessageDto.java (1)

10-17: Unify date/time formatting and avoid mixing java.text / java.time

You already define a DateTimeFormatter but toString builds a new SimpleDateFormat and Date each call. For consistency and simpler code, either:

  • Use the existing DateTimeFormatter with Instant/LocalTime, or
  • Drop the unused formatter and keep a single approach.

This is stylistic and not a functional bug.

src/main/java/com/example/HelloController.java (1)

83-88: Annotate sendMessage with @FXML for consistency

sendMessage(ActionEvent) is invoked from FXML but lacks @FXML, unlike the other handlers. It works because the method is public, but adding @FXML keeps controller wiring explicit and allows making the method private if desired.

src/main/java/com/example/HelloModel.java (1)

76-103: Add error handling for failed receive and consider reconnection strategy

receiveMessage() starts a long-lived sendAsync with BodyHandlers.ofLines() and processes the stream, but:

  • There is no exceptionally or similar handler on the CompletableFuture, so network errors or connection drops won’t be logged or retried.
  • The method is only called once (in the constructor), so if the stream fails, you don’t attempt reconnection.

For robustness, consider attaching .exceptionally(...) or .handle(...) to log failures and optionally schedule a retry of receiveMessage().

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 21c51e8 and bb0bbc7.

📒 Files selected for processing (11)
  • .gitignore (1 hunks)
  • pom.xml (1 hunks)
  • src/main/java/com/example/HelloController.java (2 hunks)
  • src/main/java/com/example/HelloFX.java (2 hunks)
  • src/main/java/com/example/HelloModel.java (2 hunks)
  • src/main/java/com/example/ManyParameters.java (1 hunks)
  • src/main/java/com/example/ManyParametersBuilder.java (1 hunks)
  • src/main/java/com/example/NtfyMessageDto.java (1 hunks)
  • src/main/java/com/example/Singelton.java (1 hunks)
  • src/main/java/module-info.java (1 hunks)
  • src/main/resources/com/example/hello-view.fxml (1 hunks)
🔇 Additional comments (4)
.gitignore (1)

3-3: Ignoring .env is a good safeguard

Adding .env to .gitignore is appropriate to keep local credentials and config out of version control, especially now that dotenv is used elsewhere in the app.

src/main/java/module-info.java (1)

4-6: Module requirements align with the new HTTP/env/JSON functionality

The added requires io.github.cdimascio.dotenv.java;, requires java.net.http;, and requires tools.jackson.databind; are consistent with the new dependencies and Jackson 3’s module name. (github.com)

If you later see reflective access or module-resolution issues with Jackson and your own model classes, you may need to add an opens com.example to tools.jackson.databind; clause so Jackson can access non‑public members at runtime.

Please verify a full modular build/run (mvn javafx:run or equivalent) to confirm that the io.github.cdimascio.dotenv.java module name matches what the jar actually exposes; adjust the requires name if the compiler reports an unresolved module.

src/main/java/com/example/HelloFX.java (1)

3-15: JavaFX entry point remains unchanged; new import is safe

The added import and minor formatting tweaks do not alter the JavaFX startup flow—start still just loads hello-view.fxml and shows the stage—so this file remains functionally stable while being ready for future dotenv-based configuration.

src/main/java/com/example/HelloController.java (1)

50-77: Custom ListCell implementation for chat bubbles looks solid

The cell factory correctly:

  • Handles empty cells,
  • Wraps and bounds label width,
  • Styles and aligns messages differently depending on msg.topic().

This aligns well with the chat UI goal.

Comment on lines +48 to +49
messageLabel.setText(model.getGreeting());
messageView.setItems(model.getMessages());
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Label text from FXML is overridden by greeting

initialize() sets messageLabel from model.getGreeting(), so the "CHAT LAB3" text configured in hello-view.fxml will never be visible. If the intent is to show the “CHAT LAB3” header, consider removing this assignment or using a separate label for the greeting/version info.

🤖 Prompt for AI Agents
In src/main/java/com/example/HelloController.java around lines 48-49, the
initialize() call messageLabel.setText(model.getGreeting()) overrides the static
"CHAT LAB3" text from hello-view.fxml; remove that assignment or wire a separate
Label for the dynamic greeting. Fix by either (A) delete the
messageLabel.setText(model.getGreeting()) line so the FXML header remains, or
(B) add a new @FXML Label (e.g., greetingLabel) in the FXML and controller and
set model.getGreeting() on that new label instead, or (C) only set the text when
the FXML value is empty (if conditional behavior is desired).

import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import tools.jackson.databind.ObjectMapper;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

ObjectMapper import likely incorrect

The import tools.jackson.databind.ObjectMapper looks suspicious; the standard Jackson ObjectMapper class is in the com.fasterxml.jackson.databind package. With the current import this will not compile unless you have a nonstandard tools.jackson dependency.

Update the import to match the actual package provided by your Jackson version (most likely com.fasterxml.jackson.databind.ObjectMapper).


🏁 Script executed:

#!/bin/bash
# Examine the HelloModel.java file and check dependencies
echo "=== HelloModel.java imports and class structure ==="
cat src/main/java/com/example/HelloModel.java 2>/dev/null || echo "File not found at expected path"

echo ""
echo "=== Searching for pom.xml to check dependencies ==="
find . -name "pom.xml" -type f | head -5

echo ""
echo "=== Searching for build.gradle to check dependencies ==="
find . -name "build.gradle*" -type f | head -5

Length of output: 3772


🏁 Script executed:

#!/bin/bash
# Check pom.xml for Jackson dependencies
echo "=== pom.xml Jackson dependencies ==="
cat pom.xml

Length of output: 3021


ObjectMapper import is incompatible with the declared dependency

The import tools.jackson.databind.ObjectMapper does not match the Jackson dependency declared in pom.xml. The dependency specifies:

<groupId>tools.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>

The groupId is tools.jackson.core, not tools.jackson.databind. This will cause a compilation error.

Additionally, tools.jackson.core is a nonstandard groupId. The official Jackson library from FasterXML uses com.fasterxml.jackson.core.

Fix: Update pom.xml to use the standard Jackson dependency:

<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>

Then update the import to import com.fasterxml.jackson.databind.ObjectMapper;

🤖 Prompt for AI Agents
In src/main/java/com/example/HelloModel.java around line 7, the current import
uses tools.jackson.databind.ObjectMapper which is incompatible with the declared
dependency and nonstandard; update the project's pom.xml to use the standard
Jackson groupId com.fasterxml.jackson.core with artifactId jackson-databind
(replace tools.jackson.core groupId if present), then change the import in this
file to import com.fasterxml.jackson.databind.ObjectMapper; ensure you
refresh/rebuild dependencies after updating pom.xml.

Comment on lines +5 to +7
public ManyParameters(String computerName, int timeout, String method, int size, byte[] data) {

}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Constructor body is empty - parameters are not stored.

The constructor accepts five parameters but the body is empty, meaning all parameters are discarded. The class also has no fields to store this data. This renders the class non-functional.

Add fields and assign the constructor parameters:

 public class ManyParameters {
+    private final String computerName;
+    private final int timeout;
+    private final String method;
+    private final int size;
+    private final byte[] data;

     public ManyParameters(String computerName, int timeout, String method, int size, byte[] data) {
-
+        this.computerName = computerName;
+        this.timeout = timeout;
+        this.method = method;
+        this.size = size;
+        this.data = data;
     }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/main/java/com/example/ManyParameters.java around lines 5 to 7, the
constructor currently has no body and there are no fields to retain the passed
values; add private fields for computerName (String), timeout (int), method
(String), size (int) and data (byte[]) to the class and assign each constructor
parameter to its corresponding field (use defensive copy for the byte[] if
immutability is desired). Ensure fields are appropriately scoped (e.g., private
final if immutable) and consider validating/null-checking parameters before
assignment.


}

static void main () {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Incorrect main method signature.

The method signature should be public static void main(String[] args) to be recognized as a valid Java program entry point. The current signature static void main() won't work.

Apply this diff:

-    static void main () {
+    public static void main(String[] args) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
static void main () {
public static void main(String[] args) {
🤖 Prompt for AI Agents
In src/main/java/com/example/ManyParameters.java around line 9, the main method
currently has the signature "static void main()" which is not a valid Java entry
point; change it to the standard public static void main(String[] args)
signature so the JVM can recognize and invoke it, updating visibility to public
and adding the String[] args parameter.

Comment on lines +30 to +33
public ManyParametersBuilder setData(byte[] data) {
this.data = data;
return this;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Missing defensive copy for mutable byte array.

The data array is stored directly without making a defensive copy. This allows external code to modify the array after passing it to the builder, breaking encapsulation.

Apply this diff to create a defensive copy:

     public ManyParametersBuilder setData(byte[] data) {
-        this.data = data;
+        this.data = data != null ? data.clone() : null;
         return this;
     }
🤖 Prompt for AI Agents
In src/main/java/com/example/ManyParametersBuilder.java around lines 30 to 33,
the setData(byte[] data) method stores the incoming mutable array directly;
change it to make a defensive copy (e.g., this.data = data == null ? null :
Arrays.copyOf(data, data.length)) and ensure you import java.util.Arrays; also
audit any getter or build method that exposes this.data and return a copy there
as well to preserve encapsulation.

@kappsegla kappsegla closed this Nov 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants