From 60fd71faa5a12723d83c72140a3019cbb405274c Mon Sep 17 00:00:00 2001 From: lukaceli Date: Tue, 14 Apr 2026 13:19:17 +0200 Subject: [PATCH 1/4] Generated javadoc for Dao-classes --- .../java/persistence/OrganizationDao.java | 19 +++++++- src/main/java/persistence/UserDao.java | 48 ++++++++++++++++++- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/main/java/persistence/OrganizationDao.java b/src/main/java/persistence/OrganizationDao.java index 7757887..470d74a 100644 --- a/src/main/java/persistence/OrganizationDao.java +++ b/src/main/java/persistence/OrganizationDao.java @@ -6,11 +6,22 @@ import java.util.ArrayList; import java.util.List; +/** + * Data Access Object for organization-related database operations. + * Provides methods for inserting and retrieving {@link Organization} records + * from the SQLite database. + */ public class OrganizationDao { - private static final String URL = "jdbc:sqlite:givehope.db"; + /** + * Inserts a new organization into the database. + * Uses {@code INSERT OR IGNORE} so duplicate org numbers are silently skipped. + * + * @param org the {@link Organization} to insert; must not be null and must have a valid org number + * @throws SQLException if a database error occurs during the insert + */ public void insert(Organization org) throws SQLException { String sql = """ INSERT OR IGNORE INTO organization @@ -30,6 +41,12 @@ public void insert(Organization org) throws SQLException { } } + /** + * Retrieves all organizations stored in the database. + * + * @return a list of all {@link Organization} objects; empty list if none exist + * @throws SQLException if a database error occurs during the query + */ public List getAll() throws SQLException { String sql = "SELECT * FROM organization"; List list = new ArrayList<>(); diff --git a/src/main/java/persistence/UserDao.java b/src/main/java/persistence/UserDao.java index 2fa7765..bdfc9f3 100644 --- a/src/main/java/persistence/UserDao.java +++ b/src/main/java/persistence/UserDao.java @@ -9,9 +9,20 @@ import java.sql.SQLException; import domain.user.User; +/** + * Data Access Object for user-related database operations. + * Implements {@link UserRepository} and provides methods for inserting users + * and looking them up by email, username, or either. + */ public class UserDao implements UserRepository { - + /** + * Inserts a new user into the database. + * Upon successful insertion, the generated database ID is set on the user object. + * + * @param user the {@link User} to insert; must not be null and must have a unique email and username + * @throws RuntimeException if a database error occurs, including unique constraint violations + */ public void insert(User user) { String sql = "INSERT INTO user(user_name, phone_number, e_mail, password_hash) VALUES(?, ?, ?, ?)"; @@ -39,6 +50,13 @@ public void insert(User user) { //private User mapRow(ResultSet rs) throws SQLException {} + /** + * Finds a user by their email address. + * + * @param email the email address to search for; leading/trailing whitespace is trimmed + * @return an {@link Optional} containing the user if found, or empty if no match exists + * @throws RuntimeException if a database error occurs during the query + */ @Override public Optional findByEmail(String email) { String sql = """ @@ -67,6 +85,13 @@ public Optional findByEmail(String email) { } } + /** + * Finds a user by their username. + * + * @param username the username to search for + * @return an {@link Optional} containing the user if found, or empty if no match exists + * @throws RuntimeException if a database error occurs during the query + */ @Override public Optional findByUsername(String username) { String sql = """ @@ -95,6 +120,13 @@ public Optional findByUsername(String username) { } } + /** + * Finds a user by either email or username. + * First attempts to match by email, then falls back to username if no email match is found. + * + * @param login the email or username to search for; returns empty if null or blank + * @return an {@link Optional} containing the user if found, or empty if no match exists + */ @Override public Optional findByLogin(String login) { if (login == null || login.isBlank()) { @@ -110,6 +142,13 @@ public Optional findByLogin(String login) { } + /** + * Checks whether a user with the given email address already exists in the database. + * + * @param email the email address to check + * @return {@code true} if a user with the given email exists, {@code false} otherwise + * @throws RuntimeException if a database error occurs during the query + */ @Override public boolean existsByEmail(String email) { String sql = "SELECT 1 FROM user WHERE e_mail = ?"; @@ -128,6 +167,13 @@ public boolean existsByEmail(String email) { } } + /** + * Checks whether a user with the given username already exists in the database. + * + * @param username the username to check + * @return {@code true} if a user with the given username exists, {@code false} otherwise + * @throws RuntimeException if a database error occurs during the query + */ @Override public boolean existsByUsername(String username) { String sql = "SELECT 1 FROM user WHERE user_name = ?"; From d00975624cb3ebdd5d9b6048daac843fac9bc761 Mon Sep 17 00:00:00 2001 From: lukaceli Date: Wed, 15 Apr 2026 10:22:59 +0200 Subject: [PATCH 2/4] Added javadoc to multiple classes --- .../application/security/PasswordHasher.java | 4 ++ .../java/application/user/UserStatistics.java | 19 +++--- src/main/java/domain/donation/Cause.java | 3 + src/main/java/domain/donation/Donation.java | 45 ++++++++++++++ .../domain/organization/Organization.java | 3 + src/main/java/domain/user/Role.java | 3 + src/main/java/domain/user/User.java | 62 +++++++++++++++++++ .../InnsamlingskontrollenClient.java | 5 ++ .../security/Sha256PasswordHasher.java | 14 ++++- src/main/java/persistence/UserRepository.java | 5 ++ src/main/java/persistence/db/Database.java | 16 +++++ src/main/java/util/SessionManager.java | 29 +++++++-- 12 files changed, 193 insertions(+), 15 deletions(-) diff --git a/src/main/java/application/security/PasswordHasher.java b/src/main/java/application/security/PasswordHasher.java index d708691..03e2564 100644 --- a/src/main/java/application/security/PasswordHasher.java +++ b/src/main/java/application/security/PasswordHasher.java @@ -1,5 +1,9 @@ package application.security; +/** + * Interface that creates a "contract" for which methods the class that implements it, needs. + * Interface is created for SHA256PasswordHasher. + */ public interface PasswordHasher { String hash(String password); diff --git a/src/main/java/application/user/UserStatistics.java b/src/main/java/application/user/UserStatistics.java index b78f18f..ed0f2dc 100644 --- a/src/main/java/application/user/UserStatistics.java +++ b/src/main/java/application/user/UserStatistics.java @@ -8,8 +8,7 @@ /** * Provides statistical information about a user's donation activity. * Acts as a service layer between the application and {@link DonationDao}, - * exposing user-friendly methods for retrieving donation history, - * total amounts, and favorite organizations. + * showing relevant userstatistics to the user. */ public class UserStatistics { private DonationDao donationDao; @@ -24,9 +23,9 @@ public UserStatistics() { /** * Returns the top three organizations that the user has donated to most frequently. * - * @param user the user whose favorite organizations are to be retrieved; must not be null + * @param user the user whose favorite organizations are going to be returned. * @return a list of up to three formatted strings, each representing an organization - * and its donation count; empty list if the user has no donations + * and its donation count. Returns empty list if the user has no donations. */ public List userFavoriteOrganization(User user) { List favoriteOrganization = donationDao.getFavoriteOrganization(user.getID()); @@ -37,8 +36,8 @@ public List userFavoriteOrganization(User user) { * Returns a formatted list of all donations made by the user. * Each entry contains the donation amount, date, and organization. * - * @param user the user whose donation history is to be retrieved; must not be null - * @return a list of formatted donation strings; empty list if the user has no donations + * @param user the user whose donation history is returned. + * @return a list of formatted donation strings. Returns empty list if the user has no donations */ public List userDonations(User user) { List userDonationList = donationDao.getUserDonations(user.getID()); @@ -48,8 +47,8 @@ public List userDonations(User user) { /** * Returns the total amount donated by the user across all donations. * - * @param user the user whose total donation amount is to be calculated; must not be null - * @return a string representation of the total donated amount; {@code "0"} if no donations exist + * @param user the user whose total donation amount is returned. + * @return a string representation of the total donated amount. Returns "0" if no donations exist */ public String userTotalDonationAmount(User user) { String totalDonations = donationDao.getTotalDonationAmount(user.getID()); @@ -59,8 +58,8 @@ public String userTotalDonationAmount(User user) { /** * Returns the total number of donations made by the user. * - * @param user the user whose donation count is to be retrieved; must not be null - * @return a string representation of the total number of donations; {@code "0"} if none exist + * @param user the user whose donation count is returned. + * @return a string representation of the total number of donations. Returns "0" if none exist. */ public String getTotalDonationsMade(User user) { String totalDonationsMade = donationDao.getTotalDonationsMade(user.getID()); diff --git a/src/main/java/domain/donation/Cause.java b/src/main/java/domain/donation/Cause.java index ae9311d..a69854e 100644 --- a/src/main/java/domain/donation/Cause.java +++ b/src/main/java/domain/donation/Cause.java @@ -1,3 +1,6 @@ package domain.donation; +/** + * Enum class that contains 5 different cause types + */ public enum Cause { HEALTH, EMERGENCY_RELIEF, CHILDREN, ENVIRONMENT, CONFLICTS; } diff --git a/src/main/java/domain/donation/Donation.java b/src/main/java/domain/donation/Donation.java index ff49864..9835c00 100644 --- a/src/main/java/domain/donation/Donation.java +++ b/src/main/java/domain/donation/Donation.java @@ -7,6 +7,10 @@ import java.time.LocalDateTime; import java.util.Objects; +/** + * Donation object that defines what a Donation is. + * Provides set and get methods. + */ public class Donation { private Long id; //get set to null by default, // Gets set to a value by database when registered? @@ -15,6 +19,13 @@ public class Donation { private final User user; private final Organization organization; + /** + * Donation takes in parameters that is needed to define what a donation is. + * Requires both user and organization to be not null. + * @param amount + * @param user + * @param organization + */ public Donation(BigDecimal amount, User user, Organization organization) { Objects.requireNonNull(amount, "Amount cannot be null"); if (amount.compareTo(BigDecimal.ZERO) <= 0) { @@ -27,6 +38,15 @@ public Donation(BigDecimal amount, User user, Organization organization) { this.organization = Objects.requireNonNull(organization, "Organization cannot be null"); } + + /** + * Sets the database-generated ID for this donation. + * Can only be set once — throws if the ID is already assigned. + * + * @param id the ID to assign; must be a positive non-null value + * @throws IllegalStateException if the ID has already been set + * @throws IllegalArgumentException if {@code id} is null or not positive + */ public void setId(Long id) { if (this.id != null) { throw new IllegalStateException("ID is already set"); @@ -37,22 +57,47 @@ public void setId(Long id) { this.id = id; } + /** + * Returns the unique database ID of this donation. + * + * @return the donation ID + */ public long getId() { return id; } + /** + * Returns the amount of this donation. + * + * @return the donation amount as a {@link BigDecimal} + */ public BigDecimal getAmount() { return amount; } + /** + * Returns the date and time when this donation was created. + * + * @return the donation timestamp as a {@link LocalDateTime} + */ public LocalDateTime getDateTime() { return dateTime; } + /** + * Returns the user who made this donation. + * + * @return the {@link User} associated with this donation + */ public User getUser() { return user; } + /** + * Returns the organization this donation was made to. + * + * @return the {@link Organization} associated with this donation + */ public Organization getOrganization() { return organization; } diff --git a/src/main/java/domain/organization/Organization.java b/src/main/java/domain/organization/Organization.java index cf45d2e..f0a470a 100644 --- a/src/main/java/domain/organization/Organization.java +++ b/src/main/java/domain/organization/Organization.java @@ -6,6 +6,9 @@ import java.util.Objects; +/** + * Class + */ @JsonIgnoreProperties(ignoreUnknown = true) public class Organization { diff --git a/src/main/java/domain/user/Role.java b/src/main/java/domain/user/Role.java index 1eba6cd..673390f 100644 --- a/src/main/java/domain/user/Role.java +++ b/src/main/java/domain/user/Role.java @@ -1,4 +1,7 @@ package domain.user; +/** + * Enum class that defines if a user has the role Admin or user. + */ public enum Role {ADMIN, USER } diff --git a/src/main/java/domain/user/User.java b/src/main/java/domain/user/User.java index 69a51b8..8108d5a 100644 --- a/src/main/java/domain/user/User.java +++ b/src/main/java/domain/user/User.java @@ -1,5 +1,9 @@ package domain.user; +/** + * Class that defines what a User is. + * Contains get and set methods for each parameter, and validating methods. + */ public class User { private String userName; private String phoneNumber; @@ -7,6 +11,14 @@ public class User { private String password; private Long id; + /** + * Constructor that takes in the parameters that define a user. + * It contains input validation on all parameters. + * @param userName + * @param phoneNumber + * @param password + * @param eMail + */ public User(String userName, String phoneNumber, String password, String eMail) { if (userName == null || userName.isBlank()) { @@ -31,40 +43,90 @@ public User(String userName, String phoneNumber, String password, String eMail) this.password = password; } + /** + * Returns the username of this user. + * + * @return the username + */ public String getUsername() { return userName; } + /** + * Returns the phone number of this user. + * + * @return the phone number + */ public String getPhoneNumber() { return phoneNumber; } + /** + * Returns the email address of this user. + * + * @return the email address + */ public String getEMail() { return eMail; } + /** + * Returns the password of this user. + * + * @return the password hash + */ public String getPassword() { return password; } + /** + * Returns the ID of this user. + * + * @return the user ID + */ public long getID() { return id; } + /** + * Sets a new password hash for this user. + * + * @param password the new password hash; must not be null + */ public void setPassword(String password) { this.password = password; } + /** + * Sets a new username for this user. + * + * @param userName the new username; must not be null or blank + */ public void setUsername(String userName) { this.userName = userName; } + /** + * Sets a new phone number for this user. + * + * @param phoneNumber the new phone number; must be exactly 8 digits + */ public void setPhonenumber (String phoneNumber) { this.phoneNumber = phoneNumber; } + /** + * Sets the ID for this user. + * + * @param id the ID to assign + */ public void setId(Long id) { this.id = id; } + /** + * Method that validates that a e-mail is in the right format. + * @param email + * @return + */ private static boolean isValidEmail(String email) { if (email == null || email.isBlank()) return false; return email.matches("^[a-zA-Z0-9._%+\\-]+@[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,}$"); diff --git a/src/main/java/integration/InnsamlingskontrollenClient.java b/src/main/java/integration/InnsamlingskontrollenClient.java index c0786fa..1f97c5b 100644 --- a/src/main/java/integration/InnsamlingskontrollenClient.java +++ b/src/main/java/integration/InnsamlingskontrollenClient.java @@ -8,6 +8,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import domain.organization.Organization; +/** + * The InnsamlingskontrollenClient class provides functionality to fetch a list + * of organizations from the Innsamlingskontrollen API. The fetched data is + * represented as an array of Organization objects. + */ public class InnsamlingskontrollenClient { public static Organization[] fetchOrganizations() throws Exception { diff --git a/src/main/java/integration/security/Sha256PasswordHasher.java b/src/main/java/integration/security/Sha256PasswordHasher.java index 2e59caa..d6c4a4f 100644 --- a/src/main/java/integration/security/Sha256PasswordHasher.java +++ b/src/main/java/integration/security/Sha256PasswordHasher.java @@ -4,9 +4,21 @@ import java.security.MessageDigest; import java.nio.charset.StandardCharsets; +/** + * Class that takes in the chosen password of a user, and hashes it. + */ public class Sha256PasswordHasher implements PasswordHasher { - @Override + /** + * Method for hashing an inputted password. + * Uses the SHA-256 algorithm. + * Transforms the passoword to a UTF-8 byte-array, then digests it using SHA-256. + * The bytes are then formatted as a 64-character string. + * @param password + * @return a 64-character hash of the password. + * @throws RuntimeException if the hashing fails. + */ + @Override public String hash(String password) { try { MessageDigest md = MessageDigest.getInstance("SHA-256"); diff --git a/src/main/java/persistence/UserRepository.java b/src/main/java/persistence/UserRepository.java index 3aa8d43..9b92669 100644 --- a/src/main/java/persistence/UserRepository.java +++ b/src/main/java/persistence/UserRepository.java @@ -4,6 +4,11 @@ import java.util.Optional; +/** + * Interface that defines a "contract" for which methods the class that implements it has + * to contiain. + * Is created for UserDao class, to define which methods needs to be implemented. + */ public interface UserRepository { Optional findByUsername(String username); Optional findByEmail(String email); diff --git a/src/main/java/persistence/db/Database.java b/src/main/java/persistence/db/Database.java index 889bba1..b110a70 100644 --- a/src/main/java/persistence/db/Database.java +++ b/src/main/java/persistence/db/Database.java @@ -8,6 +8,9 @@ import java.sql.SQLException; import java.sql.Statement; +/** + * Class that initializes and connects to the generated database. + */ public final class Database { public static final String URL = "jdbc:sqlite:givehope.db"; @@ -15,6 +18,13 @@ public final class Database { initializeDatabase(); } + /** + * Methods that provides a connection the URL/file that is initialized. + * Runs "PRAGMA FOREIGN KEYS = ON", which turns foreign key check on in SQLite. + * Connection class is used connects the java-code to the database/SQL-code. + * @return returns connection to database. + * @throws SQLException + */ public static Connection getConnection() throws SQLException { Connection conn = DriverManager.getConnection(URL); try (Statement stmt = conn.createStatement()) { @@ -23,6 +33,12 @@ public static Connection getConnection() throws SQLException { return conn; } + /** + * Method that initializes/creates the database. + * Uses file "schema.sql" to create, which contains SQL-code that creates the tables. + * Splits string at ";", to separate each CREATE TABLE-sentences. + * @throws RuntimeException if the schema file cannot be read or a database error occurs. + */ public static void initializeDatabase() { try (Connection conn = DriverManager.getConnection(URL); Statement stmt = conn.createStatement()) { diff --git a/src/main/java/util/SessionManager.java b/src/main/java/util/SessionManager.java index 9d020c3..3cbf39c 100644 --- a/src/main/java/util/SessionManager.java +++ b/src/main/java/util/SessionManager.java @@ -2,25 +2,46 @@ import domain.user.User; +/** + * Class that manages current user session for the application. + * Has methods that keep track of if a user is signed in or not. + * Only one user can be signed in at a time. + */ public class SessionManager { private static boolean SignedIn = false; private static User currentUser = null; - public static void signIn(User user) { + /** + * Signs in a user. + * Stores the user as the current session holder. + * @param the user tom sign in. + */ + public static void signIn(User user) { SignedIn = true; currentUser = user; } - public static void signOut() { + /** + * Signs out current user by clearing session. + */ + public static void signOut() { SignedIn = false; currentUser = null; } - public static boolean isSignedIn() { + /** + * Method returns boolean value on whether a user is signed in. + * @return false if user is not signed in, true if signed in. + */ + public static boolean isSignedIn() { return SignedIn; } - public static User getCurrentUser() { + /** + * Method that returns the current user that the session contains. + * @return the current user + */ + public static User getCurrentUser() { return currentUser; } } From a406ff6d1797a6fbbea630f51524c1adedf57707 Mon Sep 17 00:00:00 2001 From: lukaceli Date: Wed, 15 Apr 2026 11:23:46 +0200 Subject: [PATCH 3/4] Added javadoc to UserRegister and UserSignIn --- .../java/application/user/UserRegister.java | 26 ++++++++++++++++++- .../java/application/user/UserSignIn.java | 23 +++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/main/java/application/user/UserRegister.java b/src/main/java/application/user/UserRegister.java index 337b378..adc2107 100644 --- a/src/main/java/application/user/UserRegister.java +++ b/src/main/java/application/user/UserRegister.java @@ -4,16 +4,40 @@ import domain.user.User; import persistence.UserRepository; +/** + * The UserRegister class is responsible for handling the user registration process. + * It ensures that the provided user details meet the necessary criteria and that + * the username and email are not already in use. It also hashes the user's password + * before saving the user information into the repository. + */ public class UserRegister { private final PasswordHasher hasher; private final UserRepository repo; - public UserRegister(PasswordHasher hasher, UserRepository repo) { + /** + * Constructs a {@code UserRegister} instance responsible for handling the user registration process. + * It ensures user details meet validation criteria, such as uniqueness of username and email, + * and hashes passwords before saving user information into the repository. + * + * @param hasher a {@code PasswordHasher} implementation used to hash user passwords. + * @param repo a {@code UserRepository} implementation responsible for storing user data. + */ + public UserRegister(PasswordHasher hasher, UserRepository repo) { this.hasher = hasher; this.repo = repo; } + /** + * Executes a user registration. + * Validation checks, checks if username or e-mail already exists. + * Hashes inputted password using PasswordHasher, that uses SHA256PasswordHasher. + * Creates user object, and inserts it into UserRepository using insert method. + * @param username + * @param phoneNumber + * @param password + * @param email + */ public void execute(String username, String phoneNumber, String password, String email) { username = username.trim(); email = email.trim().toLowerCase(); diff --git a/src/main/java/application/user/UserSignIn.java b/src/main/java/application/user/UserSignIn.java index 08a6dc6..be6b159 100644 --- a/src/main/java/application/user/UserSignIn.java +++ b/src/main/java/application/user/UserSignIn.java @@ -4,16 +4,37 @@ import domain.user.User; import persistence.UserRepository; +/** + * The UserSignIn class handles the process of user authentication. + * It verifies the input credentials (login and password) against the stored user data. + * The password is validated through hashing and comparison with the stored hash. + */ public class UserSignIn { private final PasswordHasher hasher; private final UserRepository repo; - public UserSignIn(PasswordHasher hasher, UserRepository repo) { + /** + * Constructs a {@code UserSignIn} instance responsible for user authentication. + * It handles the process of verifying user credentials by comparing the provided + * input with stored data in the repository and validating the password through hashing. + * + * @param hasher a {@code PasswordHasher} implementation used to hash and validate user passwords. + * @param repo a {@code UserRepository} implementation that stores user authentication data. + */ + public UserSignIn(PasswordHasher hasher, UserRepository repo) { this.hasher = hasher; this.repo = repo; } + /** + * Execute methods, that takes in inputted login and password. + * Checks via UserRepository if login exists in database. + * Compares hashed input password with hashed password in database. + * @param login inputted login by user + * @param password inputted password by user + * @return user object, if it exists. + */ public User execute(String login, String password) { // normalize (trim etc.) login.trim().toLowerCase(); From 349171c8093e6af7ccddc1fe7f7c81c2a73f4e08 Mon Sep 17 00:00:00 2001 From: lukaceli Date: Wed, 15 Apr 2026 11:31:03 +0200 Subject: [PATCH 4/4] Added javadoc to Page enum and NavigationAware --- src/main/java/ui/Page.java | 4 ++++ src/main/java/ui/controller/NavigationAware.java | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/main/java/ui/Page.java b/src/main/java/ui/Page.java index e2066c8..c788a50 100644 --- a/src/main/java/ui/Page.java +++ b/src/main/java/ui/Page.java @@ -1,5 +1,9 @@ package ui; +/** + * Represents the different pages available in the application, where each page + * is associated with a specific FXML file used for its layout. + */ public enum Page { HOME("Home.fxml"), PROFILE("MyProfile.fxml"), diff --git a/src/main/java/ui/controller/NavigationAware.java b/src/main/java/ui/controller/NavigationAware.java index a04623e..82f215f 100644 --- a/src/main/java/ui/controller/NavigationAware.java +++ b/src/main/java/ui/controller/NavigationAware.java @@ -4,6 +4,17 @@ import java.util.function.Consumer; +/** + * Interface for controllers that need to navigate between pages. + * Controllers that implement this interface can switch to a different page + * by calling the navigation function they receive. + */ public interface NavigationAware { + + /** + * Sets the navigation function that the controller can use to switch pages. + * + * @param onNavigate a function that takes a {@link Page} and navigates to it + */ void setOnNavigate(Consumer onNavigate); } \ No newline at end of file