Skip to content

Commit

Permalink
Merge pull request #151 from TAMULib/150-add_encoding_unit_tests
Browse files Browse the repository at this point in the history
Issue 150: Fix problems with encoding/decoding and add encoding unit tests.
  • Loading branch information
kaladay authored Oct 18, 2024
2 parents 426d393 + a832e85 commit ec802b9
Show file tree
Hide file tree
Showing 168 changed files with 6,042 additions and 1,040 deletions.
12 changes: 12 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,18 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-junit-jupiter-no-dependencies</artifactId>
<version>5.14.0</version>
</dependency>

<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-client-java-no-dependencies</artifactId>
<version>5.14.0</version>
</dependency>

<dependency>
<groupId>it.ozimov</groupId>
<artifactId>embedded-redis</artifactId>
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/edu/tamu/iiif/exception/NotFoundException.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ public NotFoundException(String message) {
super(message);
}

public NotFoundException(String message, Exception e) {
super(message, e);
}

}
105 changes: 40 additions & 65 deletions src/main/java/edu/tamu/iiif/service/AbstractManifestService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,14 @@

import static edu.tamu.iiif.constants.Constants.IIIF_IMAGE_API_CONTEXT;
import static edu.tamu.iiif.constants.Constants.IIIF_IMAGE_API_LEVEL_ZERO_PROFILE;
import static edu.tamu.iiif.utility.RdfModelUtility.createRdfModel;
import static edu.tamu.iiif.utility.RdfModelUtility.getObjects;
import static edu.tamu.iiif.utility.StringUtility.encode;
import static edu.tamu.iiif.utility.StringUtility.encodeSpaces;
import static edu.tamu.iiif.utility.StringUtility.joinPath;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.annotation.PostConstruct;

import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.Property;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.rdf.model.Resource;
import org.apache.jena.rdf.model.Statement;
import org.apache.jena.rdf.model.StmtIterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import de.digitalcollections.iiif.presentation.model.api.v2.Canvas;
import de.digitalcollections.iiif.presentation.model.api.v2.Image;
import de.digitalcollections.iiif.presentation.model.api.v2.ImageResource;
Expand All @@ -66,6 +34,31 @@
import edu.tamu.iiif.model.RedisManifest;
import edu.tamu.iiif.model.rdf.RdfResource;
import edu.tamu.iiif.model.repo.RedisManifestRepo;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.Property;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.rdf.model.Resource;
import org.apache.jena.rdf.model.Statement;
import org.apache.jena.rdf.model.StmtIterator;
import org.apache.jena.riot.RDFDataMgr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

public abstract class AbstractManifestService implements ManifestService {

Expand Down Expand Up @@ -134,7 +127,6 @@ public String getManifest(ManifestRequest request) throws IOException, URISyntax
redisManifestRepo.save(new RedisManifest(encode(path), getManifestType(), getRepository(), request.getAllowed(), request.getDisallowed(), manifest));
update = false;
}

if (update) {
RedisManifest redisManifest = optionalRedisManifest.get();
manifest = generateManifest(request);
Expand All @@ -144,17 +136,16 @@ public String getManifest(ManifestRequest request) throws IOException, URISyntax
} else {
logger.info("Manifest requested: " + path);
}

return manifest;
}

protected RdfResource getRdfResourceByContextPath(String contextPath) throws NotFoundException {
protected RdfResource getRdfResourceByContextPath(String contextPath) throws IOException {
String rdfUrl = getRdfUrl(contextPath);
Model model = getRdfModel(rdfUrl);
return getRdfResource(model, rdfUrl);
}

protected RdfResource getRdfResourceByUrl(String rdfUrl) throws NotFoundException {
protected RdfResource getRdfResourceByUrl(String rdfUrl) throws IOException {
Model model = getRdfModel(rdfUrl);
return getRdfResource(model, rdfUrl);
}
Expand All @@ -165,30 +156,12 @@ private RdfResource getRdfResource(Model model, String rdfUrl) {
return new RdfResource(model, model.getResource(rdfUrl));
}

protected Model getRdfModel(String url) throws NotFoundException {
return createRdfModel(getRdf(url));
}

private String getRdf(String url) throws NotFoundException {
try {
url = URLDecoder.decode(url, StandardCharsets.UTF_8);
if (logger.isDebugEnabled()) {
logger.info("Requesting RDF for {}", url);
}
Optional<String> rdf = Optional.ofNullable(restTemplate.getForObject(url, String.class));
if (rdf.isPresent()) {
logger.debug("RDF for {}: \n{}\n", url, rdf.get());
return rdf.get();
}
} catch (RestClientException e) {
logger.error("Failed to get RDF for {}: {}", url, e.getMessage());
logger.debug("Error while requesting RDF for {}: {}", url, e.getMessage(), e);
}
throw new NotFoundException("RDF not found! " + url);
protected Model getRdfModel(String url) throws IOException {
return RDFDataMgr.loadModel(url);
}

protected URI buildId(String path) throws URISyntaxException {
return new URI(encodeSpaces(getIiifServiceUrl() + FORWARD_SLASH + getManifestType().getName() + FORWARD_SLASH + path));
return new URI(getIiifServiceUrl() + FORWARD_SLASH + getManifestType().getName() + FORWARD_SLASH + path);
}

protected String getLogo(RdfResource rdfResource) {
Expand Down Expand Up @@ -285,11 +258,12 @@ protected boolean includeResource(ManifestRequest request, String mimeType) {

protected String fetchImageInfo(String url) throws NotFoundException {
logger.debug("Fetching image info {}", url);
Optional<String> imageInfo = Optional.ofNullable(restTemplate.getForObject(url, String.class));
if (imageInfo.isPresent()) {
return imageInfo.get();

try {
return restTemplate.getForObject(url, String.class);
} catch (RestClientException e) {
throw new NotFoundException("Image not found for " + url, e);
}
throw new NotFoundException("Image information not found!");
}

protected URI getImageUri(String url) throws URISyntaxException {
Expand Down Expand Up @@ -503,12 +477,13 @@ protected Optional<JsonNode> getImageInfo(String url) {
}

protected Optional<String> getMimeType(String url) {
try {
HttpHeaders headers = restTemplate.headForHeaders(url);
return Optional.ofNullable(headers.getFirst(HttpHeaders.CONTENT_TYPE));
} catch (RestClientException e) {
HttpHeaders headers = restTemplate.headForHeaders(url);

if (headers == null) {
return Optional.empty();
}

return Optional.ofNullable(headers.getFirst(HttpHeaders.CONTENT_TYPE));
}

private Metadata buildMetadata(String label, String value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.util.Optional;

import org.apache.commons.validator.routines.UrlValidator;
import org.apache.http.Header;
import org.apache.http.HttpRequest;
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/edu/tamu/iiif/service/ManifestService.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
public interface ManifestService {

public String getManifest(ManifestRequest request) throws IOException, URISyntaxException;

public String getRepository();

public ManifestType getManifestType();

}
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
package edu.tamu.iiif.service;

import edu.tamu.iiif.exception.NotFoundException;
import edu.tamu.iiif.model.RedisResource;
import edu.tamu.iiif.model.repo.RedisResourceRepo;
import java.net.URISyntaxException;
import java.util.Optional;

import org.apache.commons.validator.routines.UrlValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;

import edu.tamu.iiif.exception.NotFoundException;
import edu.tamu.iiif.model.RedisResource;
import edu.tamu.iiif.model.repo.RedisResourceRepo;

@Service
@ConditionalOnProperty(value = "iiif.resolver.type", havingValue = "redis", matchIfMissing = true)
public class RedisResourceResolver implements ResourceResolver {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,8 @@
import static edu.tamu.iiif.constants.Constants.PRESENTATION_IDENTIFIER;
import static edu.tamu.iiif.constants.Constants.SEQUENCE_IDENTIFIER;
import static edu.tamu.iiif.utility.RdfModelUtility.hasObject;
import static edu.tamu.iiif.utility.StringUtility.encodeSpaces;
import static edu.tamu.iiif.utility.StringUtility.joinPath;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.NodeIterator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;

import de.digitalcollections.iiif.presentation.model.api.v2.Canvas;
import de.digitalcollections.iiif.presentation.model.api.v2.ImageResource;
import de.digitalcollections.iiif.presentation.model.api.v2.Sequence;
Expand All @@ -43,6 +28,18 @@
import edu.tamu.iiif.model.rdf.RdfResource;
import edu.tamu.iiif.service.AbstractManifestService;
import edu.tamu.iiif.utility.RdfModelUtility;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.NodeIterator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;

@ConditionalOnExpression(DSPACE_RDF_CONDITION)
public abstract class AbstractDSpaceRdfManifestService extends AbstractManifestService {
Expand Down Expand Up @@ -90,19 +87,19 @@ protected boolean isItem(Model model) {
}

protected URI getDSpaceIiifCollectionUri(String handle) throws URISyntaxException {
return getDSpaceIiifUri(encodeSpaces(handle), COLLECTION_IDENTIFIER);
return getDSpaceIiifUri(handle, COLLECTION_IDENTIFIER);
}

protected URI getDSpaceIiifPresentationUri(String handle) throws URISyntaxException {
return getDSpaceIiifUri(encodeSpaces(handle), PRESENTATION_IDENTIFIER);
return getDSpaceIiifUri(handle, PRESENTATION_IDENTIFIER);
}

protected URI getDSpaceIiifSequenceUri(String handle) throws URISyntaxException {
return getDSpaceIiifUri(encodeSpaces(handle), SEQUENCE_IDENTIFIER);
return getDSpaceIiifUri(handle, SEQUENCE_IDENTIFIER);
}

protected URI getDSpaceIiifCanvasUri(String handle) throws URISyntaxException {
return getDSpaceIiifUri(encodeSpaces(handle), CANVAS_IDENTIFIER);
return getDSpaceIiifUri(handle, CANVAS_IDENTIFIER);
}

protected String getHandle(String uri) {
Expand Down Expand Up @@ -181,7 +178,7 @@ private URI getDSpaceIiifUri(String handle, String type) throws URISyntaxExcepti
private List<Canvas> getCanvases(ManifestRequest request, RdfResource rdfResource) throws IOException, URISyntaxException {
List<Canvas> canvases = new ArrayList<Canvas>();
// NOTE: canvas per bitstream and bitstreams uri must contain the context handle path of the desired resource
String contextHandlePath = encodeSpaces(getHandlePath(rdfResource.getId()));
String contextHandlePath = getHandlePath(rdfResource.getId());
NodeIterator bitstreamIterator = rdfResource.getAllNodesOfPropertyWithId(DSPACE_HAS_BITSTREAM_PREDICATE);
while (bitstreamIterator.hasNext()) {
String uri = bitstreamIterator.next().toString();
Expand Down
Loading

0 comments on commit ec802b9

Please sign in to comment.