Skip to content

Commit

Permalink
feat: merged release/v1.0.0 into feat/loginpage
Browse files Browse the repository at this point in the history
  • Loading branch information
MatheaGjerde committed Mar 11, 2026
2 parents f200ee8 + 075f0e5 commit 73191e3
Show file tree
Hide file tree
Showing 24 changed files with 2,137 additions and 401 deletions.
482 changes: 482 additions & 0 deletions google_checks.xml

Large diffs are not rendered by default.

38 changes: 31 additions & 7 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
<classifier>win</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>${javafx.version}</version>
<classifier>win</classifier>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-crypto -->
<dependency>
Expand All @@ -45,13 +52,17 @@
<version>3.1.0</version>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.3.5</version>
</dependency>
</dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>6.1.10</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.9</version>
</dependency>
</dependencies>

<build>
<plugins>
Expand Down Expand Up @@ -112,6 +123,19 @@
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>META-INF/NOTICE</exclude>
<exclude>META-INF/LICENSE</exclude>
<exclude>META-INF.versions.9.module-info</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>edu.group5.app.App</mainClass>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,24 @@
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

import tools.jackson.core.exc.StreamReadException;
import tools.jackson.databind.ObjectMapper;

public class OrgAPIWrapper extends Wrapper {
/**
* A Class for Wrapping an API.
*/
public class OrgApiWrapper extends Wrapper {
private Object[] data;
private HttpClient client;
private HttpRequest request;

public OrgAPIWrapper(String urlString) {
/**
* The constructor, which takes a url String and constructs a URI and HttpRequest object from it.
* If the url is invalid, it will throw a fitting exception.
*
* @param urlString A string of the URL that's being connected to.
*/
public OrgApiWrapper(String urlString) {
if (urlString == null) {
throw new IllegalArgumentException("url can't be null");
} else if (urlString.isBlank()) {
Expand All @@ -33,6 +41,15 @@ public OrgAPIWrapper(String urlString) {

}

/**
* A method for importing data from the wrapped API.
*
* @return Returns a boolean, which indicates if the import was successful. Will be False if, for
* example, there is no internet connection.
*
* @throws InterruptedException This exception is thrown whenever the program is interrupted, like
* by ctrl + c.
*/
@Override
public boolean importData() throws InterruptedException {
try {
Expand All @@ -47,6 +64,11 @@ public boolean importData() throws InterruptedException {
}
}

/**
* A method for accessing the imported data.
*
* @return Returns an array with HashMaps, which is how data is structured in the API.
*/
@Override
public Object[] getData() {
return this.data;
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/edu/group5/app/control/Wrapper.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
package edu.group5.app.control;

/**
* An abstract class for all Wrappers of datasets.
*/
abstract class Wrapper {

protected Wrapper() {
}

/**
* An abstract method for importing data from the dataset that child methods wrap.
*
* @return Returns a boolean, which indicates if the import was successful. Will be False if, for
* example, there is no internet connection.
*
* @throws InterruptedException This exception is thrown whenever the program is interrupted, like
* by ctrl + c.
*/
public abstract boolean importData() throws InterruptedException;

/**
* An abstract method to access the imported data.
*
* @return Returns a fitting parsed Object directly from the dataset.
*/
public abstract Object getData();
}
22 changes: 19 additions & 3 deletions src/main/java/edu/group5/app/model/DBRepository.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package edu.group5.app.model;


import java.util.HashMap;
import java.util.Map;

import java.util.List;
/**
* Abstract base class for repositories that store their data
* in a database-related structure.
Expand All @@ -14,12 +12,30 @@
* </p>
*/
public abstract class DBRepository<K, V> extends Repository<K, V> {
protected final Map<K, V> contentLock;
/**
* Constructs a DBRepository with the given content.
*
* @param content the HashMap used to store repository entities
*/
protected DBRepository(Map<K, V> content) {
super(content);
this.contentLock = new HashMap<>();
}

protected void updateContentLock() {
synchronized (contentLock) {
contentLock.clear();
contentLock.putAll(this.content);
}
}

public abstract boolean addContent(V value);

/**
* Exports the repository content as a list of Object arrays, where each array represents a row of data.
* This method is intended for converting the repository content into a format suitable for database storage or export.
* @return a List of Object arrays representing the repository content for database export
*/
public abstract List<Object[]> export();
}
2 changes: 1 addition & 1 deletion src/main/java/edu/group5/app/model/Repository.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public abstract class Repository<K, V> {
*
* @param content the underlying data structure used to store entities
*/
public Repository(Map<K, V> content) {
protected Repository(Map<K, V> content) {
this.content = content;
}

Expand Down
103 changes: 90 additions & 13 deletions src/main/java/edu/group5/app/model/donation/DonationRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.List;
import java.math.BigDecimal;
import java.sql.Timestamp;

/**
* Repository class for Donation.
Expand All @@ -19,17 +22,70 @@ public class DonationRepository extends DBRepository<Integer, Donation> {
private final HashMap<Integer, Donation> content;

/**
* Constructs DonationRepository using Hashmap,
* and extends the content from DBRepository.
* @param content the underlying map used to store donations,
* where the key represents the donation ID
* Constructs DonationRepository from a list of Object[] rows from the database.
* @param rows List of Object[] representing donations from the DB.
* Each row must have 6 elements:
* [donationId, userId, organizationId, amount, date, paymentMethod]
* @throws IllegalArgumentException if the input list is null or any row is invalid
*/
public DonationRepository(HashMap<Integer, Donation> content){
if (content == null) {
throw new IllegalArgumentException("Content cannot be null");
public DonationRepository(List<Object[]> rows) {
super(new HashMap<>());
if (rows == null) {
throw new IllegalArgumentException("The list of rows cannot be null");
}
super(content);
this.content = content;
this.content = new HashMap<>();
for (Object[] row : rows) {
if (row == null || row.length != 6 ) {
throw new IllegalArgumentException("Each row must contain exactly 6 elements");
}
int donationId = (int) row[0];
int customerId = (int) row[1];
int organizationId = (int) row[2];
BigDecimal amount = (BigDecimal) row[3];
Timestamp date = (Timestamp) row[4];
String paymentMethod = (String) row[5];

Donation donation = new Donation(donationId, customerId, organizationId, amount, date, paymentMethod);
this.content.put(donationId, donation);
}
super.updateContentLock();
}

@Override
public List<Object[]> export() {
return content.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.map(entry -> { Donation donation = entry.getValue();
return new Object[] {
donation.donationId(), donation.userId(),
donation.organizationId(), donation.amount(),
donation.date(), donation.paymentMethod()};})
.toList();
}

/**
* Retrieves a donation by its ID.
* @param donationId the ID of the donation to retrieve
* @return the Donation object with the specified ID, or null if not found
* @throws IllegalArgumentException if the donationId is not positive
*/
public Donation getDonationById(int donationId) {
if (donationId <= 0) {
throw new IllegalArgumentException("Donation ID must be positive");
}
return content.get(donationId);
}

/**
* Generates the next donation ID based on the current maximum ID in the repository.
* @return the next donation ID to be used for a new donation
*/
public int getNextDonationId() {
return content.keySet().stream().max(Integer::compareTo).orElse(0) + 1;
} /* TODO change this when data database is introduced */

public Map<Integer, Donation> getAllDonations() {
return new HashMap<>(content);
}

/**
Expand All @@ -44,14 +100,15 @@ public DonationRepository(HashMap<Integer, Donation> content){
* @return {@code true} if the donation was successfully added, and
* {@code false} if a donation with the same ID already exists
*/
public boolean addDonation(Donation donation) {
@Override
public boolean addContent(Donation donation) {
if (donation == null) {
throw new IllegalArgumentException("Donation cannot be null");
}
if (content.containsKey(donation.donationId())){
return false;
return false;
}
content.put(donation.donationId(), donation);
this.content.put(donation.donationId(), donation);
return true;
}

Expand Down Expand Up @@ -98,9 +155,9 @@ public HashMap<Integer, Donation> sortByAmount() {

/**
* Returns all donations associated with a specific organization.
*
* @param orgNumber the organization ID to filter by
* @return a map containing all donations that belong to the given organization
* @throws IllegalArgumentException if the orgNumber is not positive
*/
public HashMap<Integer, Donation> filterByOrganization(int orgNumber) {
if (orgNumber <= 0) {
Expand All @@ -116,4 +173,24 @@ public HashMap<Integer, Donation> filterByOrganization(int orgNumber) {
LinkedHashMap::new
));
}

/**
* Returns all donations made by a specific user.
* @param userId the user ID to filter by
* @return a map containing all donations that belong to the given user
* @throws IllegalArgumentException if the userId is not positive
*/
public HashMap<Integer, Donation> filterByUser(int userId) {
if (userId <= 0) {
throw new IllegalArgumentException("User ID must be positive");
}
return content.entrySet().stream()
.filter(entry -> entry.getValue().userId() == userId)
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1,
LinkedHashMap::new
));
}
}
Loading

0 comments on commit 73191e3

Please sign in to comment.