Skip to content

Commit

Permalink
Update Item's date metadata - do not remove dc.date.issued (#669)
Browse files Browse the repository at this point in the history
* Created method which updates properly the Item's date metadata.

* Fixed checkstyle issues

* The servlet request could be null.

* Update the comment to make description more clear.
  • Loading branch information
milanmajchrak authored May 30, 2024
1 parent 573e3cc commit f2a606c
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 45 deletions.
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.");
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"))));
}

}

0 comments on commit f2a606c

Please sign in to comment.