Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Item's date metadata - do not remove dc.date.issued #669

Merged
merged 4 commits into from
May 30, 2024
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 @@ -8,11 +8,14 @@
package org.dspace.content.clarin;

import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.logging.log4j.Logger;
import org.dspace.content.Bitstream;
import org.dspace.content.Bundle;
Expand All @@ -21,6 +24,7 @@
import org.dspace.content.DSpaceObject;
import org.dspace.content.Item;
import org.dspace.content.MetadataField;
import org.dspace.content.MetadataValue;
import org.dspace.content.dao.clarin.ClarinItemDAO;
import org.dspace.content.service.CollectionService;
import org.dspace.content.service.ItemService;
Expand All @@ -38,6 +42,9 @@
public class ClarinItemServiceImpl implements ClarinItemService {

private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(ClarinItemServiceImpl.class);
private static final String DELIMETER = ",";
private static final String NO_YEAR = "0000";

@Autowired
ClarinItemDAO clarinItemDAO;

Expand Down Expand Up @@ -203,4 +210,63 @@ public void updateItemFilesMetadata(Context context, Bitstream bit) throws SQLEx
}
this.updateItemFilesMetadata(context, item, bundle);
}

@Override
public void updateItemDatesMetadata(Context context, Item item) throws SQLException {
if (Objects.isNull(context)) {
log.error("Cannot update item dates metadata because the context is null.");
return;
}

List<MetadataValue> approximatedDates =
itemService.getMetadata(item, "local", "approximateDate", "issued", Item.ANY, false);

if (CollectionUtils.isEmpty(approximatedDates) || StringUtils.isBlank(approximatedDates.get(0).getValue())) {
log.warn("Cannot update item dates metadata because the approximate date is empty.");
MajoBerger marked this conversation as resolved.
Show resolved Hide resolved
return;
}

// Get the approximate date value from the metadata
String approximateDateValue = approximatedDates.get(0).getValue();

// Split the approximate date value by the delimeter and get the list of years.
List<String> listOfYearValues = Arrays.asList(approximateDateValue.split(DELIMETER));
// Trim the list of years - remove leading and trailing whitespaces
listOfYearValues.replaceAll(String::trim);

try {
// Clear the current `dc.date.issued` metadata
itemService.clearMetadata(context, item, "dc", "date", "issued", Item.ANY);

// Update the `dc.date.issued` metadata with a new value: `0000` or the last year from the sequence
if (CollectionUtils.isNotEmpty(listOfYearValues) && isListOfNumbers(listOfYearValues)) {
// Take the last year from the list of years and add it to the `dc.date.issued` metadata
itemService.addMetadata(context, item, "dc", "date", "issued", Item.ANY,
getLastNumber(listOfYearValues));
} else {
// Add the `0000` value to the `dc.date.issued` metadata
itemService.addMetadata(context, item, "dc", "date", "issued", Item.ANY, NO_YEAR);
}
} catch (SQLException e) {
log.error("Cannot remove `dc.date.issued` metadata because: {}", e.getMessage());
}
}

public static boolean isListOfNumbers(List<String> values) {
for (String value : values) {
if (!NumberUtils.isCreatable(value)) {
return false;
}
}
return true;
}

private static String getLastNumber(List<String> values) {
if (CollectionUtils.isEmpty(values)) {
return NO_YEAR;
}
return values.get(values.size() - 1);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,16 @@ public interface ClarinItemService {
*/
void updateItemFilesMetadata(Context context, Bitstream bit) throws SQLException;

/**
* Update item's metadata about its dates (dc.date.issued, local.approximateDate.issued).
* If the local.approximateDate.issued has any approximate value, e.g. 'cca 1938 - 1945' or 'approx. 1995'
* or similar, use 0000
* If the local.approximateDate.issued has several values, e.g. 1993, 1918, 2021 use the last one:
* `dc.date.issued` = 2021
*
* @param context DSpace context object
* @param item Update metadata for this Item
*/
void updateItemDatesMetadata(Context context, Item item) throws SQLException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@
import org.dspace.content.MetadataField;
import org.dspace.content.MetadataValue;
import org.dspace.content.service.ItemService;
import org.dspace.content.service.clarin.ClarinItemService;
import org.dspace.core.Context;
import org.dspace.discovery.IndexableObject;
import org.dspace.services.model.Request;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
Expand All @@ -44,25 +46,23 @@ public class ItemConverter
@Autowired
private ItemService itemService;

@Autowired
private ClarinItemService clarinItemService;

private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(ItemConverter.class);

@Override
public ItemRest convert(Item obj, Projection projection) {
List<MetadataValue> approximatedDates =
itemService.getMetadata(obj, "local", "approximateDate", "issued", Item.ANY, false);
if (CollectionUtils.isNotEmpty(approximatedDates) &&
StringUtils.isNotBlank(approximatedDates.get(0).getValue())) {
List<MetadataValue> issuedDates =
itemService.getMetadata(obj, "dc", "date", "issued", Item.ANY, false);
issuedDates.forEach(metadataValue -> metadataValue.setValue(approximatedDates.get(0).getValue()));

// Remove the date from the `dc.date.issued` because it was added into `local.approximateDate.issued`.
Context context = ContextUtil.obtainContext(requestService.getCurrentRequest().getHttpServletRequest());
try {
itemService.clearMetadata(context, obj, "dc", "date", "issued", Item.ANY);
} catch (SQLException e) {
log.error("Cannot remove `dc.date.issued` metadata because: " + e.getMessage());
}
Context context = null;
Request currentRequest = requestService.getCurrentRequest();
if (currentRequest != null) {
context = ContextUtil.obtainContext(currentRequest.getHttpServletRequest());
}
try {
clarinItemService.updateItemDatesMetadata(context, obj);
} catch (SQLException e) {
log.error("Error updating item dates metadata", e);
throw new RuntimeException(e);
}

ItemRest item = super.convert(obj, projection);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4698,36 +4698,6 @@ public void findAccessStatusForItemTest() throws Exception {
.andExpect(jsonPath("$.status", notNullValue()));
}

@Test
public void findItemWithUnknownIssuedDate() throws Exception {
context.turnOffAuthorisationSystem();

//** GIVEN **
//1. A community-collection structure with one parent community and one collection
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Collection col = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection").build();

//2. Three public items that are readable by Anonymous with different subjects
Item publicItem = ItemBuilder.createItem(context, col)
.withTitle("Public item")
.withIssueDate("2021-04-27")
.withMetadata("local", "approximateDate", "issued", "unknown")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();

context.restoreAuthSystemState();
Matcher<? super Object> publicItemMatcher = ItemMatcher.matchItemWithTitleAndApproximateDateIssued(publicItem,
"Public item", "unknown");

getClient().perform(get("/api/core/items/" + publicItem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$", HalMatcher.matchNoEmbeds()))
.andExpect(jsonPath("$", publicItemMatcher));
}

@Test
public void submitterShouldSeeLocalNoteMetadata() throws Exception {
// Admin - should see `local.submission.note` and `dc.description.provenance`
Expand Down Expand Up @@ -4837,4 +4807,68 @@ public void searchByHandle() throws Exception {
)));
}

/**
* If the local.approximateDate.issued has a value like 'cca 1938 - 1945', then dc.date.issued = 0000.
*/
@Test
public void copyApproximateDateIntoDateIssued_whenApproximateDateHasMultipleValues() throws Exception {
context.turnOffAuthorisationSystem();
//** GIVEN **
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
.withName("Sub Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();

Item publicItem = ItemBuilder.createItem(context, col1)
.withTitle("Item with dates")
.withIssueDate("2017-10-17")
.withMetadata("local", "approximateDate", "issued", "cca 1938 - 1945")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
context.restoreAuthSystemState();

String adminToken = getAuthToken(admin.getEmail(), password);
getClient(adminToken).perform(get("/api/core/items/" + publicItem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$", HalMatcher.matchNoEmbeds()))
.andExpect(jsonPath("$.metadata", Matchers.allOf(
matchMetadata("dc.date.issued", "0000"))));
}

/**
* If the local.approximateDate.issued has a value like '1938, 1945, 2022', then dc.date.issued = 2022.
*/
@Test
public void copyApproximateDateIntoDateIssued_whenApproximateDateHasRangeOfValues() throws Exception {
context.turnOffAuthorisationSystem();
//** GIVEN **
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
.withName("Sub Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();

Item publicItem = ItemBuilder.createItem(context, col1)
.withTitle("Item with dates")
.withIssueDate("2017-10-17")
.withMetadata("local", "approximateDate", "issued", "1938, 1945, 2022")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
context.restoreAuthSystemState();

String adminToken = getAuthToken(admin.getEmail(), password);
getClient(adminToken).perform(get("/api/core/items/" + publicItem.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$", HalMatcher.matchNoEmbeds()))
.andExpect(jsonPath("$.metadata", Matchers.allOf(
matchMetadata("dc.date.issued", "2022"))));
}

}
Loading