Skip to content

Feat/wrapper #41

Merged
merged 6 commits into from
Mar 4, 2026
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,10 @@ out/
## VSCode
##############################
.vscode/

##############################
## Misc
##############################
.settings/*
.project
.classpath
30 changes: 30 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@
<artifactId>spring-security-crypto</artifactId>
<version>7.0.2</version>
</dependency>
<!-- Source: https://mvnrepository.com/artifact/tools.jackson.core/jackson-databind -->
<dependency>
<groupId>tools.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>3.1.0</version>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
Expand Down Expand Up @@ -91,6 +99,28 @@
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.12.0</version>
</plugin>

<!-- Fat JAR plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>edu.group5.app.App</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
20 changes: 17 additions & 3 deletions src/main/java/edu/group5/app/App.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
package edu.group5.app;

import java.util.HashMap;

import edu.group5.app.control.OrgAPIWrapper;
import tools.jackson.core.type.TypeReference;
import tools.jackson.databind.ObjectMapper;

/**
* Hello world!
*/
public class App {
public static void main(String[] args) {
System.out.println("Hello World!");
}
public static void main(String[] args) throws InterruptedException {
OrgAPIWrapper orgWrap = new OrgAPIWrapper("https://app.innsamlingskontrollen.no/api/public/v1/all");
System.out.println();
System.out.println();
orgWrap.importData();
Object[] imports = orgWrap.getData();
ObjectMapper objectMapper = new ObjectMapper();
HashMap<String, Object> map = objectMapper.convertValue(imports[0], new TypeReference<HashMap<String, Object>>() {
});
System.out.println(map.get("org_number"));
}
}
54 changes: 54 additions & 0 deletions src/main/java/edu/group5/app/control/OrgAPIWrapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package edu.group5.app.control;

import java.io.IOException;
import java.net.URI;
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 {
private Object[] data;
private HttpClient client;
private HttpRequest request;

public OrgAPIWrapper(String urlString) {
if (urlString == null) {
throw new IllegalArgumentException("url can't be null");
} else if (urlString.isBlank()) {
throw new IllegalArgumentException("url can't be blank");
}
try {
URI uri = URI.create(urlString);
this.client = HttpClient.newHttpClient();
this.request = HttpRequest.newBuilder()
.uri(uri)
.GET()
.build();
} catch (IllegalArgumentException IAe) {
throw new IllegalArgumentException("url has to be valid");
}

}

@Override
public boolean importData() throws InterruptedException {
try {
HttpResponse<String> response = this.client.send(
this.request, HttpResponse.BodyHandlers.ofString());
this.data = new ObjectMapper().readValue(response.body(), Object[].class);
return true;
} catch (IOException IOe) {
return false;
} catch (StreamReadException e) {
throw new StreamReadException("The URL leads to a website that can't be parsed");
}
}

@Override
public Object[] getData() {
return this.data;
}
}
10 changes: 8 additions & 2 deletions src/main/java/edu/group5/app/control/Wrapper.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package edu.group5.app.control;

public class Wrapper {

abstract class Wrapper {

protected Wrapper() {
}

public abstract boolean importData() throws InterruptedException;

public abstract Object getData();
}
35 changes: 20 additions & 15 deletions src/main/java/edu/group5/app/model/organization/Organization.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
/**
* Represents an organization.
*
* <p>An organization is identified by an organization number, a name,
* <p>
* An organization is identified by an organization number, a name,
* trust status, website URL, pre-approval status, and a textual description.
*
* <p>Instances are validated on creation:
* <p>
* Instances are validated on creation:
* <ul>
* <li>orgNumber must be non-negative</li>
* <li>name and websiteURL must not be null or blank</li>
* <li>description must not be null</li>
* <li>orgNumber must be non-negative</li>
* <li>name and websiteURL must not be null or blank</li>
* <li>description must not be null</li>
* </ul>
*/
public record Organization(
Expand All @@ -21,21 +23,24 @@ public record Organization(
boolean trusted,
String websiteURL,
boolean isPreApproved,
String description
) {
String description) {
/**
* Creates a new organization.
*
* @param orgNumber the organization number; must be non-negative
* @param name the organization name; must not be null or blank
* @param trusted whether the organization is trusted
* @param websiteURL the organization's website URL; must not be null or blank
* @param orgNumber the organization number; must be non-negative
* @param name the organization name; must not be null or blank
* @param trusted whether the organization is trusted
* @param websiteURL the organization's website URL; must not be null or
* blank
* @param isPreApproved whether the organization is pre-approved
* @param description a textual description of the organization; must not be null
* @throws NullPointerException if name, websiteURL or description is null
* @throws IllegalArgumentException if orgNumber is negative, or if name or websiteURL is blank
* @param description a textual description of the organization; must not be
* null
* @throws NullPointerException if name, websiteURL or description is null
* @throws IllegalArgumentException if orgNumber is negative, or if name or
* websiteURL is blank
*/
public Organization(int orgNumber, String name, boolean trusted, String websiteURL, boolean isPreApproved, String description) {
public Organization(int orgNumber, String name, boolean trusted, String websiteURL, boolean isPreApproved,
String description) {
if (orgNumber < 0) {
throw new IllegalArgumentException("orgNumber cannot be negative");
}
Expand Down
74 changes: 74 additions & 0 deletions src/test/java/edu/group5/app/control/OrgAPIWrapperTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package edu.group5.app.control;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import tools.jackson.core.exc.StreamReadException;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.lang.IllegalArgumentException;

public class OrgAPIWrapperTest {
String testURL;
String wrongURL;
String wrongURL2;

@BeforeEach
void init() {
this.testURL = "https://app.innsamlingskontrollen.no/api/public/v1/all";
this.wrongURL = "This is not a URL";
this.wrongURL2 = "https://www.google.com";
}

@Test
public void nullURLThrowsException() {
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
() -> new OrgAPIWrapper(null));
assertEquals("url can't be null", exception.getMessage());
}

@Test
public void emptyURLThrowsException() {
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> new OrgAPIWrapper(""));
assertEquals("url can't be blank", exception.getMessage());
}

@Test
public void faultyURLThrowsException() {
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
() -> new OrgAPIWrapper(this.wrongURL));
assertEquals("url has to be valid", exception.getMessage());
}

// @Test
// public void noConnectionReturnsFalseImport() {
// assertDoesNotThrow(() -> {
// OrgAPIWrapper api = new OrgAPIWrapper(this.testURL);
// assertFalse(api.importData());
// });
// }

@Test
public void importsNonEmptyData() {
assertDoesNotThrow(() -> {
OrgAPIWrapper api = new OrgAPIWrapper(testURL);
assertTrue(api.importData());
assertFalse(api.getData().length == 0);
});
}

@Test
public void nonParseableSiteThrowsExceptionWhenImporting() {
assertDoesNotThrow(() -> {
OrgAPIWrapper api = new OrgAPIWrapper(this.wrongURL2);
StreamReadException exception = assertThrows(StreamReadException.class, () -> api.importData());
assertEquals("The URL leads to a website that can't be parsed", exception.getMessage());
});
}

}