Skip to content

Commit

Permalink
Update DownloadImage logic to use jp2 over original file when getting…
Browse files Browse the repository at this point in the history
… extent
  • Loading branch information
bbpennel committed Mar 5, 2024
1 parent c4bab04 commit b4fd38e
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import edu.unc.lib.boxc.search.api.models.Datastream;
import edu.unc.lib.boxc.web.services.utils.ImageServerUtil;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
Expand Down Expand Up @@ -68,11 +69,7 @@ public String getSize(ContentObjectRecord contentObjectRecord, String size) {
if (integerSize <= 0 ) {
throw new IllegalArgumentException(INVALID_SIZE_MESSAGE);
} else {
// format of dimensions is like 800x1200
var datastreamObject = getDatastream(contentObjectRecord);
String dimensions = datastreamObject.getExtent();
String[] dimensionParts = dimensions.split("x");
int longerSide = Math.max(Integer.parseInt(dimensionParts[0]), Integer.parseInt(dimensionParts[1]));
var longerSide = getLongestSide(contentObjectRecord);
// request is bigger than or equal to full size, so we will switch to full size
if (integerSize >= longerSide) {
return FULL_SIZE;
Expand Down Expand Up @@ -106,6 +103,30 @@ private Datastream getDatastream(ContentObjectRecord contentObjectRecord) {
return contentObjectRecord.getDatastreamObject(id);
}

/**
* Get the extent value for the JP2 datastream, falling back to the original file if not set
* @param contentObjectRecord
* @return extent in string format
*/
private String getExtent(ContentObjectRecord contentObjectRecord) {
var ds = contentObjectRecord.getDatastreamObject(DatastreamType.JP2_ACCESS_COPY.getId());
String extent = ds == null ? null : ds.getExtent();
if (StringUtils.isEmpty(extent)) {
ds = contentObjectRecord.getDatastreamObject(DatastreamType.ORIGINAL_FILE.getId());
}
return ds.getExtent();
}

private int getLongestSide(ContentObjectRecord contentObjectRecord) {
var extent = getExtent(contentObjectRecord);
if (StringUtils.isEmpty(extent)) {
return 0;
}
// format of dimensions is like 800x1200, heightxwidth
String[] dimensionParts = extent.split("x");
return Math.max(Integer.parseInt(dimensionParts[0]), Integer.parseInt(dimensionParts[1]));
}

public void setIiifBasePath(String iiifBasePath) {
this.iiifBasePath = iiifBasePath;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ public void testGetImageAtPixelSizeSmallerThanFull() throws Exception {
when(originalDatastream.getExtent()).thenReturn("1200x1200");
when(originalDatastream.getFilename()).thenReturn(filename);
when(contentObjectSolrRecord.getDatastreamObject(DatastreamType.JP2_ACCESS_COPY.getId())).thenReturn(jp2Datastream);
when(jp2Datastream.getExtent()).thenReturn("1200x1200");
when(contentObjectSolrRecord.getPid()).thenReturn(pid);

MvcResult result = mvc.perform(get("/downloadImage/" + pidString + "/800"))
Expand Down Expand Up @@ -197,6 +198,40 @@ public void testGetImageAtPixelSizeBiggerThanFullNoPermission() throws Exception
assertEquals("Insufficient permissions", response.getContentAsString());
}

@Test
public void testGetImageFromJp2AtPixelSizeBiggerThanFull() throws Exception {
var pid = makePid();
var pidString = pid.getId();
var formattedPid = ImageServerUtil.getImageServerEncodedId(pidString);
var filename = "bunny.jpg";
ContentObjectSolrRecord contentObjectSolrRecord = mock(ContentObjectSolrRecord.class);
Datastream originalDatastream = mock(Datastream.class);
Datastream jp2Datastream = mock(Datastream.class);

stubFor(WireMock.get(urlMatching("/" + formattedPid + "/full/max/0/default.jpg"))
.willReturn(aResponse()
.withStatus(HttpStatus.OK.value())
.withBodyFile(filename)
.withHeader("Content-Type", "image/jpeg")));

when(solrSearchService.getObjectById(any(SimpleIdRequest.class))).thenReturn(contentObjectSolrRecord);
when(contentObjectSolrRecord.getDatastreamObject("original_file")).thenReturn(originalDatastream);
when(originalDatastream.getExtent()).thenReturn("9999x3333");
when(originalDatastream.getFilename()).thenReturn(filename);
when(contentObjectSolrRecord.getDatastreamObject(DatastreamType.JP2_ACCESS_COPY.getId())).thenReturn(jp2Datastream);
when(jp2Datastream.getExtent()).thenReturn("1200x1300");
when(contentObjectSolrRecord.getPid()).thenReturn(pid);

MvcResult result = mvc.perform(get("/downloadImage/" + pidString + "/1800"))
.andExpect(status().is2xxSuccessful())
.andReturn();

var response = result.getResponse();

assertEquals("attachment; filename=bunny_max.jpg", response.getHeader(CONTENT_DISPOSITION));
assertCorrectImageReturned(response);
}

@Test
public void testGetImageNoViewReducedPermission() throws Exception {
var pid = makePid();
Expand Down Expand Up @@ -282,6 +317,32 @@ public void testGetImageNoJP2() throws Exception {
.andReturn();
}

@Test
public void testGetImageFailToStream() throws Exception {
var pid = makePid();
var pidString = pid.getId();
var formattedPid = ImageServerUtil.getImageServerEncodedId(pidString);
var filename = "bunny.jpg";
ContentObjectSolrRecord contentObjectSolrRecord = mock(ContentObjectSolrRecord.class);
Datastream originalDatastream = mock(Datastream.class);
Datastream jp2Datastream = mock(Datastream.class);

when(solrSearchService.getObjectById(any(SimpleIdRequest.class))).thenReturn(contentObjectSolrRecord);
when(contentObjectSolrRecord.getDatastreamObject(DatastreamType.ORIGINAL_FILE.getId())).thenReturn(originalDatastream);
when(originalDatastream.getFilename()).thenReturn(filename);
when(contentObjectSolrRecord.getDatastreamObject(DatastreamType.JP2_ACCESS_COPY.getId())).thenReturn(jp2Datastream);

when(contentObjectSolrRecord.getPid()).thenReturn(pid);

stubFor(WireMock.get(urlMatching("/" + formattedPid + "/full/max/0/default.jpg"))
.willReturn(aResponse()
.withStatus(HttpStatus.BAD_REQUEST.value())));

MvcResult result = mvc.perform(get("/downloadImage/" + pidString + "/max"))
.andExpect(status().isNotFound())
.andReturn();
}

private void assertCorrectImageReturned(MockHttpServletResponse response) throws IOException {
assertEquals("image/jpeg", response.getContentType());

Expand Down

0 comments on commit b4fd38e

Please sign in to comment.