Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.sql.SQLException;
import java.util.Date;

import org.dspace.content.Bitstream;
import org.dspace.content.Item;
import org.dspace.core.Context;

Expand Down Expand Up @@ -39,4 +40,27 @@ public String getAccessStatusFromItem(Context context, Item item, Date threshold
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
public String getEmbargoFromItem(Context context, Item item, Date threshold) throws SQLException;

/**
* Calculate the access status for the bitstream.
*
* @param context the DSpace context
* @param bitstream the bitstream
* @param threshold the embargo threshold date
* @return an access status value
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
public String getAccessStatusFromBitstream(Context context, Bitstream bitstream, Date threshold)
throws SQLException;

/**
* Retrieve embargo information for the bitstream
*
* @param context the DSpace context
* @param bitstream the bitstream to check for embargo information
* @param threshold the embargo threshold date
* @return an embargo date
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
public String getEmbargoFromBitstream(Context context, Bitstream bitstream, Date threshold) throws SQLException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.Date;

import org.dspace.access.status.service.AccessStatusService;
import org.dspace.content.Bitstream;
import org.dspace.content.Item;
import org.dspace.core.Context;
import org.dspace.core.service.PluginService;
Expand Down Expand Up @@ -68,4 +69,14 @@ public String getAccessStatus(Context context, Item item) throws SQLException {
public String getEmbargoFromItem(Context context, Item item) throws SQLException {
return helper.getEmbargoFromItem(context, item, forever_date);
}

@Override
public String getAccessStatus(Context context, Bitstream bitstream) throws SQLException {
return helper.getAccessStatusFromBitstream(context, bitstream, forever_date);
}

@Override
public String getEmbargoFromBitstream(Context context, Bitstream bitstream) throws SQLException {
return helper.getEmbargoFromBitstream(context, bitstream, forever_date);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package org.dspace.access.status;

import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -47,6 +48,11 @@ public class DefaultAccessStatusHelper implements AccessStatusHelper {
public static final String RESTRICTED = "restricted";
public static final String UNKNOWN = "unknown";

// REST date fields use a plain ISO calendar date (e.g. "2050-01-01"), matching the format used
// elsewhere in the REST API (see ResourcePolicyRest). Date#toString() is locale/timezone-dependent
// and must not be used for values exposed over REST.
private static final String REST_DATE_FORMAT = "yyyy-MM-dd";

protected ItemService itemService =
ContentServiceFactory.getInstance().getItemService();
protected ResourcePolicyService resourcePolicyService =
Expand All @@ -59,7 +65,7 @@ public DefaultAccessStatusHelper() {
}

/**
* Look at the item's policies to determine an access status value.
* Look at the item policies to determine an access status value.
* It is also considering a date threshold for embargoes and restrictions.
*
* If the item is null, simply returns the "unknown" value.
Expand Down Expand Up @@ -96,7 +102,7 @@ public String getAccessStatusFromItem(Context context, Item item, Date threshold
}

/**
* Look at the DSpace object's policies to determine an access status value.
* Look at the DSpace object policies to determine an access status value.
*
* If the object is null, returns the "metadata.only" value.
* If any policy attached to the object is valid for the anonymous group,
Expand Down Expand Up @@ -170,7 +176,8 @@ private String calculateAccessStatusForDso(Context context, DSpaceObject dso, Da
*
* @param context the DSpace context
* @param item the item to embargo
* @return an access status value
* @param threshold the embargo threshold date
* @return an embargo date
*/
@Override
public String getEmbargoFromItem(Context context, Item item, Date threshold)
Expand Down Expand Up @@ -207,11 +214,73 @@ public String getEmbargoFromItem(Context context, Item item, Date threshold)

embargoDate = this.retrieveShortestEmbargo(context, bitstream);

return embargoDate != null ? embargoDate.toString() : null;
return formatEmbargoDate(embargoDate);
}

/**
* Look at the policies attached directly to the bitstream to determine an access status value.
* It is also considering a date threshold for embargoes and restrictions.
*
* If the bitstream is null, simply returns the "unknown" value.
*
* @param context the DSpace context
* @param bitstream the bitstream to check for embargoes
* @param threshold the embargo threshold date
* @return an access status value
*/
@Override
public String getAccessStatusFromBitstream(Context context, Bitstream bitstream, Date threshold)
throws SQLException {
if (bitstream == null) {
return UNKNOWN;
}
return calculateAccessStatusForDso(context, bitstream, threshold);
}

/**
* Look at the policies of the bitstream to retrieve its embargo.
*
* If the bitstream is null, simply returns no embargo date.
*
* @param context the DSpace context
* @param bitstream the bitstream to embargo
* @param threshold the embargo threshold date
* @return an embargo date
*/
@Override
public String getEmbargoFromBitstream(Context context, Bitstream bitstream, Date threshold)
throws SQLException {
if (bitstream == null) {
return null;
}
// If Bitstream status is not "embargo" then return a null embargo date.
String accessStatus = getAccessStatusFromBitstream(context, bitstream, threshold);
if (!accessStatus.equals(EMBARGO)) {
return null;
}
Date embargoDate = this.retrieveShortestEmbargo(context, bitstream);

return formatEmbargoDate(embargoDate);
}

/**
* Format an embargo date for REST exposure as a plain ISO calendar date (yyyy-MM-dd),
* matching the format used elsewhere in the REST API. SimpleDateFormat is not thread-safe,
* so a new instance is created per call.
*
* @param date the date to format, may be null
* @return the formatted date, or null if the given date is null
*/
private String formatEmbargoDate(Date date) {
return date != null ? new SimpleDateFormat(REST_DATE_FORMAT).format(date) : null;
}

/**
* Look at the read policies of a bitstream to retrieve the shortest active embargo date.
*
* @param context the DSpace context
* @param bitstream the bitstream
* @return the shortest embargo date, or null if there is none
*/
private Date retrieveShortestEmbargo(Context context, Bitstream bitstream) throws SQLException {
Date embargoDate = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import java.sql.SQLException;

import org.dspace.content.Bitstream;
import org.dspace.content.Item;
import org.dspace.core.Context;

Expand Down Expand Up @@ -54,4 +55,24 @@ public interface AccessStatusService {
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
public String getEmbargoFromItem(Context context, Item item) throws SQLException;

/**
* Calculate the access status for a Bitstream while considering the forever embargo date threshold.
*
* @param context the DSpace context
* @param bitstream the bitstream
* @return an access status value
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
public String getAccessStatus(Context context, Bitstream bitstream) throws SQLException;

/**
* Retrieve embargo information for the bitstream
*
* @param context the DSpace context
* @param bitstream the bitstream to check for embargo information
* @return an embargo date
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
public String getEmbargoFromBitstream(Context context, Bitstream bitstream) throws SQLException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,33 @@
package org.dspace.access.status;

import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.sql.SQLException;

import org.apache.logging.log4j.Logger;
import org.dspace.AbstractUnitTest;
import org.dspace.access.status.factory.AccessStatusServiceFactory;
import org.dspace.access.status.service.AccessStatusService;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Bitstream;
import org.dspace.content.Bundle;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.Item;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.BitstreamService;
import org.dspace.content.service.BundleService;
import org.dspace.content.service.CollectionService;
import org.dspace.content.service.CommunityService;
import org.dspace.content.service.InstallItemService;
import org.dspace.content.service.ItemService;
import org.dspace.content.service.WorkspaceItemService;
import org.dspace.core.Constants;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -40,13 +49,19 @@ public class AccessStatusServiceTest extends AbstractUnitTest {
private Collection collection;
private Community owningCommunity;
private Item item;
private Bundle bundle;
private Bitstream bitstream;

protected CommunityService communityService =
ContentServiceFactory.getInstance().getCommunityService();
protected CollectionService collectionService =
ContentServiceFactory.getInstance().getCollectionService();
protected ItemService itemService =
ContentServiceFactory.getInstance().getItemService();
protected BundleService bundleService =
ContentServiceFactory.getInstance().getBundleService();
protected BitstreamService bitstreamService =
ContentServiceFactory.getInstance().getBitstreamService();
protected WorkspaceItemService workspaceItemService =
ContentServiceFactory.getInstance().getWorkspaceItemService();
protected InstallItemService installItemService =
Expand All @@ -71,13 +86,20 @@ public void init() {
collection = collectionService.create(context, owningCommunity);
item = installItemService.installItem(context,
workspaceItemService.create(context, collection, true));
bundle = bundleService.create(context, item, Constants.CONTENT_BUNDLE_NAME);
bitstream = bitstreamService.create(context, bundle,
new ByteArrayInputStream("1".getBytes(StandardCharsets.UTF_8)));
bitstream.setName(context, "primary");
context.restoreAuthSystemState();
} catch (AuthorizeException ex) {
log.error("Authorization Error in init", ex);
fail("Authorization Error in init: " + ex.getMessage());
} catch (SQLException ex) {
log.error("SQL Error in init", ex);
fail("SQL Error in init: " + ex.getMessage());
} catch (IOException ex) {
log.error("IO Error in init", ex);
fail("IO Error in init: " + ex.getMessage());
}
}

Expand All @@ -92,6 +114,16 @@ public void init() {
@Override
public void destroy() {
context.turnOffAuthorisationSystem();
try {
bitstreamService.delete(context, bitstream);
} catch (Exception e) {
// ignore
}
try {
bundleService.delete(context, bundle);
} catch (Exception e) {
// ignore
}
try {
itemService.delete(context, item);
} catch (Exception e) {
Expand All @@ -108,6 +140,8 @@ public void destroy() {
// ignore
}
context.restoreAuthSystemState();
bitstream = null;
bundle = null;
item = null;
collection = null;
owningCommunity = null;
Expand All @@ -123,4 +157,22 @@ public void testGetAccessStatus() throws Exception {
String status = accessStatusService.getAccessStatus(context, item);
assertNotEquals("testGetAccessStatus 0", status, DefaultAccessStatusHelper.UNKNOWN);
}

@Test
public void testGetEmbargoFromItem() throws Exception {
String embargo = accessStatusService.getEmbargoFromItem(context, item);
assertNull("testGetEmbargoFromItem 0", embargo);
}

@Test
public void testGetAccessStatusFromBitstream() throws Exception {
String status = accessStatusService.getAccessStatus(context, bitstream);
assertNotEquals("testGetAccessStatusFromBitstream 0", status, DefaultAccessStatusHelper.UNKNOWN);
}

@Test
public void testGetEmbargoFromBitstream() throws Exception {
String embargo = accessStatusService.getEmbargoFromBitstream(context, bitstream);
assertNull("testGetEmbargoFromBitstream 0", embargo);
}
}
Loading
Loading