diff --git a/dspace-api/src/main/java/org/dspace/content/RelationshipServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/RelationshipServiceImpl.java index da14e8cfeb..755062f646 100644 --- a/dspace-api/src/main/java/org/dspace/content/RelationshipServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/RelationshipServiceImpl.java @@ -33,6 +33,7 @@ import org.dspace.content.virtual.VirtualMetadataPopulator; import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.services.ConfigurationService; +import org.dspace.versioning.utils.RelationshipVersioningUtils; import org.springframework.beans.factory.annotation.Autowired; public class RelationshipServiceImpl implements RelationshipService { @@ -59,6 +60,10 @@ public class RelationshipServiceImpl implements RelationshipService { @Autowired private RelationshipMetadataService relationshipMetadataService; + + @Autowired + private RelationshipVersioningUtils relationshipVersioningUtils; + @Autowired private VirtualMetadataPopulator virtualMetadataPopulator; @@ -264,13 +269,13 @@ public class RelationshipServiceImpl implements RelationshipService { context.turnOffAuthorisationSystem(); //only shift if the place is relevant for the latest relationships - if (otherSideIsLatest(true, relationship.getLatestVersionStatus())) { + if (relationshipVersioningUtils.otherSideIsLatest(true, relationship.getLatestVersionStatus())) { shiftSiblings( relationship, true, oldLeftPlace, movedUpLeft, insertLeft, deletedFromLeft, leftRelationships, leftMetadata ); } - if (otherSideIsLatest(false, relationship.getLatestVersionStatus())) { + if (relationshipVersioningUtils.otherSideIsLatest(false, relationship.getLatestVersionStatus())) { shiftSiblings( relationship, false, oldRightPlace, movedUpRight, insertRight, deletedFromRight, rightRelationships, rightMetadata @@ -483,22 +488,6 @@ public class RelationshipServiceImpl implements RelationshipService { } } - /** - * Given a latest version status, check if the other side is "latest". - * If we look from the left, this implies BOTH and RIGHT_ONLY return true. - * If we look from the right, this implies BOTH and LEFT_ONLY return true. - * @param isLeft whether we should look from the left or right side. - * @param latestVersionStatus the latest version status. - * @return true if the other side has "latest" status, false otherwise. - */ - private boolean otherSideIsLatest(boolean isLeft, LatestVersionStatus latestVersionStatus) { - if (latestVersionStatus == LatestVersionStatus.BOTH) { - return true; - } - - return latestVersionStatus == (isLeft ? LatestVersionStatus.RIGHT_ONLY : LatestVersionStatus.LEFT_ONLY); - } - private int getPlace(Relationship relationship, boolean isLeft) { if (isLeft) { return relationship.getLeftPlace(); diff --git a/dspace-api/src/main/java/org/dspace/versioning/VersioningConsumer.java b/dspace-api/src/main/java/org/dspace/versioning/VersioningConsumer.java index b186daad8a..db28accdf3 100644 --- a/dspace-api/src/main/java/org/dspace/versioning/VersioningConsumer.java +++ b/dspace-api/src/main/java/org/dspace/versioning/VersioningConsumer.java @@ -34,6 +34,7 @@ import org.dspace.event.Consumer; import org.dspace.event.Event; import org.dspace.versioning.factory.VersionServiceFactory; import org.dspace.versioning.service.VersionHistoryService; +import org.dspace.versioning.utils.RelationshipVersioningUtils; /** * When a new version of an item is published, unarchive the previous version and @@ -54,6 +55,7 @@ public class VersioningConsumer implements Consumer { private EntityTypeService entityTypeService; private RelationshipTypeService relationshipTypeService; private RelationshipService relationshipService; + private RelationshipVersioningUtils relationshipVersioningUtils; @Override public void initialize() throws Exception { @@ -62,6 +64,7 @@ public class VersioningConsumer implements Consumer { entityTypeService = ContentServiceFactory.getInstance().getEntityTypeService(); relationshipTypeService = ContentServiceFactory.getInstance().getRelationshipTypeService(); relationshipService = ContentServiceFactory.getInstance().getRelationshipService(); + relationshipVersioningUtils = VersionServiceFactory.getInstance().getRelationshipVersioningUtils(); } @Override @@ -227,14 +230,14 @@ public class VersioningConsumer implements Consumer { // of the item will not be shown anymore on the page of the third-party item. That makes sense, // because either the relationship has been deleted from the new version of the item (no match), // or the matching relationship (linked to new version) will receive "latest" status in the next step. - updateLatestVersionStatus(previousItemRelationship, isLeft, false); + relationshipVersioningUtils.updateLatestVersionStatus(previousItemRelationship, isLeft, false); // Set the new version of the item to latest if the relevant relationship exists (match found). // This implies that the new version of the item will appear on the page of the third-party item. // The old version of the item will not appear anymore on the page of the third-party item, // see previous step. if (latestItemRelationship != null) { - updateLatestVersionStatus(latestItemRelationship, isLeft, true); + relationshipVersioningUtils.updateLatestVersionStatus(latestItemRelationship, isLeft, true); } } } @@ -450,65 +453,6 @@ public class VersioningConsumer implements Consumer { return matchingRelationships.get(0); } - /** - * Update {@link Relationship#latestVersionStatus} of the given relationship. - * @param relationship the relationship. - * @param updateLeftSide whether the status of the left item or the right item should be updated. - * @param isLatest to what the status should be set. - * @throws IllegalStateException if the operation would result in both the left side and the right side - * being set to non-latest. - */ - protected void updateLatestVersionStatus( - Relationship relationship, boolean updateLeftSide, boolean isLatest - ) throws IllegalStateException { - LatestVersionStatus lvs = relationship.getLatestVersionStatus(); - - boolean leftSideIsLatest = lvs == LatestVersionStatus.BOTH || lvs == LatestVersionStatus.LEFT_ONLY; - boolean rightSideIsLatest = lvs == LatestVersionStatus.BOTH || lvs == LatestVersionStatus.RIGHT_ONLY; - - if (updateLeftSide) { - if (leftSideIsLatest == isLatest) { - return; // no change needed - } - leftSideIsLatest = isLatest; - } else { - if (rightSideIsLatest == isLatest) { - return; // no change needed - } - rightSideIsLatest = isLatest; - } - - LatestVersionStatus newVersionStatus; - if (leftSideIsLatest && rightSideIsLatest) { - newVersionStatus = LatestVersionStatus.BOTH; - } else if (leftSideIsLatest) { - newVersionStatus = LatestVersionStatus.LEFT_ONLY; - } else if (rightSideIsLatest) { - newVersionStatus = LatestVersionStatus.RIGHT_ONLY; - } else { - String msg = String.format( - "Illegal state: cannot set %s item to latest = false, because relationship with id %s, " + - "rightward name %s between left item with uuid %s, handle %s and right item with uuid %s, handle %s " + - "has latest version status set to %s", - updateLeftSide ? "left" : "right", relationship.getID(), - relationship.getRelationshipType().getRightwardType(), - relationship.getLeftItem().getID(), relationship.getLeftItem().getHandle(), - relationship.getRightItem().getID(), relationship.getRightItem().getHandle(), lvs - ); - log.error(msg); - throw new IllegalStateException(msg); - } - - log.info(String.format( - "set latest version status from %s to %s for relationship with id %s, rightward name %s " + - "between left item with uuid %s, handle %s and right item with uuid %s, handle %s", - lvs, newVersionStatus, relationship.getID(), relationship.getRelationshipType().getRightwardType(), - relationship.getLeftItem().getID(), relationship.getLeftItem().getHandle(), - relationship.getRightItem().getID(), relationship.getRightItem().getHandle() - )); - relationship.setLatestVersionStatus(newVersionStatus); - } - @Override public void end(Context ctx) throws Exception { if (itemsToProcess != null) { diff --git a/dspace-api/src/main/java/org/dspace/versioning/factory/VersionServiceFactory.java b/dspace-api/src/main/java/org/dspace/versioning/factory/VersionServiceFactory.java index ecc3315a72..8e8cc786ca 100644 --- a/dspace-api/src/main/java/org/dspace/versioning/factory/VersionServiceFactory.java +++ b/dspace-api/src/main/java/org/dspace/versioning/factory/VersionServiceFactory.java @@ -10,6 +10,7 @@ package org.dspace.versioning.factory; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.versioning.service.VersionHistoryService; import org.dspace.versioning.service.VersioningService; +import org.dspace.versioning.utils.RelationshipVersioningUtils; /** * Abstract factory to get services for the versioning package, use VersionServiceFactory.getInstance() to retrieve @@ -23,6 +24,8 @@ public abstract class VersionServiceFactory { public abstract VersioningService getVersionService(); + public abstract RelationshipVersioningUtils getRelationshipVersioningUtils(); + public static VersionServiceFactory getInstance() { return DSpaceServicesFactory.getInstance().getServiceManager() .getServiceByName("versionServiceFactory", VersionServiceFactory.class); diff --git a/dspace-api/src/main/java/org/dspace/versioning/factory/VersionServiceFactoryImpl.java b/dspace-api/src/main/java/org/dspace/versioning/factory/VersionServiceFactoryImpl.java index 613cb4faf4..97e4083426 100644 --- a/dspace-api/src/main/java/org/dspace/versioning/factory/VersionServiceFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/versioning/factory/VersionServiceFactoryImpl.java @@ -9,6 +9,7 @@ package org.dspace.versioning.factory; import org.dspace.versioning.service.VersionHistoryService; import org.dspace.versioning.service.VersioningService; +import org.dspace.versioning.utils.RelationshipVersioningUtils; import org.springframework.beans.factory.annotation.Autowired; /** @@ -25,6 +26,9 @@ public class VersionServiceFactoryImpl extends VersionServiceFactory { @Autowired(required = true) protected VersioningService versionService; + @Autowired(required = true) + protected RelationshipVersioningUtils relationshipVersioningUtils; + @Override public VersionHistoryService getVersionHistoryService() { return versionHistoryService; @@ -34,4 +38,10 @@ public class VersionServiceFactoryImpl extends VersionServiceFactory { public VersioningService getVersionService() { return versionService; } + + @Override + public RelationshipVersioningUtils getRelationshipVersioningUtils() { + return relationshipVersioningUtils; + } + } diff --git a/dspace-api/src/main/java/org/dspace/versioning/utils/RelationshipVersioningUtils.java b/dspace-api/src/main/java/org/dspace/versioning/utils/RelationshipVersioningUtils.java new file mode 100644 index 0000000000..92bcaa5152 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/versioning/utils/RelationshipVersioningUtils.java @@ -0,0 +1,87 @@ +package org.dspace.versioning.utils; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.dspace.content.Relationship; +import org.dspace.content.Relationship.LatestVersionStatus; + +public class RelationshipVersioningUtils { + + private static final Logger log = LogManager.getLogger(RelationshipVersioningUtils.class); + + /** + * Given a latest version status, check if the other side is "latest". + * If we look from the left, this implies BOTH and RIGHT_ONLY return true. + * If we look from the right, this implies BOTH and LEFT_ONLY return true. + * @param isLeft whether we should look from the left or right side. + * @param latestVersionStatus the latest version status. + * @return true if the other side has "latest" status, false otherwise. + */ + public boolean otherSideIsLatest(boolean isLeft, LatestVersionStatus latestVersionStatus) { + if (latestVersionStatus == LatestVersionStatus.BOTH) { + return true; + } + + return latestVersionStatus == (isLeft ? LatestVersionStatus.RIGHT_ONLY : LatestVersionStatus.LEFT_ONLY); + } + + /** + * Update {@link Relationship#latestVersionStatus} of the given relationship. + * @param relationship the relationship. + * @param updateLeftSide whether the status of the left item or the right item should be updated. + * @param isLatest to what the status should be set. + * @throws IllegalStateException if the operation would result in both the left side and the right side + * being set to non-latest. + */ + public void updateLatestVersionStatus( + Relationship relationship, boolean updateLeftSide, boolean isLatest + ) throws IllegalStateException { + LatestVersionStatus lvs = relationship.getLatestVersionStatus(); + + boolean leftSideIsLatest = lvs == LatestVersionStatus.BOTH || lvs == LatestVersionStatus.LEFT_ONLY; + boolean rightSideIsLatest = lvs == LatestVersionStatus.BOTH || lvs == LatestVersionStatus.RIGHT_ONLY; + + if (updateLeftSide) { + if (leftSideIsLatest == isLatest) { + return; // no change needed + } + leftSideIsLatest = isLatest; + } else { + if (rightSideIsLatest == isLatest) { + return; // no change needed + } + rightSideIsLatest = isLatest; + } + + LatestVersionStatus newVersionStatus; + if (leftSideIsLatest && rightSideIsLatest) { + newVersionStatus = LatestVersionStatus.BOTH; + } else if (leftSideIsLatest) { + newVersionStatus = LatestVersionStatus.LEFT_ONLY; + } else if (rightSideIsLatest) { + newVersionStatus = LatestVersionStatus.RIGHT_ONLY; + } else { + String msg = String.format( + "Illegal state: cannot set %s item to latest = false, because relationship with id %s, " + + "rightward name %s between left item with uuid %s, handle %s and right item with uuid %s, handle %s " + + "has latest version status set to %s", + updateLeftSide ? "left" : "right", relationship.getID(), + relationship.getRelationshipType().getRightwardType(), + relationship.getLeftItem().getID(), relationship.getLeftItem().getHandle(), + relationship.getRightItem().getID(), relationship.getRightItem().getHandle(), lvs + ); + log.error(msg); + throw new IllegalStateException(msg); + } + + log.info(String.format( + "set latest version status from %s to %s for relationship with id %s, rightward name %s " + + "between left item with uuid %s, handle %s and right item with uuid %s, handle %s", + lvs, newVersionStatus, relationship.getID(), relationship.getRelationshipType().getRightwardType(), + relationship.getLeftItem().getID(), relationship.getLeftItem().getHandle(), + relationship.getRightItem().getID(), relationship.getRightItem().getHandle() + )); + relationship.setLatestVersionStatus(newVersionStatus); + } + +} diff --git a/dspace/config/spring/api/versioning-service.xml b/dspace/config/spring/api/versioning-service.xml index ac80c15bed..69dacbcbe0 100644 --- a/dspace/config/spring/api/versioning-service.xml +++ b/dspace/config/spring/api/versioning-service.xml @@ -30,4 +30,6 @@ + +