Skip to content

Commit

Permalink
119634: Add configuration to control copying of relation.* virtual me…
Browse files Browse the repository at this point in the history
…tadata upon relationship deletion
  • Loading branch information
Zahraa Chreim committed Oct 23, 2024
1 parent 4cdb662 commit e928bb5
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,11 @@ private boolean containsVirtualMetadata(String typeToSearchInVirtualMetadata) {
private void copyMetadataValues(Context context, Relationship relationship, boolean copyToLeftItem,
boolean copyToRightItem)
throws SQLException, AuthorizeException {

// Fetch configuration: should we copy relation.* metadata or not?
boolean copyRelationMetadata =
configurationService.getBooleanProperty("relation.metadata.copy.on.delete", true);

if (copyToLeftItem) {
String entityTypeString = itemService.getEntityTypeLabel(relationship.getLeftItem());
List<RelationshipMetadataValue> relationshipMetadataValues =
Expand All @@ -878,14 +883,19 @@ private void copyMetadataValues(Context context, Relationship relationship, bool
// relationship values which are not useForPlace, while the relationhip type has useForPlace
// E.g. when using addAndShiftRightMetadata on relation.isAuthorOfPublication, it will break the order
// from dc.contributor.author
itemService.addMetadata(context, relationship.getLeftItem(),
relationshipMetadataValue.getMetadataField().
getMetadataSchema().getName(),
relationshipMetadataValue.getMetadataField().getElement(),
relationshipMetadataValue.getMetadataField().getQualifier(),
relationshipMetadataValue.getLanguage(),
relationshipMetadataValue.getValue(), null, -1,
relationshipMetadataValue.getPlace());

MetadataField metadataField = relationshipMetadataValue.getMetadataField();
// Only add metadata if it's not relation.* or if copying relation.* metadata is allowed
if (copyRelationMetadata || !"relation".equals(metadataField.getMetadataSchema().getName())) {
itemService.addMetadata(context, relationship.getLeftItem(),
relationshipMetadataValue.getMetadataField().
getMetadataSchema().getName(),
relationshipMetadataValue.getMetadataField().getElement(),
relationshipMetadataValue.getMetadataField().getQualifier(),
relationshipMetadataValue.getLanguage(),
relationshipMetadataValue.getValue(), null, -1,
relationshipMetadataValue.getPlace());
}
}
//This will ensure the new values no longer overlap, but won't break the order
itemService.update(context, relationship.getLeftItem());
Expand All @@ -896,14 +906,19 @@ private void copyMetadataValues(Context context, Relationship relationship, bool
relationshipMetadataService.findRelationshipMetadataValueForItemRelationship(context,
relationship.getRightItem(), entityTypeString, relationship, true);
for (RelationshipMetadataValue relationshipMetadataValue : relationshipMetadataValues) {
itemService.addMetadata(context, relationship.getRightItem(),
relationshipMetadataValue.getMetadataField().
getMetadataSchema().getName(),
relationshipMetadataValue.getMetadataField().getElement(),
relationshipMetadataValue.getMetadataField().getQualifier(),
relationshipMetadataValue.getLanguage(),
relationshipMetadataValue.getValue(), null, -1,
relationshipMetadataValue.getPlace());

MetadataField metadataField = relationshipMetadataValue.getMetadataField();
// Only add metadata if it's not relation.* or if copying relation.* metadata is allowed
if (copyRelationMetadata || !"relation".equals(metadataField.getMetadataSchema().getName())) {
itemService.addMetadata(context, relationship.getRightItem(),
relationshipMetadataValue.getMetadataField().
getMetadataSchema().getName(),
relationshipMetadataValue.getMetadataField().getElement(),
relationshipMetadataValue.getMetadataField().getQualifier(),
relationshipMetadataValue.getLanguage(),
relationshipMetadataValue.getValue(), null, -1,
relationshipMetadataValue.getPlace());
}
}
itemService.update(context, relationship.getRightItem());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.content;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;

import java.util.List;

import org.dspace.AbstractIntegrationTestWithDatabase;
import org.dspace.builder.CollectionBuilder;
import org.dspace.builder.CommunityBuilder;
import org.dspace.builder.EntityTypeBuilder;
import org.dspace.builder.ItemBuilder;
import org.dspace.builder.RelationshipBuilder;
import org.dspace.builder.RelationshipTypeBuilder;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.ItemService;
import org.dspace.content.service.RelationshipService;
import org.dspace.services.ConfigurationService;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.junit.Before;
import org.junit.Test;

public class RelationshipServiceImplMetadataCopyTest extends AbstractIntegrationTestWithDatabase {

private ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
private RelationshipService relationshipService = ContentServiceFactory.getInstance().getRelationshipService();
private ItemService itemService = ContentServiceFactory.getInstance().getItemService();

private Item leftItem;
private Item rightItem;

private Relationship leftRightRelationship;

@Before
public void setUp() throws Exception {
super.setUp();

context.turnOffAuthorisationSystem();

Community community = CommunityBuilder.createCommunity(context).build();

Collection journalVolumeCollection = CollectionBuilder.createCollection(context, community)
.withEntityType("JournalVolume")
.build();
Collection journalIssueCollection = CollectionBuilder.createCollection(context, community)
.withEntityType("JournalIssue")
.build();

EntityType journalVolumeType = EntityTypeBuilder.createEntityTypeBuilder(context, "JournalVolume").build();
EntityType journalIssueType = EntityTypeBuilder.createEntityTypeBuilder(context, "JournalIssue").build();

RelationshipType issueJournalVolumeType =
RelationshipTypeBuilder
.createRelationshipTypeBuilder(context, journalIssueType, journalVolumeType,
"isJournalVolumeOfIssue", "isIssueOfJournalVolume",
null, null, null, null).build();

leftItem = ItemBuilder.createItem(context, journalIssueCollection)
.withPublicationIssueNumber("2").build();
rightItem = ItemBuilder.createItem(context, journalVolumeCollection)
.withPublicationVolumeNumber("30").build();

leftRightRelationship =
RelationshipBuilder.createRelationshipBuilder(context, leftItem, rightItem, issueJournalVolumeType).build();

context.restoreAuthSystemState();
}

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

// Set the configuration to disable relation metadata copying
configurationService.setProperty("relation.metadata.copy.on.delete", "false");

// Assert the relationship exists before removal
List<Relationship> relationships = relationshipService.findByItem(context, leftItem);
assertEquals(1, relationships.size());

// Verify the left item's relation.isJournalVolumeOfIssue metadata before removal
List<MetadataValue> volumeList =
itemService.getMetadata(leftItem, "relation", "isJournalVolumeOfIssue", null, Item.ANY);
assertThat(volumeList.get(0).getValue(), equalTo(rightItem.getID().toString()));

// Verify the right item's relation.isIssueOfJournalVolume metadata before removal
List<MetadataValue> issueList =
itemService.getMetadata(rightItem, "relation", "isIssueOfJournalVolume", null, Item.ANY);
assertThat(issueList.get(0).getValue(), equalTo(leftItem.getID().toString()));

// Remove the relationship
relationshipService.delete(context, leftRightRelationship);

// Assert the relationship is removed
relationships = relationshipService.findByItem(context, leftItem);
assertEquals(0, relationships.size());

// Verify the left item's relation.isJournalVolumeOfIssue metadata should NOT be copied
volumeList = itemService.getMetadata(leftItem, "relation", "isJournalVolumeOfIssue", null, Item.ANY);
assertThat(volumeList.size(), equalTo(0)); // Expect no metadata from rightItem

// Verify the right item's relation.isIssueOfJournalVolume metadata should NOT be copied
issueList = itemService.getMetadata(rightItem, "relation", "isIssueOfJournalVolume", null, Item.ANY);
assertThat(issueList.size(), equalTo(0)); // Expect no metadata from leftItem

context.restoreAuthSystemState();
}

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

// Set the configuration to disable relation metadata copying
configurationService.setProperty("relation.metadata.copy.on.delete", "true");

// Assert the relationship exists before removal
List<Relationship> relationships = relationshipService.findByItem(context, leftItem);
assertEquals(1, relationships.size());

// Verify the left item's relation.isJournalVolumeOfIssue metadata before removal
List<MetadataValue> volumeList =
itemService.getMetadata(leftItem, "relation", "isJournalVolumeOfIssue", null, Item.ANY);
assertThat(volumeList.get(0).getValue(), equalTo(rightItem.getID().toString()));

// Verify the right item's relation.isIssueOfJournalVolume metadata before removal
List<MetadataValue> issueList =
itemService.getMetadata(rightItem, "relation", "isIssueOfJournalVolume", null, Item.ANY);
assertThat(issueList.get(0).getValue(), equalTo(leftItem.getID().toString()));

// Remove the relationship
relationshipService.delete(context, leftRightRelationship);

// Assert the relationship is removed
relationships = relationshipService.findByItem(context, leftItem);
assertEquals(0, relationships.size());

// Verify the left item's relation.isJournalVolumeOfIssue metadata copied after removal
volumeList = itemService.getMetadata(leftItem, "relation", "isJournalVolumeOfIssue", null, Item.ANY);
assertThat(volumeList.size(), equalTo(0));

// Verify the right item's relation.isIssueOfJournalVolume metadata copied after removal
issueList = itemService.getMetadata(rightItem, "relation", "isIssueOfJournalVolume", null, Item.ANY);
assertThat(issueList.size(), equalTo(0));

context.restoreAuthSystemState();
}
}
4 changes: 4 additions & 0 deletions dspace/config/dspace.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -1671,3 +1671,7 @@ include = ${module_dir}/usage-statistics.cfg
include = ${module_dir}/versioning.cfg
include = ${module_dir}/workflow.cfg
include = ${module_dir}/external-providers.cfg

# Controls whether relation.* virtual metadata should be copied when deleting a relationship
# Default is true, meaning relation.* metadata will be copied
relation.metadata.copy.on.delete = true

0 comments on commit e928bb5

Please sign in to comment.