From a5164d33bb513ecf7ad492deed2468a344689ded Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Tue, 6 Dec 2022 12:17:10 +0100 Subject: [PATCH 01/20] orcid preferences based on hidden/selected relations for the orcid profiles owner with OrcidEntitySyncPreference MINE and MY_SELECTED for some entity an additional check was added. The check uses the solr-search to determine, if the corresponding/linked item is among the hidden/preferred items of the orcid profile owner. The solr query for the relation can be configured. --- .../org/dspace/content/ItemServiceImpl.java | 4 +- .../orcid/consumer/OrcidQueueConsumer.java | 6 +-- .../service/OrcidSynchronizationService.java | 2 +- .../service/impl/OrcidQueueServiceImpl.java | 52 ++++++++++++++++--- .../impl/OrcidSynchronizationServiceImpl.java | 37 ++++++++++--- dspace/config/modules/orcid.cfg | 9 ++++ 6 files changed, 89 insertions(+), 21 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java index 40eca6cfc279..6b82da06fa13 100644 --- a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java @@ -1341,7 +1341,7 @@ private boolean shouldBeAppended(Context context, DSpaceObject dso, ResourcePoli * @throws AuthorizeException if authorization error Exception indicating the * current user of the context does not have * permission - * + * */ @Override public Iterator findArchivedByMetadataField(Context context, @@ -1874,7 +1874,7 @@ private void createOrcidQueueRecordsToDeleteOnOrcid(Context context, Item entity Map profileAndPutCodeMap = orcidHistoryService.findLastPutCodes(context, entity); for (Item profile : profileAndPutCodeMap.keySet()) { - if (orcidSynchronizationService.isSynchronizationAllowed(profile, entity)) { + if (orcidSynchronizationService.isSynchronizationAllowed(context, profile, entity)) { String putCode = profileAndPutCodeMap.get(profile); String title = getMetadataFirstValue(entity, "dc", "title", null, Item.ANY); orcidQueueService.createEntityDeletionRecord(context, profile, title, entityType, putCode); diff --git a/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java b/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java index 518d41432b70..b07e51173477 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java +++ b/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java @@ -158,7 +158,7 @@ private void consumeEntity(Context context, Item entity) throws SQLException { continue; } - if (shouldNotBeSynchronized(owner, entity) || isAlreadyQueued(context, owner, entity)) { + if (shouldNotBeSynchronized(context, owner, entity) || isAlreadyQueued(context, owner, entity)) { continue; } @@ -289,8 +289,8 @@ private boolean hasNotOrcidAccessToken(Context context, Item profileItemItem) { return orcidTokenService.findByProfileItem(context, profileItemItem) == null; } - private boolean shouldNotBeSynchronized(Item profileItem, Item entity) { - return !orcidSynchronizationService.isSynchronizationAllowed(profileItem, entity); + private boolean shouldNotBeSynchronized(Context context, Item profileItem, Item entity) { + return !orcidSynchronizationService.isSynchronizationAllowed(context, profileItem, entity); } private boolean isNotProfileItem(Item profileItemItem) { diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/OrcidSynchronizationService.java b/dspace-api/src/main/java/org/dspace/orcid/service/OrcidSynchronizationService.java index ae342f310553..d770638e28cf 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/OrcidSynchronizationService.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/OrcidSynchronizationService.java @@ -120,7 +120,7 @@ public boolean setSynchronizationMode(Context context, Item profile, OrcidSynchr * @return true if the given entity type can be synchronize with ORCID, * false otherwise */ - public boolean isSynchronizationAllowed(Item profile, Item item); + public boolean isSynchronizationAllowed(Context context, Item profile, Item item); /** * Returns the ORCID synchronization mode configured for the given profile item. diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java index 98ab0c713a24..c953284f2091 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java @@ -8,13 +8,12 @@ package org.dspace.orcid.service.impl; import static org.apache.commons.lang3.ArrayUtils.contains; +import static org.dspace.profile.OrcidEntitySyncPreference.*; +import static org.springframework.util.StringUtils.capitalize; import java.sql.SQLException; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; -import java.util.UUID; +import java.text.MessageFormat; +import java.util.*; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; @@ -34,6 +33,7 @@ import org.dspace.orcid.service.OrcidQueueService; import org.dspace.profile.OrcidEntitySyncPreference; import org.dspace.services.ConfigurationService; +import org.dspace.util.UUIDUtils; import org.springframework.beans.factory.annotation.Autowired; /** @@ -214,9 +214,19 @@ public void update(Context context, OrcidQueue orcidQueue) throws SQLException { public void recalculateOrcidQueue(Context context, Item profileItem, OrcidEntityType orcidEntityType, OrcidEntitySyncPreference preference) throws SQLException { - String entityType = orcidEntityType.getEntityType(); - if (preference == OrcidEntitySyncPreference.DISABLED) { + String entityType = capitalize(orcidEntityType.name().toLowerCase()); + if (preference == DISABLED) { deleteByProfileItemAndRecordType(context, profileItem, entityType); + } else if(preference == MY_SELECTED || preference == MINE){ + // delete existing queue + deleteByProfileItemAndRecordType(context, profileItem, entityType); + // add additional filterquery + String filterrelationname = configurationService.getProperty("orcid.relationpreference." + entityType + "." + preference.name()); + if(Objects.isNull(filterrelationname)) return; + Iterator entities = findAllEntitiesWithRelationshipFilterLinkableWith(context, profileItem, entityType, filterrelationname); + while (entities.hasNext()) { + create(context, profileItem, entities.next()); + } } else { Iterator entities = findAllEntitiesLinkableWith(context, profileItem, entityType); while (entities.hasNext()) { @@ -249,6 +259,34 @@ private Iterator findAllEntitiesLinkableWith(Context context, Item owner, } + private Iterator findAllEntitiesWithRelationshipFilterLinkableWith(Context context, Item owner, String entityType, String filterrelationname) { + + String ownerType = itemService.getEntityType(owner); + + String query = choiceAuthorityService.getAuthorityControlledFieldsByEntityType(ownerType).stream() + .map(metadataField -> metadataField.replaceAll("_", ".")) + .filter(metadataField -> shouldNotBeIgnoredForOrcid(metadataField)) + .map(metadataField -> metadataField + "_allauthority: \"" + owner.getID().toString() + "\"") + .collect(Collectors.joining(" OR ")); + + if (StringUtils.isEmpty(query)) { + return Collections.emptyIterator(); + } + + DiscoverQuery discoverQuery = new DiscoverQuery(); + discoverQuery.addDSpaceObjectFilter(IndexableItem.TYPE); + discoverQuery.addFilterQueries(query); + discoverQuery.addFilterQueries("search.entitytype:" + entityType); + + filterrelationname = MessageFormat.format(filterrelationname, UUIDUtils.toString(owner.getID())); + discoverQuery.addFilterQueries(filterrelationname); + + + return new DiscoverResultItemIterator(context, discoverQuery); + + } + + private boolean shouldNotBeIgnoredForOrcid(String metadataField) { return !contains(configurationService.getArrayProperty("orcid.linkable-metadata-fields.ignore"), metadataField); } diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java index 065dbc5ee343..be12c67bfc41 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java @@ -18,10 +18,7 @@ import static org.dspace.profile.OrcidEntitySyncPreference.DISABLED; import java.sql.SQLException; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -181,7 +178,7 @@ public boolean setSynchronizationMode(Context context, Item profile, OrcidSynchr } @Override - public boolean isSynchronizationAllowed(Item profile, Item item) { + public boolean isSynchronizationAllowed(Context context, Item profile, Item item) { if (isOrcidSynchronizationDisabled()) { return false; @@ -193,9 +190,23 @@ public boolean isSynchronizationAllowed(Item profile, Item item) { } if (OrcidEntityType.isValidEntityType(entityType)) { - return getEntityPreference(profile, OrcidEntityType.fromEntityType(entityType)) - .filter(pref -> pref != DISABLED) - .isPresent(); + Optional option = getEntityPreference(profile, OrcidEntityType.fromEntityType(entityType)); + if(option.isPresent()){ + if(option.get().equals(DISABLED)) return false; + if(option.get().equals(OrcidEntitySyncPreference.ALL)) return true; + if(option.get().equals(OrcidEntitySyncPreference.MINE) || option.get().equals(OrcidEntitySyncPreference.MY_SELECTED) ){ + String filterrelationname = configurationService.getProperty("orcid.relationpreference." + entityType + "." + option.get().name()); + if(Objects.isNull(filterrelationname)) return false; + Iterator entities = checkRelation(context, profile, item, filterrelationname); + if (entities.hasNext()) { + return true; + }else{ + return false; + } + } + }else{ + return false; + } } if (entityType.equals(researcherProfileService.getProfileType())) { @@ -206,6 +217,16 @@ public boolean isSynchronizationAllowed(Item profile, Item item) { } + public Iterator checkRelation(Context context, Item profile, Item item, String filterrelationname) { + DiscoverQuery discoverQuery = new DiscoverQuery(); + discoverQuery.setDSpaceObjectFilter(IndexableItem.TYPE); + discoverQuery.addFilterQueries("search.resourceid:" + item.getID()); + filterrelationname = filterrelationname.replace("{0}", profile.getID().toString()); + discoverQuery.addFilterQueries(filterrelationname); + discoverQuery.setMaxResults(1); + return new DiscoverResultItemIterator(context, discoverQuery); + } + @Override public Optional getSynchronizationMode(Item item) { return getMetadataValue(item, "dspace.orcid.sync-mode") diff --git a/dspace/config/modules/orcid.cfg b/dspace/config/modules/orcid.cfg index bc4d8cfdd90e..86f333c38e82 100644 --- a/dspace/config/modules/orcid.cfg +++ b/dspace/config/modules/orcid.cfg @@ -47,6 +47,15 @@ orcid.scope = /read-limited orcid.scope = /activities/update orcid.scope = /person/update +#------------------------------------------------------------------# +#---------------------ORCID RELATIONPREFERENCES -------------------# +#------------------------------------------------------------------# +# EntityType.Relation.Type: solrfilterquery:{0} with {0} the id of the owner +#orcid.relationpreference.Funding.MINE = -relation.isProjectsHiddenFor:{0} +#orcid.relationpreference.Funding.MY_SELECTED = relation.isProjectsSelectedFor:{0} +orcid.relationpreference.Publication.MINE = -relation.isResearchoutputsHiddenFor:{0} +orcid.relationpreference.Publication.MY_SELECTED = relation.isResearchoutputsSelectedFor:{0} + #------------------------------------------------------------------# #--------------------ORCID MAPPING CONFIGURATIONS------------------# #------------------------------------------------------------------# From 7285e5bfcaa601cec310575ad985daa71e50d0d3 Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Wed, 7 Dec 2022 10:42:03 +0100 Subject: [PATCH 02/20] fix checkstyle issues --- .../service/impl/OrcidQueueServiceImpl.java | 26 ++++++++---- .../impl/OrcidSynchronizationServiceImpl.java | 41 ++++++++++++------- 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java index c953284f2091..15558162a067 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java @@ -8,12 +8,19 @@ package org.dspace.orcid.service.impl; import static org.apache.commons.lang3.ArrayUtils.contains; -import static org.dspace.profile.OrcidEntitySyncPreference.*; +import static org.dspace.profile.OrcidEntitySyncPreference.DISABLED; +import static org.dspace.profile.OrcidEntitySyncPreference.MINE; +import static org.dspace.profile.OrcidEntitySyncPreference.MY_SELECTED; import static org.springframework.util.StringUtils.capitalize; import java.sql.SQLException; import java.text.MessageFormat; -import java.util.*; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; @@ -217,13 +224,17 @@ public void recalculateOrcidQueue(Context context, Item profileItem, OrcidEntity String entityType = capitalize(orcidEntityType.name().toLowerCase()); if (preference == DISABLED) { deleteByProfileItemAndRecordType(context, profileItem, entityType); - } else if(preference == MY_SELECTED || preference == MINE){ + } else if (preference == MY_SELECTED || preference == MINE) { // delete existing queue deleteByProfileItemAndRecordType(context, profileItem, entityType); // add additional filterquery - String filterrelationname = configurationService.getProperty("orcid.relationpreference." + entityType + "." + preference.name()); - if(Objects.isNull(filterrelationname)) return; - Iterator entities = findAllEntitiesWithRelationshipFilterLinkableWith(context, profileItem, entityType, filterrelationname); + String filterrelationname = configurationService.getProperty("orcid.relationpreference." + + entityType + "." + preference.name()); + if (Objects.isNull(filterrelationname)) { + return; + } + Iterator entities; + entities = findAllRelationShipEntitiesLinkableWith(context, profileItem, entityType, filterrelationname); while (entities.hasNext()) { create(context, profileItem, entities.next()); } @@ -259,7 +270,8 @@ private Iterator findAllEntitiesLinkableWith(Context context, Item owner, } - private Iterator findAllEntitiesWithRelationshipFilterLinkableWith(Context context, Item owner, String entityType, String filterrelationname) { + private Iterator findAllRelationShipEntitiesLinkableWith( + Context context, Item owner, String entityType, String filterrelationname) { String ownerType = itemService.getEntityType(owner); diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java index be12c67bfc41..25c8dfbb237a 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java @@ -15,10 +15,13 @@ import static org.apache.commons.lang3.EnumUtils.isValidEnum; import static org.apache.commons.lang3.StringUtils.isBlank; import static org.dspace.content.Item.ANY; -import static org.dspace.profile.OrcidEntitySyncPreference.DISABLED; import java.sql.SQLException; -import java.util.*; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -190,21 +193,31 @@ public boolean isSynchronizationAllowed(Context context, Item profile, Item item } if (OrcidEntityType.isValidEntityType(entityType)) { - Optional option = getEntityPreference(profile, OrcidEntityType.fromEntityType(entityType)); - if(option.isPresent()){ - if(option.get().equals(DISABLED)) return false; - if(option.get().equals(OrcidEntitySyncPreference.ALL)) return true; - if(option.get().equals(OrcidEntitySyncPreference.MINE) || option.get().equals(OrcidEntitySyncPreference.MY_SELECTED) ){ - String filterrelationname = configurationService.getProperty("orcid.relationpreference." + entityType + "." + option.get().name()); - if(Objects.isNull(filterrelationname)) return false; - Iterator entities = checkRelation(context, profile, item, filterrelationname); - if (entities.hasNext()) { + Optional option; + option = getEntityPreference(profile, OrcidEntityType.fromEntityType(entityType)); + if (option.isPresent()) { + switch (option.get()) { + case DISABLED: + return false; + case ALL: return true; - }else{ + case MINE: + case MY_SELECTED: + String filterproperty = "orcid.relationpreference." + entityType + "." + option.get().name(); + String filter = configurationService.getProperty(filterproperty); + if (Objects.isNull(filter)) { + return false; + } + Iterator entities = checkRelation(context, profile, item, filter); + if (entities.hasNext()) { + return true; + } else { + return false; + } + default: return false; - } } - }else{ + } else { return false; } } From 125297ffd1294ed33459583603e7e7d1664188eb Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Tue, 6 Dec 2022 12:17:10 +0100 Subject: [PATCH 03/20] orcid preferences based on hidden/selected relations for the orcid profiles owner with OrcidEntitySyncPreference MINE and MY_SELECTED for some entity an additional check was added. The check uses the solr-search to determine, if the corresponding/linked item is among the hidden/preferred items of the orcid profile owner. The solr query for the relation can be configured. --- .../org/dspace/content/ItemServiceImpl.java | 2 +- .../orcid/consumer/OrcidQueueConsumer.java | 6 +-- .../service/OrcidSynchronizationService.java | 2 +- .../service/impl/OrcidQueueServiceImpl.java | 52 ++++++++++++++++--- .../impl/OrcidSynchronizationServiceImpl.java | 37 ++++++++++--- dspace/config/modules/orcid.cfg | 9 ++++ 6 files changed, 88 insertions(+), 20 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java index 3ad03377cb27..07973cab6dc4 100644 --- a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java @@ -2048,7 +2048,7 @@ private void createOrcidQueueRecordsToDeleteOnOrcid(Context context, Item entity Map profileAndPutCodeMap = orcidHistoryService.findLastPutCodes(context, entity); for (Item profile : profileAndPutCodeMap.keySet()) { - if (orcidSynchronizationService.isSynchronizationAllowed(profile, entity)) { + if (orcidSynchronizationService.isSynchronizationAllowed(context, profile, entity)) { String putCode = profileAndPutCodeMap.get(profile); String title = getMetadataFirstValue(entity, "dc", "title", null, Item.ANY); orcidQueueService.createEntityDeletionRecord(context, profile, title, entityType, putCode); diff --git a/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java b/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java index 97605429d9cd..0546a206e92a 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java +++ b/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java @@ -158,7 +158,7 @@ private void consumeEntity(Context context, Item entity) throws SQLException { continue; } - if (shouldNotBeSynchronized(relatedItem, entity) || isAlreadyQueued(context, relatedItem, entity)) { + if (shouldNotBeSynchronized(context, relatedItem, entity) || isAlreadyQueued(context, relatedItem, entity)) { continue; } @@ -289,8 +289,8 @@ private boolean hasNotOrcidAccessToken(Context context, Item profileItemItem) { return orcidTokenService.findByProfileItem(context, profileItemItem) == null; } - private boolean shouldNotBeSynchronized(Item profileItem, Item entity) { - return !orcidSynchronizationService.isSynchronizationAllowed(profileItem, entity); + private boolean shouldNotBeSynchronized(Context context, Item profileItem, Item entity) { + return !orcidSynchronizationService.isSynchronizationAllowed(context, profileItem, entity); } private boolean isNotProfileItem(Item profileItemItem) { diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/OrcidSynchronizationService.java b/dspace-api/src/main/java/org/dspace/orcid/service/OrcidSynchronizationService.java index ae342f310553..d770638e28cf 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/OrcidSynchronizationService.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/OrcidSynchronizationService.java @@ -120,7 +120,7 @@ public boolean setSynchronizationMode(Context context, Item profile, OrcidSynchr * @return true if the given entity type can be synchronize with ORCID, * false otherwise */ - public boolean isSynchronizationAllowed(Item profile, Item item); + public boolean isSynchronizationAllowed(Context context, Item profile, Item item); /** * Returns the ORCID synchronization mode configured for the given profile item. diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java index 98ab0c713a24..c953284f2091 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java @@ -8,13 +8,12 @@ package org.dspace.orcid.service.impl; import static org.apache.commons.lang3.ArrayUtils.contains; +import static org.dspace.profile.OrcidEntitySyncPreference.*; +import static org.springframework.util.StringUtils.capitalize; import java.sql.SQLException; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; -import java.util.UUID; +import java.text.MessageFormat; +import java.util.*; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; @@ -34,6 +33,7 @@ import org.dspace.orcid.service.OrcidQueueService; import org.dspace.profile.OrcidEntitySyncPreference; import org.dspace.services.ConfigurationService; +import org.dspace.util.UUIDUtils; import org.springframework.beans.factory.annotation.Autowired; /** @@ -214,9 +214,19 @@ public void update(Context context, OrcidQueue orcidQueue) throws SQLException { public void recalculateOrcidQueue(Context context, Item profileItem, OrcidEntityType orcidEntityType, OrcidEntitySyncPreference preference) throws SQLException { - String entityType = orcidEntityType.getEntityType(); - if (preference == OrcidEntitySyncPreference.DISABLED) { + String entityType = capitalize(orcidEntityType.name().toLowerCase()); + if (preference == DISABLED) { deleteByProfileItemAndRecordType(context, profileItem, entityType); + } else if(preference == MY_SELECTED || preference == MINE){ + // delete existing queue + deleteByProfileItemAndRecordType(context, profileItem, entityType); + // add additional filterquery + String filterrelationname = configurationService.getProperty("orcid.relationpreference." + entityType + "." + preference.name()); + if(Objects.isNull(filterrelationname)) return; + Iterator entities = findAllEntitiesWithRelationshipFilterLinkableWith(context, profileItem, entityType, filterrelationname); + while (entities.hasNext()) { + create(context, profileItem, entities.next()); + } } else { Iterator entities = findAllEntitiesLinkableWith(context, profileItem, entityType); while (entities.hasNext()) { @@ -249,6 +259,34 @@ private Iterator findAllEntitiesLinkableWith(Context context, Item owner, } + private Iterator findAllEntitiesWithRelationshipFilterLinkableWith(Context context, Item owner, String entityType, String filterrelationname) { + + String ownerType = itemService.getEntityType(owner); + + String query = choiceAuthorityService.getAuthorityControlledFieldsByEntityType(ownerType).stream() + .map(metadataField -> metadataField.replaceAll("_", ".")) + .filter(metadataField -> shouldNotBeIgnoredForOrcid(metadataField)) + .map(metadataField -> metadataField + "_allauthority: \"" + owner.getID().toString() + "\"") + .collect(Collectors.joining(" OR ")); + + if (StringUtils.isEmpty(query)) { + return Collections.emptyIterator(); + } + + DiscoverQuery discoverQuery = new DiscoverQuery(); + discoverQuery.addDSpaceObjectFilter(IndexableItem.TYPE); + discoverQuery.addFilterQueries(query); + discoverQuery.addFilterQueries("search.entitytype:" + entityType); + + filterrelationname = MessageFormat.format(filterrelationname, UUIDUtils.toString(owner.getID())); + discoverQuery.addFilterQueries(filterrelationname); + + + return new DiscoverResultItemIterator(context, discoverQuery); + + } + + private boolean shouldNotBeIgnoredForOrcid(String metadataField) { return !contains(configurationService.getArrayProperty("orcid.linkable-metadata-fields.ignore"), metadataField); } diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java index 065dbc5ee343..be12c67bfc41 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java @@ -18,10 +18,7 @@ import static org.dspace.profile.OrcidEntitySyncPreference.DISABLED; import java.sql.SQLException; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -181,7 +178,7 @@ public boolean setSynchronizationMode(Context context, Item profile, OrcidSynchr } @Override - public boolean isSynchronizationAllowed(Item profile, Item item) { + public boolean isSynchronizationAllowed(Context context, Item profile, Item item) { if (isOrcidSynchronizationDisabled()) { return false; @@ -193,9 +190,23 @@ public boolean isSynchronizationAllowed(Item profile, Item item) { } if (OrcidEntityType.isValidEntityType(entityType)) { - return getEntityPreference(profile, OrcidEntityType.fromEntityType(entityType)) - .filter(pref -> pref != DISABLED) - .isPresent(); + Optional option = getEntityPreference(profile, OrcidEntityType.fromEntityType(entityType)); + if(option.isPresent()){ + if(option.get().equals(DISABLED)) return false; + if(option.get().equals(OrcidEntitySyncPreference.ALL)) return true; + if(option.get().equals(OrcidEntitySyncPreference.MINE) || option.get().equals(OrcidEntitySyncPreference.MY_SELECTED) ){ + String filterrelationname = configurationService.getProperty("orcid.relationpreference." + entityType + "." + option.get().name()); + if(Objects.isNull(filterrelationname)) return false; + Iterator entities = checkRelation(context, profile, item, filterrelationname); + if (entities.hasNext()) { + return true; + }else{ + return false; + } + } + }else{ + return false; + } } if (entityType.equals(researcherProfileService.getProfileType())) { @@ -206,6 +217,16 @@ public boolean isSynchronizationAllowed(Item profile, Item item) { } + public Iterator checkRelation(Context context, Item profile, Item item, String filterrelationname) { + DiscoverQuery discoverQuery = new DiscoverQuery(); + discoverQuery.setDSpaceObjectFilter(IndexableItem.TYPE); + discoverQuery.addFilterQueries("search.resourceid:" + item.getID()); + filterrelationname = filterrelationname.replace("{0}", profile.getID().toString()); + discoverQuery.addFilterQueries(filterrelationname); + discoverQuery.setMaxResults(1); + return new DiscoverResultItemIterator(context, discoverQuery); + } + @Override public Optional getSynchronizationMode(Item item) { return getMetadataValue(item, "dspace.orcid.sync-mode") diff --git a/dspace/config/modules/orcid.cfg b/dspace/config/modules/orcid.cfg index bc4d8cfdd90e..86f333c38e82 100644 --- a/dspace/config/modules/orcid.cfg +++ b/dspace/config/modules/orcid.cfg @@ -47,6 +47,15 @@ orcid.scope = /read-limited orcid.scope = /activities/update orcid.scope = /person/update +#------------------------------------------------------------------# +#---------------------ORCID RELATIONPREFERENCES -------------------# +#------------------------------------------------------------------# +# EntityType.Relation.Type: solrfilterquery:{0} with {0} the id of the owner +#orcid.relationpreference.Funding.MINE = -relation.isProjectsHiddenFor:{0} +#orcid.relationpreference.Funding.MY_SELECTED = relation.isProjectsSelectedFor:{0} +orcid.relationpreference.Publication.MINE = -relation.isResearchoutputsHiddenFor:{0} +orcid.relationpreference.Publication.MY_SELECTED = relation.isResearchoutputsSelectedFor:{0} + #------------------------------------------------------------------# #--------------------ORCID MAPPING CONFIGURATIONS------------------# #------------------------------------------------------------------# From 996c6741a9f11d4ca5d1e55a90a8cef4c039ecab Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Wed, 7 Dec 2022 10:42:03 +0100 Subject: [PATCH 04/20] fix checkstyle issues --- .../service/impl/OrcidQueueServiceImpl.java | 26 ++++++++---- .../impl/OrcidSynchronizationServiceImpl.java | 41 ++++++++++++------- 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java index c953284f2091..15558162a067 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java @@ -8,12 +8,19 @@ package org.dspace.orcid.service.impl; import static org.apache.commons.lang3.ArrayUtils.contains; -import static org.dspace.profile.OrcidEntitySyncPreference.*; +import static org.dspace.profile.OrcidEntitySyncPreference.DISABLED; +import static org.dspace.profile.OrcidEntitySyncPreference.MINE; +import static org.dspace.profile.OrcidEntitySyncPreference.MY_SELECTED; import static org.springframework.util.StringUtils.capitalize; import java.sql.SQLException; import java.text.MessageFormat; -import java.util.*; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; @@ -217,13 +224,17 @@ public void recalculateOrcidQueue(Context context, Item profileItem, OrcidEntity String entityType = capitalize(orcidEntityType.name().toLowerCase()); if (preference == DISABLED) { deleteByProfileItemAndRecordType(context, profileItem, entityType); - } else if(preference == MY_SELECTED || preference == MINE){ + } else if (preference == MY_SELECTED || preference == MINE) { // delete existing queue deleteByProfileItemAndRecordType(context, profileItem, entityType); // add additional filterquery - String filterrelationname = configurationService.getProperty("orcid.relationpreference." + entityType + "." + preference.name()); - if(Objects.isNull(filterrelationname)) return; - Iterator entities = findAllEntitiesWithRelationshipFilterLinkableWith(context, profileItem, entityType, filterrelationname); + String filterrelationname = configurationService.getProperty("orcid.relationpreference." + + entityType + "." + preference.name()); + if (Objects.isNull(filterrelationname)) { + return; + } + Iterator entities; + entities = findAllRelationShipEntitiesLinkableWith(context, profileItem, entityType, filterrelationname); while (entities.hasNext()) { create(context, profileItem, entities.next()); } @@ -259,7 +270,8 @@ private Iterator findAllEntitiesLinkableWith(Context context, Item owner, } - private Iterator findAllEntitiesWithRelationshipFilterLinkableWith(Context context, Item owner, String entityType, String filterrelationname) { + private Iterator findAllRelationShipEntitiesLinkableWith( + Context context, Item owner, String entityType, String filterrelationname) { String ownerType = itemService.getEntityType(owner); diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java index be12c67bfc41..25c8dfbb237a 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java @@ -15,10 +15,13 @@ import static org.apache.commons.lang3.EnumUtils.isValidEnum; import static org.apache.commons.lang3.StringUtils.isBlank; import static org.dspace.content.Item.ANY; -import static org.dspace.profile.OrcidEntitySyncPreference.DISABLED; import java.sql.SQLException; -import java.util.*; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -190,21 +193,31 @@ public boolean isSynchronizationAllowed(Context context, Item profile, Item item } if (OrcidEntityType.isValidEntityType(entityType)) { - Optional option = getEntityPreference(profile, OrcidEntityType.fromEntityType(entityType)); - if(option.isPresent()){ - if(option.get().equals(DISABLED)) return false; - if(option.get().equals(OrcidEntitySyncPreference.ALL)) return true; - if(option.get().equals(OrcidEntitySyncPreference.MINE) || option.get().equals(OrcidEntitySyncPreference.MY_SELECTED) ){ - String filterrelationname = configurationService.getProperty("orcid.relationpreference." + entityType + "." + option.get().name()); - if(Objects.isNull(filterrelationname)) return false; - Iterator entities = checkRelation(context, profile, item, filterrelationname); - if (entities.hasNext()) { + Optional option; + option = getEntityPreference(profile, OrcidEntityType.fromEntityType(entityType)); + if (option.isPresent()) { + switch (option.get()) { + case DISABLED: + return false; + case ALL: return true; - }else{ + case MINE: + case MY_SELECTED: + String filterproperty = "orcid.relationpreference." + entityType + "." + option.get().name(); + String filter = configurationService.getProperty(filterproperty); + if (Objects.isNull(filter)) { + return false; + } + Iterator entities = checkRelation(context, profile, item, filter); + if (entities.hasNext()) { + return true; + } else { + return false; + } + default: return false; - } } - }else{ + } else { return false; } } From d4861ec5176c6507c9f0c349a45736a68256e421 Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Mon, 3 Jul 2023 19:02:37 +0200 Subject: [PATCH 05/20] sql script in post migration transforming orcid publications and fundings sync settings --- .../etc/migration/orcid_history_migration.ktr | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/dspace/etc/migration/orcid_history_migration.ktr b/dspace/etc/migration/orcid_history_migration.ktr index 5dfd5b7ad3bc..01d5a87558f0 100644 --- a/dspace/etc/migration/orcid_history_migration.ktr +++ b/dspace/etc/migration/orcid_history_migration.ktr @@ -1666,6 +1666,51 @@ AND h.handle = ? Y + + migrate sync preferences + ExecSQL + + Y + + 1 + + none + + + dspace + N + Y + N + N + UPDATE metadatavalue mv SET text_value = 'DISABLED' FROM metadatafieldregistry mfr, metadataschemaregistry msr WHERE mfr.metadata_field_id = mv.metadata_field_id AND mfr.metadata_schema_id = msr.metadata_schema_id AND mfr.element = 'orcid' AND mfr.qualifier = 'sync-publications' AND msr.short_id = 'dspace' AND mv.text_value = '0'; +UPDATE metadatavalue mv SET text_value = 'ALL' FROM metadatafieldregistry mfr, metadataschemaregistry msr WHERE mfr.metadata_field_id = mv.metadata_field_id AND mfr.metadata_schema_id = msr.metadata_schema_id AND mfr.element = 'orcid' AND mfr.qualifier = 'sync-publications' AND msr.short_id = 'dspace' AND mv.text_value = '1'; +UPDATE metadatavalue mv SET text_value = 'DISABLED' FROM metadatafieldregistry mfr, metadataschemaregistry msr WHERE mfr.metadata_field_id = mv.metadata_field_id AND mfr.metadata_schema_id = msr.metadata_schema_id AND mfr.element = 'orcid' AND mfr.qualifier = 'sync-publications' AND msr.short_id = 'dspace' AND mv.text_value = '2'; +UPDATE metadatavalue mv SET text_value = 'DISABLED' FROM metadatafieldregistry mfr, metadataschemaregistry msr WHERE mfr.metadata_field_id = mv.metadata_field_id AND mfr.metadata_schema_id = msr.metadata_schema_id AND mfr.element = 'orcid' AND mfr.qualifier = 'sync-publications' AND msr.short_id = 'dspace' AND mv.text_value = '3'; +UPDATE metadatavalue mv SET text_value = 'DISABLED' FROM metadatafieldregistry mfr, metadataschemaregistry msr WHERE mfr.metadata_field_id = mv.metadata_field_id AND mfr.metadata_schema_id = msr.metadata_schema_id AND mfr.element = 'orcid' AND mfr.qualifier = 'sync-fundings' AND msr.short_id = 'dspace' AND mv.text_value = '0'; +UPDATE metadatavalue mv SET text_value = 'ALL' FROM metadatafieldregistry mfr, metadataschemaregistry msr WHERE mfr.metadata_field_id = mv.metadata_field_id AND mfr.metadata_schema_id = msr.metadata_schema_id AND mfr.element = 'orcid' AND mfr.qualifier = 'sync-fundings' AND msr.short_id = 'dspace' AND mv.text_value = '1'; +UPDATE metadatavalue mv SET text_value = 'DISABLED' FROM metadatafieldregistry mfr, metadataschemaregistry msr WHERE mfr.metadata_field_id = mv.metadata_field_id AND mfr.metadata_schema_id = msr.metadata_schema_id AND mfr.element = 'orcid' AND mfr.qualifier = 'sync-fundings' AND msr.short_id = 'dspace' AND mv.text_value = '2'; +UPDATE metadatavalue mv SET text_value = 'DISABLED' FROM metadatafieldregistry mfr, metadataschemaregistry msr WHERE mfr.metadata_field_id = mv.metadata_field_id AND mfr.metadata_schema_id = msr.metadata_schema_id AND mfr.element = 'orcid' AND mfr.qualifier = 'sync-fundings' AND msr.short_id = 'dspace' AND mv.text_value = '3'; + N + + + + + + + + + + + + + + + + 656 + 880 + Y + + From 86aee5a4489c28c5d48243f69f799560288148c4 Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Mon, 3 Jul 2023 19:10:21 +0200 Subject: [PATCH 06/20] Revert "sql script in post migration transforming orcid publications and fundings sync settings" This reverts commit d4861ec5176c6507c9f0c349a45736a68256e421. --- .../etc/migration/orcid_history_migration.ktr | 45 ------------------- 1 file changed, 45 deletions(-) diff --git a/dspace/etc/migration/orcid_history_migration.ktr b/dspace/etc/migration/orcid_history_migration.ktr index 01d5a87558f0..5dfd5b7ad3bc 100644 --- a/dspace/etc/migration/orcid_history_migration.ktr +++ b/dspace/etc/migration/orcid_history_migration.ktr @@ -1666,51 +1666,6 @@ AND h.handle = ? Y - - migrate sync preferences - ExecSQL - - Y - - 1 - - none - - - dspace - N - Y - N - N - UPDATE metadatavalue mv SET text_value = 'DISABLED' FROM metadatafieldregistry mfr, metadataschemaregistry msr WHERE mfr.metadata_field_id = mv.metadata_field_id AND mfr.metadata_schema_id = msr.metadata_schema_id AND mfr.element = 'orcid' AND mfr.qualifier = 'sync-publications' AND msr.short_id = 'dspace' AND mv.text_value = '0'; -UPDATE metadatavalue mv SET text_value = 'ALL' FROM metadatafieldregistry mfr, metadataschemaregistry msr WHERE mfr.metadata_field_id = mv.metadata_field_id AND mfr.metadata_schema_id = msr.metadata_schema_id AND mfr.element = 'orcid' AND mfr.qualifier = 'sync-publications' AND msr.short_id = 'dspace' AND mv.text_value = '1'; -UPDATE metadatavalue mv SET text_value = 'DISABLED' FROM metadatafieldregistry mfr, metadataschemaregistry msr WHERE mfr.metadata_field_id = mv.metadata_field_id AND mfr.metadata_schema_id = msr.metadata_schema_id AND mfr.element = 'orcid' AND mfr.qualifier = 'sync-publications' AND msr.short_id = 'dspace' AND mv.text_value = '2'; -UPDATE metadatavalue mv SET text_value = 'DISABLED' FROM metadatafieldregistry mfr, metadataschemaregistry msr WHERE mfr.metadata_field_id = mv.metadata_field_id AND mfr.metadata_schema_id = msr.metadata_schema_id AND mfr.element = 'orcid' AND mfr.qualifier = 'sync-publications' AND msr.short_id = 'dspace' AND mv.text_value = '3'; -UPDATE metadatavalue mv SET text_value = 'DISABLED' FROM metadatafieldregistry mfr, metadataschemaregistry msr WHERE mfr.metadata_field_id = mv.metadata_field_id AND mfr.metadata_schema_id = msr.metadata_schema_id AND mfr.element = 'orcid' AND mfr.qualifier = 'sync-fundings' AND msr.short_id = 'dspace' AND mv.text_value = '0'; -UPDATE metadatavalue mv SET text_value = 'ALL' FROM metadatafieldregistry mfr, metadataschemaregistry msr WHERE mfr.metadata_field_id = mv.metadata_field_id AND mfr.metadata_schema_id = msr.metadata_schema_id AND mfr.element = 'orcid' AND mfr.qualifier = 'sync-fundings' AND msr.short_id = 'dspace' AND mv.text_value = '1'; -UPDATE metadatavalue mv SET text_value = 'DISABLED' FROM metadatafieldregistry mfr, metadataschemaregistry msr WHERE mfr.metadata_field_id = mv.metadata_field_id AND mfr.metadata_schema_id = msr.metadata_schema_id AND mfr.element = 'orcid' AND mfr.qualifier = 'sync-fundings' AND msr.short_id = 'dspace' AND mv.text_value = '2'; -UPDATE metadatavalue mv SET text_value = 'DISABLED' FROM metadatafieldregistry mfr, metadataschemaregistry msr WHERE mfr.metadata_field_id = mv.metadata_field_id AND mfr.metadata_schema_id = msr.metadata_schema_id AND mfr.element = 'orcid' AND mfr.qualifier = 'sync-fundings' AND msr.short_id = 'dspace' AND mv.text_value = '3'; - N - - - - - - - - - - - - - - - - 656 - 880 - Y - - From 9dd4406c0adbb15ece8d62011372c36ab49c422f Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Tue, 4 Jul 2023 13:46:13 +0200 Subject: [PATCH 07/20] fix build error from merge --- .../main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java b/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java index 9a3d2e2acb5d..0546a206e92a 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java +++ b/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java @@ -162,7 +162,7 @@ private void consumeEntity(Context context, Item entity) throws SQLException { continue; } - orcidQueueService.create(context, owner, entity); + orcidQueueService.create(context, relatedItem, entity); } From e61c9414f0c3ee88292a014690684996622c28f9 Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Wed, 5 Jul 2023 18:47:57 +0200 Subject: [PATCH 08/20] fix checkstyle issue --- .../java/org/dspace/orcid/consumer/OrcidQueueConsumer.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java b/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java index 0546a206e92a..2198c9f18c6b 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java +++ b/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java @@ -158,7 +158,8 @@ private void consumeEntity(Context context, Item entity) throws SQLException { continue; } - if (shouldNotBeSynchronized(context, relatedItem, entity) || isAlreadyQueued(context, relatedItem, entity)) { + if (shouldNotBeSynchronized(context, relatedItem, entity) || + isAlreadyQueued(context, relatedItem, entity)) { continue; } From 26b58ae2bf816c2306f00705ad870c235f0302ef Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Fri, 18 Aug 2023 17:41:41 +0200 Subject: [PATCH 09/20] delete orcid queues entries which should not be synchronized this can occur when some relation was removed (e.g. selected) which is not reflected to the orcid queue. The entry is only removen when the whole queue is recalculated --- .../org/dspace/orcid/consumer/OrcidQueueConsumer.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java b/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java index 2198c9f18c6b..d70ecd87918e 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java +++ b/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java @@ -34,6 +34,7 @@ import org.dspace.event.Event; import org.dspace.orcid.OrcidHistory; import org.dspace.orcid.OrcidOperation; +import org.dspace.orcid.OrcidQueue; import org.dspace.orcid.factory.OrcidServiceFactory; import org.dspace.orcid.model.OrcidEntityType; import org.dspace.orcid.model.factory.OrcidProfileSectionFactory; @@ -160,6 +161,15 @@ private void consumeEntity(Context context, Item entity) throws SQLException { if (shouldNotBeSynchronized(context, relatedItem, entity) || isAlreadyQueued(context, relatedItem, entity)) { + // delete queue entries which are queued but which should not be synchronized anymore + if (isAlreadyQueued(context, relatedItem, entity) && + shouldNotBeSynchronized(context, relatedItem, entity)) { + List queueentries = + orcidQueueService.findByProfileItemAndEntity(context, relatedItem, entity); + for (OrcidQueue queueentry : queueentries) { + orcidQueueService.delete(context, queueentry); + } + } continue; } From f096dbd7dd176b41ec2cc4cacf477de8caa5cb34 Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Fri, 18 Aug 2023 17:42:28 +0200 Subject: [PATCH 10/20] minor fixes on orcud queue und sync implementations especially new introduced null checks --- .../dspace/orcid/service/OrcidSynchronizationService.java | 4 ++-- .../dspace/orcid/service/impl/OrcidQueueServiceImpl.java | 6 ++---- .../orcid/service/impl/OrcidSynchronizationServiceImpl.java | 5 ++--- dspace/config/modules/orcid.cfg | 6 +++++- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/OrcidSynchronizationService.java b/dspace-api/src/main/java/org/dspace/orcid/service/OrcidSynchronizationService.java index d770638e28cf..49b6ecf54442 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/OrcidSynchronizationService.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/OrcidSynchronizationService.java @@ -22,7 +22,7 @@ import org.dspace.profile.OrcidSynchronizationMode; /** - * Service that handle the the syncronization between a DSpace profile and the + * Service that handle the syncronization between a DSpace profile and the * relative ORCID profile, if any. * * @author Luca Giamminonni (luca.giamminonni at 4science.it) @@ -117,7 +117,7 @@ public boolean setSynchronizationMode(Context context, Item profile, OrcidSynchr * * @param profile the researcher profile item * @param item the entity type to check - * @return true if the given entity type can be synchronize with ORCID, + * @return true if the given entity type can be synchronized with ORCID, * false otherwise */ public boolean isSynchronizationAllowed(Context context, Item profile, Item item); diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java index 15558162a067..0304caf7de36 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java @@ -11,14 +11,12 @@ import static org.dspace.profile.OrcidEntitySyncPreference.DISABLED; import static org.dspace.profile.OrcidEntitySyncPreference.MINE; import static org.dspace.profile.OrcidEntitySyncPreference.MY_SELECTED; -import static org.springframework.util.StringUtils.capitalize; import java.sql.SQLException; import java.text.MessageFormat; import java.util.Collections; import java.util.Iterator; import java.util.List; -import java.util.Objects; import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; @@ -221,7 +219,7 @@ public void update(Context context, OrcidQueue orcidQueue) throws SQLException { public void recalculateOrcidQueue(Context context, Item profileItem, OrcidEntityType orcidEntityType, OrcidEntitySyncPreference preference) throws SQLException { - String entityType = capitalize(orcidEntityType.name().toLowerCase()); + String entityType = orcidEntityType.getEntityType(); if (preference == DISABLED) { deleteByProfileItemAndRecordType(context, profileItem, entityType); } else if (preference == MY_SELECTED || preference == MINE) { @@ -230,7 +228,7 @@ public void recalculateOrcidQueue(Context context, Item profileItem, OrcidEntity // add additional filterquery String filterrelationname = configurationService.getProperty("orcid.relationpreference." + entityType + "." + preference.name()); - if (Objects.isNull(filterrelationname)) { + if (StringUtils.isBlank(filterrelationname)) { return; } Iterator entities; diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java index 25c8dfbb237a..e0f4225963db 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java @@ -20,7 +20,6 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -205,7 +204,7 @@ public boolean isSynchronizationAllowed(Context context, Item profile, Item item case MY_SELECTED: String filterproperty = "orcid.relationpreference." + entityType + "." + option.get().name(); String filter = configurationService.getProperty(filterproperty); - if (Objects.isNull(filter)) { + if (isBlank(filter) || !filter.contains("{0}")) { return false; } Iterator entities = checkRelation(context, profile, item, filter); @@ -230,7 +229,7 @@ public boolean isSynchronizationAllowed(Context context, Item profile, Item item } - public Iterator checkRelation(Context context, Item profile, Item item, String filterrelationname) { + private Iterator checkRelation(Context context, Item profile, Item item, String filterrelationname) { DiscoverQuery discoverQuery = new DiscoverQuery(); discoverQuery.setDSpaceObjectFilter(IndexableItem.TYPE); discoverQuery.addFilterQueries("search.resourceid:" + item.getID()); diff --git a/dspace/config/modules/orcid.cfg b/dspace/config/modules/orcid.cfg index 86f333c38e82..2a952da8fb64 100644 --- a/dspace/config/modules/orcid.cfg +++ b/dspace/config/modules/orcid.cfg @@ -50,7 +50,11 @@ orcid.scope = /person/update #------------------------------------------------------------------# #---------------------ORCID RELATIONPREFERENCES -------------------# #------------------------------------------------------------------# -# EntityType.Relation.Type: solrfilterquery:{0} with {0} the id of the owner +# This allows to push certains relations and their preferences as MINE and MY_SELECTED settigns on entities +# e.g. MY_SELECTED pushes only selected publications of some user +# e.g. MINE pushes all publications of some user but not hidden ones +# The Relation must be configured and it's checked by some solr query with {0} containing the id of the profile +# orcid.relationpreference..: :{0} #orcid.relationpreference.Funding.MINE = -relation.isProjectsHiddenFor:{0} #orcid.relationpreference.Funding.MY_SELECTED = relation.isProjectsSelectedFor:{0} orcid.relationpreference.Publication.MINE = -relation.isResearchoutputsHiddenFor:{0} From 6224aaa622b51aded3e67e3829ea9569ef18d5e8 Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Fri, 18 Aug 2023 17:45:39 +0200 Subject: [PATCH 11/20] Integration tests for orcid queue among relations tests to check the creation of OrcidEntitySyncPreference MINE and MY_SELECTED with different configuration settings and test cases as well as new tests on changes on the recalculation of the orcid queue with these new settings --- .../dspace/orcid/OrcidQueueConsumerIT.java | 427 ++++++++++++++++++ 1 file changed, 427 insertions(+) diff --git a/dspace-api/src/test/java/org/dspace/orcid/OrcidQueueConsumerIT.java b/dspace-api/src/test/java/org/dspace/orcid/OrcidQueueConsumerIT.java index 1cec9473ba22..4fbc509b8013 100644 --- a/dspace-api/src/test/java/org/dspace/orcid/OrcidQueueConsumerIT.java +++ b/dspace-api/src/test/java/org/dspace/orcid/OrcidQueueConsumerIT.java @@ -16,6 +16,8 @@ import static org.dspace.orcid.model.OrcidProfileSectionType.KEYWORDS; import static org.dspace.profile.OrcidEntitySyncPreference.ALL; import static org.dspace.profile.OrcidEntitySyncPreference.DISABLED; +import static org.dspace.profile.OrcidEntitySyncPreference.MINE; +import static org.dspace.profile.OrcidEntitySyncPreference.MY_SELECTED; import static org.dspace.profile.OrcidProfileSyncPreference.AFFILIATION; import static org.dspace.profile.OrcidProfileSyncPreference.BIOGRAPHICAL; import static org.dspace.profile.OrcidProfileSyncPreference.EDUCATION; @@ -37,16 +39,24 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; +import org.dspace.builder.EntityTypeBuilder; import org.dspace.builder.ItemBuilder; import org.dspace.builder.OrcidHistoryBuilder; +import org.dspace.builder.RelationshipBuilder; +import org.dspace.builder.RelationshipTypeBuilder; import org.dspace.content.Collection; +import org.dspace.content.EntityType; import org.dspace.content.Item; import org.dspace.content.MetadataValue; +import org.dspace.content.Relationship; +import org.dspace.content.RelationshipType; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.ItemService; import org.dspace.orcid.consumer.OrcidQueueConsumer; import org.dspace.orcid.factory.OrcidServiceFactory; +import org.dspace.orcid.model.OrcidEntityType; import org.dspace.orcid.service.OrcidQueueService; +import org.dspace.profile.OrcidEntitySyncPreference; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; import org.junit.After; @@ -473,6 +483,416 @@ public void testOrcidQueueRecordCreationForPublication() throws Exception { assertThat(orcidQueueRecords.get(0), equalTo(newOrcidQueueRecords.get(0))); } + @Test + public void testOrcidQueueRecordCreationForPublicationRelationMySELECTED() throws Exception { + + context.turnOffAuthorisationSystem(); + + configurationService.addPropertyValue("orcid.relationpreference.Publication.MY_SELECTED", + "relation.isResearchoutputsSelectedFor:{0}"); + + Item profile = ItemBuilder.createItem(context, profileCollection) + .withTitle("Test User") + .withOrcidIdentifier("0000-1111-2222-3333") + .withOrcidAccessToken("ab4d18a0-8d9a-40f1-b601-a417255c8d20", eperson) + .withOrcidSynchronizationPublicationsPreference(MY_SELECTED) + .build(); + + Collection publicationCollection = createCollection("Publications", "Publication"); + + Item publication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication") + .withAuthor("Test User", profile.getID().toString()) + .build(); + + Item secondpublication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication 2") + .withAuthor("Test User", profile.getID().toString()) + .build(); + + Item thirdpublication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication 3") + .withAuthor("Test User", profile.getID().toString()) + .build(); + + EntityType personType = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); + + RelationshipType SelectedType = RelationshipTypeBuilder + .createRelationshipTypeBuilder(context, null, personType, "isResearchoutputsSelectedFor", + "hasSelectedResearchoutputs", 0, null, 0, + null).build(); + + RelationshipBuilder.createRelationshipBuilder(context, publication, profile, SelectedType).build(); + + context.restoreAuthSystemState(); + context.commit(); + + List orcidQueueRecords = orcidQueueService.findAll(context); + assertThat(orcidQueueRecords, hasSize(1)); + assertThat(orcidQueueRecords.get(0), matches(profile, publication, "Publication", INSERT)); + + addMetadata(publication, "dc", "contributor", "editor", "Editor", null); + addMetadata(secondpublication, "dc", "contributor", "editor", "Editor", null); + addMetadata(thirdpublication, "dc", "contributor", "editor", "Editor", null); + context.commit(); + + List newOrcidQueueRecords = orcidQueueService.findAll(context); + assertThat(newOrcidQueueRecords, hasSize(1)); + + assertThat(orcidQueueRecords.get(0), equalTo(newOrcidQueueRecords.get(0))); + + context.turnOffAuthorisationSystem(); + Relationship secondrelselected = + RelationshipBuilder.createRelationshipBuilder(context, secondpublication, profile, SelectedType) + .build(); + context.restoreAuthSystemState(); + context.commit(); + + List newaftercreationOrcidQueueRecords = orcidQueueService.findAll(context); + assertThat(newaftercreationOrcidQueueRecords, hasSize(2)); + assertThat(newaftercreationOrcidQueueRecords.get(0), matches(profile, publication, "Publication", INSERT)); + assertThat(newaftercreationOrcidQueueRecords.get(1), matches(profile, secondpublication, + "Publication", INSERT)); + + context.turnOffAuthorisationSystem(); + RelationshipBuilder.deleteRelationship(secondrelselected.getID()); + itemService.update(context, secondpublication); + context.restoreAuthSystemState(); + context.commit(); + + List newafterdeletionOrcidQueueRecords = orcidQueueService.findAll(context); + assertThat(newafterdeletionOrcidQueueRecords, hasSize(1)); + assertThat(newafterdeletionOrcidQueueRecords.get(0), matches(profile, publication, "Publication", INSERT)); + } + + @Test + public void testNoOrcidQueueRecordCreationForPublicationIfRelationMYSELECTEDIsNotConfigured() throws Exception { + + context.turnOffAuthorisationSystem(); + configurationService.setProperty("orcid.relationpreference.Publication.MY_SELECTED", null); + Item profile = ItemBuilder.createItem(context, profileCollection) + .withTitle("Test User") + .withOrcidIdentifier("0000-1111-2222-3333") + .withOrcidAccessToken("ab4d18a0-8d9a-40f1-b601-a417255c8d20", eperson) + .withOrcidSynchronizationPublicationsPreference(MY_SELECTED) + .build(); + + Collection publicationCollection = createCollection("Publications", "Publication"); + + Item publication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication") + .withAuthor("Test User", profile.getID().toString()) + .build(); + + Item secondpublication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication 2") + .withAuthor("Test User", profile.getID().toString()) + .build(); + + EntityType personType = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); + + RelationshipType SelectedType = RelationshipTypeBuilder + .createRelationshipTypeBuilder(context, null, personType, "isResearchoutputsSelectedFor", + "hasSelectedResearchoutputs", 0, null, 0, + null).build(); + + RelationshipBuilder.createRelationshipBuilder(context, publication, profile, SelectedType).build(); + RelationshipBuilder.createRelationshipBuilder(context, secondpublication, profile, SelectedType).build(); + + context.restoreAuthSystemState(); + context.commit(); + + List orcidQueueRecords = orcidQueueService.findAll(context); + assertThat(orcidQueueRecords, hasSize(0)); + + addMetadata(publication, "dc", "contributor", "editor", "Editor", null); + addMetadata(secondpublication, "dc", "contributor", "editor", "Editor", null); + context.commit(); + + List newOrcidQueueRecords = orcidQueueService.findAll(context); + assertThat(newOrcidQueueRecords, hasSize(0)); + + } + @Test + public void testNoOrcidQueueRecordCreationForPublicationIfRelationMYSELECTEDQueryHasNoProfile() throws Exception { + + context.turnOffAuthorisationSystem(); + configurationService.setProperty("orcid.relationpreference.Publication.MY_SELECTED", + "isResearchoutputsSelectedFor"); + Item profile = ItemBuilder.createItem(context, profileCollection) + .withTitle("Test User") + .withOrcidIdentifier("0000-1111-2222-3333") + .withOrcidAccessToken("ab4d18a0-8d9a-40f1-b601-a417255c8d20", eperson) + .withOrcidSynchronizationPublicationsPreference(MY_SELECTED) + .build(); + + Collection publicationCollection = createCollection("Publications", "Publication"); + + Item publication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication") + .withAuthor("Test User", profile.getID().toString()) + .build(); + + Item secondpublication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication 2") + .withAuthor("Test User", profile.getID().toString()) + .build(); + + EntityType personType = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); + + RelationshipType SelectedType = RelationshipTypeBuilder + .createRelationshipTypeBuilder(context, null, personType, "isResearchoutputsSelectedFor", + "hasSelectedResearchoutputs", 0, null, 0, + null).build(); + + RelationshipBuilder.createRelationshipBuilder(context, publication, profile, SelectedType).build(); + RelationshipBuilder.createRelationshipBuilder(context, secondpublication, profile, SelectedType).build(); + + context.restoreAuthSystemState(); + context.commit(); + + List orcidQueueRecords = orcidQueueService.findAll(context); + assertThat(orcidQueueRecords, hasSize(0)); + } + + @Test + public void testOrcidQueueRecordCreationForPublicationRelationMINE() throws Exception { + + context.turnOffAuthorisationSystem(); + Item profile = ItemBuilder.createItem(context, profileCollection) + .withTitle("Test User") + .withOrcidIdentifier("0000-1111-2222-3333") + .withOrcidAccessToken("ab4d18a0-8d9a-40f1-b601-a417255c8d20", eperson) + .withOrcidSynchronizationPublicationsPreference(MINE) + .build(); + + Collection publicationCollection = createCollection("Publications", "Publication"); + + Item publication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication") + .withAuthor("Test User", profile.getID().toString()) + .build(); + + Item secondpublication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication 2") + .withAuthor("Test User", profile.getID().toString()) + .build(); + + Item thirdpublication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication 3") + .withAuthor("Test User", profile.getID().toString()) + .build(); + itemService.update(context, thirdpublication); + EntityType personType = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); + + RelationshipType SelectedType = RelationshipTypeBuilder + .createRelationshipTypeBuilder(context, null, personType, "isResearchoutputsSelectedFor", + "hasSelectedResearchoutputs", 0, null, 0, + null).build(); + RelationshipType HiddenType = RelationshipTypeBuilder + .createRelationshipTypeBuilder(context, null, personType, "isResearchoutputsHiddenFor", + "notDisplayingResearchoutputs", 0, null, 0, + null).build(); + + RelationshipBuilder.createRelationshipBuilder(context, publication, profile, SelectedType).build(); + RelationshipBuilder.createRelationshipBuilder(context, secondpublication, profile, HiddenType).build(); + + context.restoreAuthSystemState(); + context.commit(); + + List orcidQueueRecords = orcidQueueService.findAll(context); + assertThat(orcidQueueRecords, hasSize(2)); + assertThat(orcidQueueRecords.get(0), matches(profile, thirdpublication, "Publication", INSERT)); + assertThat(orcidQueueRecords.get(1), matches(profile, publication, "Publication", INSERT)); + + addMetadata(publication, "dc", "contributor", "editor", "Editor", null); + addMetadata(secondpublication, "dc", "contributor", "editor", "Editor", null); + addMetadata(thirdpublication, "dc", "contributor", "editor", "Editor", null); + context.commit(); + + List newOrcidQueueRecords = orcidQueueService.findAll(context); + assertThat(newOrcidQueueRecords, hasSize(2)); + + assertThat(orcidQueueRecords.get(0), equalTo(newOrcidQueueRecords.get(0))); + assertThat(orcidQueueRecords.get(1), equalTo(newOrcidQueueRecords.get(1))); + + context.turnOffAuthorisationSystem(); + Relationship relbeingdeleted = + RelationshipBuilder.createRelationshipBuilder(context, thirdpublication, profile, HiddenType).build(); + context.restoreAuthSystemState(); + context.commit(); + + List newcreationQueueRecords = orcidQueueService.findAll(context); + assertThat(newcreationQueueRecords, hasSize(1)); + assertThat(newcreationQueueRecords.get(0), matches(profile, publication, "Publication", INSERT)); + context.turnOffAuthorisationSystem(); + + context.turnOffAuthorisationSystem(); + RelationshipBuilder.deleteRelationship(relbeingdeleted.getID()); + itemService.update(context, thirdpublication); + context.restoreAuthSystemState(); + context.commit(); + + List newafterdeletionQueueRecords = orcidQueueService.findAll(context); + assertThat(newafterdeletionQueueRecords, hasSize(2)); + assertThat(newafterdeletionQueueRecords.get(0), matches(profile, publication, "Publication", INSERT)); + assertThat(newafterdeletionQueueRecords.get(1), matches(profile, thirdpublication, "Publication", INSERT)); + } + + @Test + public void testNoOrcidQueueRecordCreationForPublicationRelationMineIfAllAreHidden() throws Exception { + + context.turnOffAuthorisationSystem(); + Item profile = ItemBuilder.createItem(context, profileCollection) + .withTitle("Test User") + .withOrcidIdentifier("0000-1111-2222-3333") + .withOrcidAccessToken("ab4d18a0-8d9a-40f1-b601-a417255c8d20", eperson) + .withOrcidSynchronizationPublicationsPreference(MINE) + .build(); + + Collection publicationCollection = createCollection("Publications", "Publication"); + + Item publication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication") + .withAuthor("Test User", profile.getID().toString()) + .build(); + + Item secondpublication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication 2") + .withAuthor("Test User", profile.getID().toString()) + .build(); + + EntityType personType = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); + + RelationshipType HiddenType = RelationshipTypeBuilder + .createRelationshipTypeBuilder(context, null, personType, "isResearchoutputsHiddenFor", + "notDisplayingResearchoutputs", 0, null, 0, + null).build(); + + RelationshipBuilder.createRelationshipBuilder(context, publication, profile, HiddenType).build(); + RelationshipBuilder.createRelationshipBuilder(context, secondpublication, profile, HiddenType).build(); + + context.restoreAuthSystemState(); + context.commit(); + + List orcidQueueRecords = orcidQueueService.findAll(context); + assertThat(orcidQueueRecords, hasSize(0)); + + addMetadata(publication, "dc", "contributor", "editor", "Editor", null); + addMetadata(secondpublication, "dc", "contributor", "editor", "Editor", null); + context.commit(); + + List newOrcidQueueRecords = orcidQueueService.findAll(context); + assertThat(newOrcidQueueRecords, hasSize(0)); + } + + @Test + public void testNoOrcidQueueRecordCreationOccursIfPublicationRelationMYSELECTEDNoneExist() throws Exception { + + context.turnOffAuthorisationSystem(); + Item profile = ItemBuilder.createItem(context, profileCollection) + .withTitle("Test User") + .withOrcidIdentifier("0000-1111-2222-3333") + .withOrcidAccessToken("ab4d18a0-8d9a-40f1-b601-a417255c8d20", eperson) + .withOrcidSynchronizationPublicationsPreference(MY_SELECTED) + .build(); + + Collection publicationCollection = createCollection("Publications", "Publication"); + + Item publication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication") + .withAuthor("Test User", profile.getID().toString()) + .build(); + + Item secondpublication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication 2") + .withAuthor("Test User", profile.getID().toString()) + .build(); + + context.restoreAuthSystemState(); + context.commit(); + + List orcidQueueRecords = orcidQueueService.findAll(context); + assertThat(orcidQueueRecords, hasSize(0)); + + addMetadata(publication, "dc", "contributor", "editor", "Editor", null); + addMetadata(secondpublication, "dc", "contributor", "editor", "Editor", null); + context.commit(); + + List newOrcidQueueRecords = orcidQueueService.findAll(context); + assertThat(newOrcidQueueRecords, hasSize(0)); + } + + @Test + public void testOrcidQueueRecalculationForChangedPublicationRelationSettings() throws Exception { + + context.turnOffAuthorisationSystem(); + Item profile = ItemBuilder.createItem(context, profileCollection) + .withTitle("Test User") + .withOrcidIdentifier("0000-1111-2222-3333") + .withOrcidAccessToken("ab4d18a0-8d9a-40f1-b601-a417255c8d20", eperson) + .withOrcidSynchronizationPublicationsPreference(ALL) + .build(); + + Collection publicationCollection = createCollection("Publications", "Publication"); + + Item publication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication") + .withAuthor("Test User", profile.getID().toString()) + .build(); + + Item secondpublication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication 2") + .withAuthor("Test User", profile.getID().toString()) + .build(); + + Item thirdpublication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication 3") + .withAuthor("Test User", profile.getID().toString()) + .build(); + + EntityType personType = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); + + RelationshipType HiddenType = RelationshipTypeBuilder + .createRelationshipTypeBuilder(context, null, personType, "isResearchoutputsHiddenFor", + "notDisplayingResearchoutputs", 0, null, 0, + null).build(); + + RelationshipType SelectedType = RelationshipTypeBuilder + .createRelationshipTypeBuilder(context, null, personType, "isResearchoutputsSelectedFor", + "hasSelectedResearchoutputs", 0, null, 0, + null).build(); + + RelationshipBuilder.createRelationshipBuilder(context, publication, profile, HiddenType).build(); + RelationshipBuilder.createRelationshipBuilder(context, secondpublication, profile, SelectedType).build(); + + context.restoreAuthSystemState(); + context.commit(); + + List orcidQueueRecords = orcidQueueService.findAll(context); + assertThat(orcidQueueRecords, hasSize(3)); + assertThat(orcidQueueRecords.get(0), matches(profile, publication, "Publication", INSERT)); + assertThat(orcidQueueRecords.get(1), matches(profile, secondpublication, "Publication", INSERT)); + assertThat(orcidQueueRecords.get(2), matches(profile, thirdpublication, "Publication", INSERT)); + + changeProfilePublicationSyncPreference(profile, MY_SELECTED); + + List selectedOrcidQueueRecords = orcidQueueService.findAll(context); + assertThat(selectedOrcidQueueRecords, hasSize(1)); + assertThat(selectedOrcidQueueRecords.get(0), matches(profile, secondpublication, "Publication", INSERT)); + + changeProfilePublicationSyncPreference(profile, MINE); + + List mineOrcidQueueRecords = orcidQueueService.findAll(context); + assertThat(mineOrcidQueueRecords, hasSize(2)); + assertThat(mineOrcidQueueRecords.get(0), matches(profile, thirdpublication, "Publication", INSERT)); + assertThat(mineOrcidQueueRecords.get(1), matches(profile, secondpublication, "Publication", INSERT)); + + changeProfilePublicationSyncPreference(profile, DISABLED); + + List disabledOrcidQueueRecords = orcidQueueService.findAll(context); + assertThat(disabledOrcidQueueRecords, hasSize(0)); + } @Test public void testOrcidQueueRecordCreationToUpdatePublication() throws Exception { @@ -991,4 +1411,11 @@ private Collection createCollection(String name, String entityType) { .build(); } + private void changeProfilePublicationSyncPreference(Item profile, OrcidEntitySyncPreference preference) + throws SQLException { + context.turnOffAuthorisationSystem(); + orcidQueueService.recalculateOrcidQueue(context, profile, OrcidEntityType.PUBLICATION, preference); + context.restoreAuthSystemState(); + context.commit(); + } } From fbec5392e123a9153eab76ec4d186c39d30efa16 Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Fri, 18 Aug 2023 18:04:07 +0200 Subject: [PATCH 12/20] improve and align replacement of variable --- .../orcid/service/impl/OrcidSynchronizationServiceImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java index e0f4225963db..89f2fb747057 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java @@ -17,6 +17,7 @@ import static org.dspace.content.Item.ANY; import java.sql.SQLException; +import java.text.MessageFormat; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -49,6 +50,7 @@ import org.dspace.profile.OrcidSynchronizationMode; import org.dspace.profile.service.ResearcherProfileService; import org.dspace.services.ConfigurationService; +import org.dspace.util.UUIDUtils; import org.springframework.beans.factory.annotation.Autowired; /** @@ -233,7 +235,7 @@ private Iterator checkRelation(Context context, Item profile, Item item, S DiscoverQuery discoverQuery = new DiscoverQuery(); discoverQuery.setDSpaceObjectFilter(IndexableItem.TYPE); discoverQuery.addFilterQueries("search.resourceid:" + item.getID()); - filterrelationname = filterrelationname.replace("{0}", profile.getID().toString()); + filterrelationname = MessageFormat.format(filterrelationname, UUIDUtils.toString(profile.getID())); discoverQuery.addFilterQueries(filterrelationname); discoverQuery.setMaxResults(1); return new DiscoverResultItemIterator(context, discoverQuery); From 28cc8844e4deb79584993b4669e191d0e9becdf7 Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Fri, 25 Aug 2023 18:59:48 +0200 Subject: [PATCH 13/20] refactor deletion of orcidqueue entries among relationships use database-approach instead of solr because the values might not be indexed/remodev when the orcidconsumer interacts; simplify configuration to name of relationship instead of filter; some fixes and tests --- ...RelationshipPlacesIndexingServiceImpl.java | 14 ++- .../orcid/consumer/OrcidQueueConsumer.java | 15 ++- .../service/OrcidSynchronizationService.java | 12 ++ .../service/impl/OrcidQueueServiceImpl.java | 26 ++-- .../impl/OrcidSynchronizationServiceImpl.java | 79 ++++++++++-- .../dspace/orcid/OrcidQueueConsumerIT.java | 118 ++++++++++++++---- dspace/config/modules/orcid.cfg | 22 ++-- 7 files changed, 230 insertions(+), 56 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/content/RelationshipPlacesIndexingServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/RelationshipPlacesIndexingServiceImpl.java index 1ed14b4fbe1f..42e4dfd5b0a1 100644 --- a/dspace-api/src/main/java/org/dspace/content/RelationshipPlacesIndexingServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/RelationshipPlacesIndexingServiceImpl.java @@ -55,7 +55,9 @@ public void updateRelationReferences(final Context context, final Relationship r if (singleDirectionRelationship("right", relationship.getRelationshipType())) { times = relation.getLeftPlace() - relation.getRightPlace(); } - rightItemsIdsToAdd.addAll(Collections.nCopies(times, relation.getRightItem().getID().toString())); + if (times > 0) { + rightItemsIdsToAdd.addAll(Collections.nCopies(times, relation.getRightItem().getID().toString())); + } } if (!rightItemsIdsToAdd.isEmpty()) { @@ -79,7 +81,9 @@ public void updateRelationReferences(final Context context, final Relationship r if (singleDirectionRelationship("left", relationship.getRelationshipType())) { times = relation.getRightPlace() - relation.getLeftPlace(); } - leftItemsIdsToAdd.addAll(Collections.nCopies(times, relation.getLeftItem().getID().toString())); + if (times > 0) { + leftItemsIdsToAdd.addAll(Collections.nCopies(times, relation.getLeftItem().getID().toString())); + } } if (!leftItemsIdsToAdd.isEmpty()) { @@ -102,7 +106,9 @@ private void addRightItemsReferences(final Context context, final Relationship r if (singleDirectionRelationship("right", relationship.getRelationshipType())) { times = leftItemRelation.getLeftPlace() - leftItemRelation.getRightPlace(); } + if (times > 0) { rightItemsToAdd.addAll(Collections.nCopies(times, leftItemRelation.getRightItem().getID().toString())); + } } if (!rightItemsToAdd.isEmpty()) { indexingService.updateRelationForItem(leftItem.getID().toString(), @@ -122,7 +128,9 @@ private void addLeftItemsReferences(final Context context, final Relationship re if (singleDirectionRelationship("left", relationship.getRelationshipType())) { times = leftItemRelation.getRightPlace() - leftItemRelation.getLeftPlace(); } - rightItemsToAdd.addAll(Collections.nCopies(times, leftItemRelation.getLeftItem().getID().toString())); + if (times > 0) { + rightItemsToAdd.addAll(Collections.nCopies(times, leftItemRelation.getLeftItem().getID().toString())); + } } if (!rightItemsToAdd.isEmpty()) { indexingService.updateRelationForItem(rightItem.getID().toString(), diff --git a/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java b/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java index d70ecd87918e..864ddcf4927d 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java +++ b/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java @@ -161,9 +161,12 @@ private void consumeEntity(Context context, Item entity) throws SQLException { if (shouldNotBeSynchronized(context, relatedItem, entity) || isAlreadyQueued(context, relatedItem, entity)) { - // delete queue entries which are queued but which should not be synchronized anymore - if (isAlreadyQueued(context, relatedItem, entity) && - shouldNotBeSynchronized(context, relatedItem, entity)) { + // delete queue entries which are queued and relate on relationships, + // but where the relation does not exist anymore. + // Using the shouldNotBySynchonized might not be actual, because the solr + // might be behind the database state + if (isAlreadyQueued(context, relatedItem, entity) + && isSyncSettingsBasedOnRelationshipCriteriaNotValid(context, relatedItem, entity)) { List queueentries = orcidQueueService.findByProfileItemAndEntity(context, relatedItem, entity); for (OrcidQueue queueentry : queueentries) { @@ -304,6 +307,12 @@ private boolean shouldNotBeSynchronized(Context context, Item profileItem, Item return !orcidSynchronizationService.isSynchronizationAllowed(context, profileItem, entity); } + private boolean isSyncSettingsBasedOnRelationshipCriteriaNotValid( + Context context, Item profileItem, Item entity) { + return orcidSynchronizationService. + isSyncSettingsBasedOnRelationshipCriteriaNotValid(context, profileItem, entity); + } + private boolean isNotProfileItem(Item profileItemItem) { return !getProfileType().equals(itemService.getEntityTypeLabel(profileItemItem)); } diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/OrcidSynchronizationService.java b/dspace-api/src/main/java/org/dspace/orcid/service/OrcidSynchronizationService.java index 49b6ecf54442..8715288c1bac 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/OrcidSynchronizationService.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/OrcidSynchronizationService.java @@ -130,6 +130,18 @@ public boolean setSynchronizationMode(Context context, Item profile, OrcidSynchr */ Optional getSynchronizationMode(Item profile); + /** + * Check if the current sync setting for the items is related to some relationship. + * And if so than check if the relationship criteria is not valid. + * + * @param profile the researcher profile item + * @param item the entity type to check + * @return true if the given entity type is bases on relationship + * false otherwise + */ + boolean isSyncSettingsBasedOnRelationshipCriteriaNotValid(Context context, Item profile, Item item); + + /** * Returns the ORCID synchronization preference related to the given entity type * configured for the given profile item. diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java index 0304caf7de36..640ee1f26ccb 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java @@ -13,7 +13,6 @@ import static org.dspace.profile.OrcidEntitySyncPreference.MY_SELECTED; import java.sql.SQLException; -import java.text.MessageFormat; import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -38,7 +37,6 @@ import org.dspace.orcid.service.OrcidQueueService; import org.dspace.profile.OrcidEntitySyncPreference; import org.dspace.services.ConfigurationService; -import org.dspace.util.UUIDUtils; import org.springframework.beans.factory.annotation.Autowired; /** @@ -226,13 +224,16 @@ public void recalculateOrcidQueue(Context context, Item profileItem, OrcidEntity // delete existing queue deleteByProfileItemAndRecordType(context, profileItem, entityType); // add additional filterquery - String filterrelationname = configurationService.getProperty("orcid.relationpreference." + - entityType + "." + preference.name()); - if (StringUtils.isBlank(filterrelationname)) { + String relationname = + configurationService.getProperty("orcid.relation." + entityType + "." + preference.name()); + boolean exclusion = configurationService.getBooleanProperty("orcid.relation." + + entityType + "." + preference.name() + ".exclusion", false); + if (StringUtils.isBlank(relationname)) { return; } Iterator entities; - entities = findAllRelationShipEntitiesLinkableWith(context, profileItem, entityType, filterrelationname); + entities = findAllRelationShipEntitiesLinkableWith(context, profileItem, entityType, relationname, + exclusion); while (entities.hasNext()) { create(context, profileItem, entities.next()); } @@ -269,7 +270,7 @@ private Iterator findAllEntitiesLinkableWith(Context context, Item owner, } private Iterator findAllRelationShipEntitiesLinkableWith( - Context context, Item owner, String entityType, String filterrelationname) { + Context context, Item owner, String entityType, String filterrelationname, boolean exclusion) { String ownerType = itemService.getEntityType(owner); @@ -283,14 +284,19 @@ private Iterator findAllRelationShipEntitiesLinkableWith( return Collections.emptyIterator(); } + StringBuilder sb = new StringBuilder(); + if (exclusion) { + sb.append("-"); + } + sb.append("relation." + filterrelationname + ":"); + sb.append(owner.getID().toString()); + DiscoverQuery discoverQuery = new DiscoverQuery(); discoverQuery.addDSpaceObjectFilter(IndexableItem.TYPE); discoverQuery.addFilterQueries(query); discoverQuery.addFilterQueries("search.entitytype:" + entityType); - filterrelationname = MessageFormat.format(filterrelationname, UUIDUtils.toString(owner.getID())); - discoverQuery.addFilterQueries(filterrelationname); - + discoverQuery.addFilterQueries(sb.toString()); return new DiscoverResultItemIterator(context, discoverQuery); diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java index 89f2fb747057..bbbf99b9c09f 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java @@ -17,7 +17,6 @@ import static org.dspace.content.Item.ANY; import java.sql.SQLException; -import java.text.MessageFormat; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -29,7 +28,9 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.content.Item; import org.dspace.content.MetadataValue; +import org.dspace.content.Relationship; import org.dspace.content.service.ItemService; +import org.dspace.content.service.RelationshipService; import org.dspace.core.Context; import org.dspace.discovery.DiscoverQuery; import org.dspace.discovery.DiscoverResultItemIterator; @@ -50,7 +51,6 @@ import org.dspace.profile.OrcidSynchronizationMode; import org.dspace.profile.service.ResearcherProfileService; import org.dspace.services.ConfigurationService; -import org.dspace.util.UUIDUtils; import org.springframework.beans.factory.annotation.Autowired; /** @@ -82,6 +82,9 @@ public class OrcidSynchronizationServiceImpl implements OrcidSynchronizationServ @Autowired private ResearcherProfileService researcherProfileService; + @Autowired + private RelationshipService relationshipService; + @Override public void linkProfile(Context context, Item profile, OrcidTokenResponseDTO token) throws SQLException { @@ -204,12 +207,14 @@ public boolean isSynchronizationAllowed(Context context, Item profile, Item item return true; case MINE: case MY_SELECTED: - String filterproperty = "orcid.relationpreference." + entityType + "." + option.get().name(); - String filter = configurationService.getProperty(filterproperty); - if (isBlank(filter) || !filter.contains("{0}")) { + String relationname = configurationService.getProperty( + "orcid.relation." + entityType + "." + option.get().name()); + boolean exclusion = configurationService.getBooleanProperty("orcid.relation." + + entityType + "." + option.get().name() + ".exclusion", false); + if (isBlank(relationname)) { return false; } - Iterator entities = checkRelation(context, profile, item, filter); + Iterator entities = checkRelation(context, profile, item, relationname, exclusion); if (entities.hasNext()) { return true; } else { @@ -231,12 +236,68 @@ public boolean isSynchronizationAllowed(Context context, Item profile, Item item } - private Iterator checkRelation(Context context, Item profile, Item item, String filterrelationname) { + @Override + public boolean isSyncSettingsBasedOnRelationshipCriteriaNotValid(Context context, Item profile, Item item) { + String entityType = itemService.getEntityTypeLabel(item); + if (entityType == null) { + return false; + } + Optional option = + getEntityPreference(profile, OrcidEntityType.fromEntityType(entityType)); + if (option.isPresent()) { + try { + switch (option.get()) { + case MINE: + case MY_SELECTED: + // Consider MINE and MY_SELECTED Settings + String relationname = configurationService.getProperty( + "orcid.relation." + entityType + "." + option.get().name()); + if (isBlank(relationname)) { + return false; + } + boolean exclusion = configurationService.getBooleanProperty("orcid.relation." + + entityType + "." + option.get().name() + ".exclusion", false); + if (exclusion) { + //check, if relationship exists + List rels = relationshipService.findByItem(context, profile); + boolean val = rels.stream() + .anyMatch(relationship -> + relationship.getLeftItem().getID().toString().equals(item.getID().toString()) && + relationship.getLeftwardValue().contentEquals(relationname)); + return val; + } else { + //check if no relationship exists + List rels = relationshipService.findByItem(context, profile); + boolean val = rels.stream() + .noneMatch(relationship -> + relationship.getLeftItem().getID().toString().equals(item.getID().toString()) && + relationship.getLeftwardValue().contentEquals(relationname)); + return val; + } + + default: + return false; + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + return false; + } + + private Iterator checkRelation(Context context, Item profile, Item item, String filterrelationname, + boolean exclusion) { + StringBuilder sb = new StringBuilder(); + if (exclusion) { + sb.append("-"); + } + sb.append("relation." + filterrelationname + ":"); + sb.append(profile.getID().toString()); + DiscoverQuery discoverQuery = new DiscoverQuery(); discoverQuery.setDSpaceObjectFilter(IndexableItem.TYPE); discoverQuery.addFilterQueries("search.resourceid:" + item.getID()); - filterrelationname = MessageFormat.format(filterrelationname, UUIDUtils.toString(profile.getID())); - discoverQuery.addFilterQueries(filterrelationname); + discoverQuery.addFilterQueries(sb.toString()); discoverQuery.setMaxResults(1); return new DiscoverResultItemIterator(context, discoverQuery); } diff --git a/dspace-api/src/test/java/org/dspace/orcid/OrcidQueueConsumerIT.java b/dspace-api/src/test/java/org/dspace/orcid/OrcidQueueConsumerIT.java index 4fbc509b8013..e8b1e1773526 100644 --- a/dspace-api/src/test/java/org/dspace/orcid/OrcidQueueConsumerIT.java +++ b/dspace-api/src/test/java/org/dspace/orcid/OrcidQueueConsumerIT.java @@ -488,8 +488,8 @@ public void testOrcidQueueRecordCreationForPublicationRelationMySELECTED() throw context.turnOffAuthorisationSystem(); - configurationService.addPropertyValue("orcid.relationpreference.Publication.MY_SELECTED", - "relation.isResearchoutputsSelectedFor:{0}"); + configurationService.addPropertyValue("orcid.relation.Publication.MY_SELECTED", + "isResearchoutputsSelectedFor"); Item profile = ItemBuilder.createItem(context, profileCollection) .withTitle("Test User") @@ -522,7 +522,8 @@ public void testOrcidQueueRecordCreationForPublicationRelationMySELECTED() throw "hasSelectedResearchoutputs", 0, null, 0, null).build(); - RelationshipBuilder.createRelationshipBuilder(context, publication, profile, SelectedType).build(); + RelationshipBuilder.createRelationshipBuilder(context, publication, profile, SelectedType) + .withLeftwardValue("isResearchoutputsSelectedFor").build(); context.restoreAuthSystemState(); context.commit(); @@ -544,7 +545,7 @@ public void testOrcidQueueRecordCreationForPublicationRelationMySELECTED() throw context.turnOffAuthorisationSystem(); Relationship secondrelselected = RelationshipBuilder.createRelationshipBuilder(context, secondpublication, profile, SelectedType) - .build(); + .withLeftwardValue("isResearchoutputsSelectedFor").build(); context.restoreAuthSystemState(); context.commit(); @@ -569,7 +570,7 @@ public void testOrcidQueueRecordCreationForPublicationRelationMySELECTED() throw public void testNoOrcidQueueRecordCreationForPublicationIfRelationMYSELECTEDIsNotConfigured() throws Exception { context.turnOffAuthorisationSystem(); - configurationService.setProperty("orcid.relationpreference.Publication.MY_SELECTED", null); + configurationService.setProperty("orcid.relation.Publication.MY_SELECTED", null); Item profile = ItemBuilder.createItem(context, profileCollection) .withTitle("Test User") .withOrcidIdentifier("0000-1111-2222-3333") @@ -596,8 +597,10 @@ public void testNoOrcidQueueRecordCreationForPublicationIfRelationMYSELECTEDIsNo "hasSelectedResearchoutputs", 0, null, 0, null).build(); - RelationshipBuilder.createRelationshipBuilder(context, publication, profile, SelectedType).build(); - RelationshipBuilder.createRelationshipBuilder(context, secondpublication, profile, SelectedType).build(); + RelationshipBuilder.createRelationshipBuilder(context, publication, profile, SelectedType) + .withLeftwardValue("isResearchoutputsSelectedFor").build(); + RelationshipBuilder.createRelationshipBuilder(context, secondpublication, profile, SelectedType) + .withLeftwardValue("isResearchoutputsSelectedFor").build(); context.restoreAuthSystemState(); context.commit(); @@ -614,11 +617,11 @@ public void testNoOrcidQueueRecordCreationForPublicationIfRelationMYSELECTEDIsNo } @Test - public void testNoOrcidQueueRecordCreationForPublicationIfRelationMYSELECTEDQueryHasNoProfile() throws Exception { + public void testNoOrcidQueueRecordCreationForPublicationIfRelationMYSELECTEDQueryIsDifferent() throws Exception { context.turnOffAuthorisationSystem(); - configurationService.setProperty("orcid.relationpreference.Publication.MY_SELECTED", - "isResearchoutputsSelectedFor"); + configurationService.setProperty("orcid.relation.Publication.MY_SELECTED", + "isSomeOtherRelationSelectedFor"); Item profile = ItemBuilder.createItem(context, profileCollection) .withTitle("Test User") .withOrcidIdentifier("0000-1111-2222-3333") @@ -645,11 +648,13 @@ public void testNoOrcidQueueRecordCreationForPublicationIfRelationMYSELECTEDQuer "hasSelectedResearchoutputs", 0, null, 0, null).build(); - RelationshipBuilder.createRelationshipBuilder(context, publication, profile, SelectedType).build(); - RelationshipBuilder.createRelationshipBuilder(context, secondpublication, profile, SelectedType).build(); + RelationshipBuilder.createRelationshipBuilder(context, publication, profile, SelectedType) + .withLeftwardValue("isResearchoutputsSelectedFor").build(); + RelationshipBuilder.createRelationshipBuilder(context, secondpublication, profile, SelectedType) + .withLeftwardValue("isResearchoutputsSelectedFor").build(); - context.restoreAuthSystemState(); context.commit(); + context.restoreAuthSystemState(); List orcidQueueRecords = orcidQueueService.findAll(context); assertThat(orcidQueueRecords, hasSize(0)); @@ -694,8 +699,10 @@ public void testOrcidQueueRecordCreationForPublicationRelationMINE() throws Exce "notDisplayingResearchoutputs", 0, null, 0, null).build(); - RelationshipBuilder.createRelationshipBuilder(context, publication, profile, SelectedType).build(); - RelationshipBuilder.createRelationshipBuilder(context, secondpublication, profile, HiddenType).build(); + RelationshipBuilder.createRelationshipBuilder(context, publication, profile, SelectedType) + .withLeftwardValue("isResearchoutputsSelectedFor").build(); + RelationshipBuilder.createRelationshipBuilder(context, secondpublication, profile, HiddenType) + .withLeftwardValue("isResearchoutputsHiddenFor").build(); context.restoreAuthSystemState(); context.commit(); @@ -718,9 +725,10 @@ public void testOrcidQueueRecordCreationForPublicationRelationMINE() throws Exce context.turnOffAuthorisationSystem(); Relationship relbeingdeleted = - RelationshipBuilder.createRelationshipBuilder(context, thirdpublication, profile, HiddenType).build(); - context.restoreAuthSystemState(); + RelationshipBuilder.createRelationshipBuilder(context, thirdpublication, profile, HiddenType) + .withLeftwardValue("isResearchoutputsHiddenFor").build(); context.commit(); + context.restoreAuthSystemState(); List newcreationQueueRecords = orcidQueueService.findAll(context); assertThat(newcreationQueueRecords, hasSize(1)); @@ -769,8 +777,59 @@ public void testNoOrcidQueueRecordCreationForPublicationRelationMineIfAllAreHidd "notDisplayingResearchoutputs", 0, null, 0, null).build(); - RelationshipBuilder.createRelationshipBuilder(context, publication, profile, HiddenType).build(); - RelationshipBuilder.createRelationshipBuilder(context, secondpublication, profile, HiddenType).build(); + RelationshipBuilder.createRelationshipBuilder(context, publication, profile, HiddenType) + .withLeftwardValue("isResearchoutputsHiddenFor").build(); + RelationshipBuilder.createRelationshipBuilder(context, secondpublication, profile, HiddenType) + .withLeftwardValue("isResearchoutputsHiddenFor").build(); + context.commit(); + context.restoreAuthSystemState(); + + List orcidQueueRecords = orcidQueueService.findAll(context); + assertThat(orcidQueueRecords, hasSize(0)); + + addMetadata(publication, "dc", "contributor", "editor", "Editor", null); + addMetadata(secondpublication, "dc", "contributor", "editor", "Editor", null); + context.commit(); + + List newOrcidQueueRecords = orcidQueueService.findAll(context); + assertThat(newOrcidQueueRecords, hasSize(0)); + } + + @Test + public void testNoOrcidQueueRecordCreationForPublicationRelationMineIfOneDeleted() throws Exception { + + context.turnOffAuthorisationSystem(); + Item profile = ItemBuilder.createItem(context, profileCollection) + .withTitle("Test User") + .withOrcidIdentifier("0000-1111-2222-3333") + .withOrcidAccessToken("ab4d18a0-8d9a-40f1-b601-a417255c8d20", eperson) + .withOrcidSynchronizationPublicationsPreference(MINE) + .build(); + + Collection publicationCollection = createCollection("Publications", "Publication"); + + Item publication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication") + .withAuthor("Test User", profile.getID().toString()) + .build(); + + Item secondpublication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication 2") + .withAuthor("Test User", profile.getID().toString()) + .build(); + + EntityType personType = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); + + RelationshipType HiddenType = RelationshipTypeBuilder + .createRelationshipTypeBuilder(context, null, personType, "isResearchoutputsHiddenFor", + "notDisplayingResearchoutputs", 0, null, 0, + null).build(); + + RelationshipBuilder.createRelationshipBuilder(context, publication, profile, HiddenType) + .withLeftwardValue("isResearchoutputsHiddenFor").build(); + Relationship hiddenbeingdeleted = + RelationshipBuilder.createRelationshipBuilder(context, secondpublication, profile, HiddenType) + .withLeftwardValue("isResearchoutputsHiddenFor").build(); context.restoreAuthSystemState(); context.commit(); @@ -780,10 +839,21 @@ public void testNoOrcidQueueRecordCreationForPublicationRelationMineIfAllAreHidd addMetadata(publication, "dc", "contributor", "editor", "Editor", null); addMetadata(secondpublication, "dc", "contributor", "editor", "Editor", null); - context.commit(); + List newOrcidQueueRecords = orcidQueueService.findAll(context); assertThat(newOrcidQueueRecords, hasSize(0)); + + context.commit(); + context.turnOffAuthorisationSystem(); + RelationshipBuilder.deleteRelationship(hiddenbeingdeleted.getID()); + itemService.update(context,secondpublication); + + context.commit(); + context.restoreAuthSystemState(); + + List newafterdeletionOrcidQueueRecords = orcidQueueService.findAll(context); + assertThat(newafterdeletionOrcidQueueRecords, hasSize(1)); } @Test @@ -863,8 +933,10 @@ public void testOrcidQueueRecalculationForChangedPublicationRelationSettings() t "hasSelectedResearchoutputs", 0, null, 0, null).build(); - RelationshipBuilder.createRelationshipBuilder(context, publication, profile, HiddenType).build(); - RelationshipBuilder.createRelationshipBuilder(context, secondpublication, profile, SelectedType).build(); + RelationshipBuilder.createRelationshipBuilder(context, publication, profile, HiddenType) + .withLeftwardValue("isResearchoutputsHiddenFor").build(); + RelationshipBuilder.createRelationshipBuilder(context, secondpublication, profile, SelectedType) + .withLeftwardValue("isResearchoutputsSelectedFor").build(); context.restoreAuthSystemState(); context.commit(); @@ -1415,7 +1487,7 @@ private void changeProfilePublicationSyncPreference(Item profile, OrcidEntitySyn throws SQLException { context.turnOffAuthorisationSystem(); orcidQueueService.recalculateOrcidQueue(context, profile, OrcidEntityType.PUBLICATION, preference); - context.restoreAuthSystemState(); context.commit(); + context.restoreAuthSystemState(); } } diff --git a/dspace/config/modules/orcid.cfg b/dspace/config/modules/orcid.cfg index 2a952da8fb64..8de206e6c4e6 100644 --- a/dspace/config/modules/orcid.cfg +++ b/dspace/config/modules/orcid.cfg @@ -48,17 +48,23 @@ orcid.scope = /activities/update orcid.scope = /person/update #------------------------------------------------------------------# -#---------------------ORCID RELATIONPREFERENCES -------------------# +#--------------------------- ORCID RELATION -----------------------# #------------------------------------------------------------------# -# This allows to push certains relations and their preferences as MINE and MY_SELECTED settigns on entities +# This allows to push certains relations and their sync preferences as MINE and MY_SELECTED settings on entities # e.g. MY_SELECTED pushes only selected publications of some user # e.g. MINE pushes all publications of some user but not hidden ones -# The Relation must be configured and it's checked by some solr query with {0} containing the id of the profile -# orcid.relationpreference..: :{0} -#orcid.relationpreference.Funding.MINE = -relation.isProjectsHiddenFor:{0} -#orcid.relationpreference.Funding.MY_SELECTED = relation.isProjectsSelectedFor:{0} -orcid.relationpreference.Publication.MINE = -relation.isResearchoutputsHiddenFor:{0} -orcid.relationpreference.Publication.MY_SELECTED = relation.isResearchoutputsSelectedFor:{0} +# The Relation must be configured between the item entity type and the profile entity type +# It's checked by some solr query while recalculating the orcid queue when changing the setting and +# it's checked by the orcid consumer wnhen some relation is being removed if the orcid queue entry is still valid. +# orcid.relation..: - usually Person.. +# orcid.relation...exclusion: add some check to check, if the relation dies not exist +#orcid.relation.Funding.MINE = isProjectsHiddenFor +#orcid.relation.Funding.MINE.exclusion = true +#orcid.relation.Funding.MY_SELECTED = isProjectsSelectedFor +# +orcid.relation.Publication.MINE = isResearchoutputsHiddenFor +orcid.relation.Publication.MINE.exclusion = true +orcid.relation.Publication.MY_SELECTED = isResearchoutputsSelectedFor #------------------------------------------------------------------# #--------------------ORCID MAPPING CONFIGURATIONS------------------# From e7d4bc1e3f7f57af49e1e8bca3605b13c141912e Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Fri, 25 Aug 2023 19:17:22 +0200 Subject: [PATCH 14/20] fix checkstyle --- .../dspace/content/RelationshipPlacesIndexingServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/content/RelationshipPlacesIndexingServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/RelationshipPlacesIndexingServiceImpl.java index 42e4dfd5b0a1..f29e209d7790 100644 --- a/dspace-api/src/main/java/org/dspace/content/RelationshipPlacesIndexingServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/RelationshipPlacesIndexingServiceImpl.java @@ -107,7 +107,7 @@ private void addRightItemsReferences(final Context context, final Relationship r times = leftItemRelation.getLeftPlace() - leftItemRelation.getRightPlace(); } if (times > 0) { - rightItemsToAdd.addAll(Collections.nCopies(times, leftItemRelation.getRightItem().getID().toString())); + rightItemsToAdd.addAll(Collections.nCopies(times, leftItemRelation.getRightItem().getID().toString())); } } if (!rightItemsToAdd.isEmpty()) { From 6b9c478d43c873fbd62f914d621f0b5e3ee5129b Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Fri, 25 Aug 2023 19:18:16 +0200 Subject: [PATCH 15/20] enable config for funding --- dspace/config/modules/orcid.cfg | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dspace/config/modules/orcid.cfg b/dspace/config/modules/orcid.cfg index 8de206e6c4e6..142ace838e68 100644 --- a/dspace/config/modules/orcid.cfg +++ b/dspace/config/modules/orcid.cfg @@ -65,6 +65,9 @@ orcid.scope = /person/update orcid.relation.Publication.MINE = isResearchoutputsHiddenFor orcid.relation.Publication.MINE.exclusion = true orcid.relation.Publication.MY_SELECTED = isResearchoutputsSelectedFor +orcid.relation.Funding.MINE = isProjectsHiddenFor +orcid.relation.Funding.MINE.exclusion = true +orcid.relation.Funding.MY_SELECTED = isProjectsSelectedFor #------------------------------------------------------------------# #--------------------ORCID MAPPING CONFIGURATIONS------------------# From b2fad1a75a1f12b4f233a5cd83a4e004d52b5c13 Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Mon, 28 Aug 2023 10:35:41 +0200 Subject: [PATCH 16/20] fix wrong config property breaking tests --- dspace/config/local.cfg.EXAMPLE | 2 +- dspace/config/modules/rest.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace/config/local.cfg.EXAMPLE b/dspace/config/local.cfg.EXAMPLE index 78f5bad26770..e0a1bed1fbb2 100644 --- a/dspace/config/local.cfg.EXAMPLE +++ b/dspace/config/local.cfg.EXAMPLE @@ -243,7 +243,7 @@ db.schema = public # avoid trouble for such browsers (i.e. rest.cors.allowed-origins = ${dspace.ui.url}, https://samltest.id ) #rest.cors.allowed-origins = ${dspace.ui.url} -#rest.cors.bitstream-allowed-origins = ${dspace.ui.url} +#rest.cors.bitstream-allow-origins = ${dspace.ui.url} ################################################# # SPRING BOOT SETTINGS (Used by Server Webapp) # diff --git a/dspace/config/modules/rest.cfg b/dspace/config/modules/rest.cfg index 9d2eb77be2cc..76abcb619528 100644 --- a/dspace/config/modules/rest.cfg +++ b/dspace/config/modules/rest.cfg @@ -134,7 +134,7 @@ rest.regex-clause = text_value ~ ? ##### Customize the REST origins allowed to retrieve the bitstreams ##### ##### default is set to pattern * - use this configuration to restrict/modify this behavior ##### This configuration doens't support the wildcard -bitstream.cors.allowed-origins = +rest.cors.bitstream-allow-origins = ##### Configure REST Report Filters ##### From 6920c38b37efcafa4cb64da28d36e81c02a1629d Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Thu, 9 Nov 2023 15:58:57 +0100 Subject: [PATCH 17/20] use relationship approach for orcid sync setting check if relationship exist using the relationshipservice rather than the search, becaude the requested item might not have been indexed yet if it is recent archived --- .../impl/OrcidSynchronizationServiceImpl.java | 99 +++++++++---------- 1 file changed, 45 insertions(+), 54 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java index bbbf99b9c09f..d309427f12ed 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java @@ -28,7 +28,6 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.content.Item; import org.dspace.content.MetadataValue; -import org.dspace.content.Relationship; import org.dspace.content.service.ItemService; import org.dspace.content.service.RelationshipService; import org.dspace.core.Context; @@ -200,28 +199,34 @@ public boolean isSynchronizationAllowed(Context context, Item profile, Item item Optional option; option = getEntityPreference(profile, OrcidEntityType.fromEntityType(entityType)); if (option.isPresent()) { - switch (option.get()) { - case DISABLED: - return false; - case ALL: - return true; - case MINE: - case MY_SELECTED: - String relationname = configurationService.getProperty( - "orcid.relation." + entityType + "." + option.get().name()); - boolean exclusion = configurationService.getBooleanProperty("orcid.relation." - + entityType + "." + option.get().name() + ".exclusion", false); - if (isBlank(relationname)) { + try { + switch (option.get()) { + case DISABLED: return false; - } - Iterator entities = checkRelation(context, profile, item, relationname, exclusion); - if (entities.hasNext()) { + case ALL: return true; - } else { + case MINE: + case MY_SELECTED: + String relationname = configurationService.getProperty("orcid.relation." + entityType + "." + + option.get().name()); + if (isBlank(relationname)) { + return false; + } + if (configurationService.getBooleanProperty("orcid.relation." + entityType + "." + + option.get().name() + ".exclusion", false)) { + //check if no relationship exists between profile and item (e.g. MINE) + return relationShipMatchForOrcidSync(context, profile, item, relationname, false); + } else { + //check, if any relationship exists between profile and item(e.g. MY_SELECTED) + + return relationShipMatchForOrcidSync(context, profile, item, relationname, true); + + } + default: return false; - } - default: - return false; + } + } catch (SQLException e) { + throw new RuntimeException(e); } } else { return false; @@ -249,30 +254,20 @@ public boolean isSyncSettingsBasedOnRelationshipCriteriaNotValid(Context context switch (option.get()) { case MINE: case MY_SELECTED: - // Consider MINE and MY_SELECTED Settings - String relationname = configurationService.getProperty( - "orcid.relation." + entityType + "." + option.get().name()); + String relationname = configurationService.getProperty("orcid.relation." + entityType + "." + + option.get().name()); if (isBlank(relationname)) { return false; } - boolean exclusion = configurationService.getBooleanProperty("orcid.relation." - + entityType + "." + option.get().name() + ".exclusion", false); - if (exclusion) { - //check, if relationship exists - List rels = relationshipService.findByItem(context, profile); - boolean val = rels.stream() - .anyMatch(relationship -> - relationship.getLeftItem().getID().toString().equals(item.getID().toString()) && - relationship.getLeftwardValue().contentEquals(relationname)); - return val; + + //because we check the criteria is not valid we have to check the opposite + if (configurationService.getBooleanProperty("orcid.relation." + entityType + "." + + option.get().name() + ".exclusion", false)) { + //check, if any relationship exists between profile and item (e.g. MINE) + return relationShipMatchForOrcidSync(context, profile, item, relationname, true); } else { - //check if no relationship exists - List rels = relationshipService.findByItem(context, profile); - boolean val = rels.stream() - .noneMatch(relationship -> - relationship.getLeftItem().getID().toString().equals(item.getID().toString()) && - relationship.getLeftwardValue().contentEquals(relationname)); - return val; + //check if none relationship exist between profile and item (e.g. MY_SELECT) + return relationShipMatchForOrcidSync(context, profile, item, relationname, false); } default: @@ -285,21 +280,17 @@ public boolean isSyncSettingsBasedOnRelationshipCriteriaNotValid(Context context return false; } - private Iterator checkRelation(Context context, Item profile, Item item, String filterrelationname, - boolean exclusion) { - StringBuilder sb = new StringBuilder(); - if (exclusion) { - sb.append("-"); + protected boolean relationShipMatchForOrcidSync(Context context, Item profile, Item item, String relationname, + boolean any) throws SQLException { + if (any) { + return relationshipService.findByItem(context, profile).stream().anyMatch(relationship -> + relationship.getLeftItem().getID().toString().equals(item.getID().toString()) && + relationship.getLeftwardValue().contentEquals(relationname)); + } else { + return relationshipService.findByItem(context, profile).stream().noneMatch(relationship -> + relationship.getLeftItem().getID().toString().equals(item.getID().toString()) && + relationship.getLeftwardValue().contentEquals(relationname)); } - sb.append("relation." + filterrelationname + ":"); - sb.append(profile.getID().toString()); - - DiscoverQuery discoverQuery = new DiscoverQuery(); - discoverQuery.setDSpaceObjectFilter(IndexableItem.TYPE); - discoverQuery.addFilterQueries("search.resourceid:" + item.getID()); - discoverQuery.addFilterQueries(sb.toString()); - discoverQuery.setMaxResults(1); - return new DiscoverResultItemIterator(context, discoverQuery); } @Override From d8c31e360e51a70e819178191ad043239c834d60 Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Wed, 20 Dec 2023 12:33:16 +0100 Subject: [PATCH 18/20] clear orcid queue before recalculating all option --- .../org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java index 640ee1f26ccb..078d8a67eaa6 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java @@ -238,6 +238,7 @@ public void recalculateOrcidQueue(Context context, Item profileItem, OrcidEntity create(context, profileItem, entities.next()); } } else { + deleteByProfileItemAndRecordType(context, profileItem, entityType); Iterator entities = findAllEntitiesLinkableWith(context, profileItem, entityType); while (entities.hasNext()) { create(context, profileItem, entities.next()); From 8f624499ea90ef87ae740070ac6de0935028f1af Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Tue, 20 Feb 2024 14:53:11 +0100 Subject: [PATCH 19/20] fix integration test with orcidqueueconsumer --- .../dspace/orcid/OrcidQueueConsumerIT.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/orcid/OrcidQueueConsumerIT.java b/dspace-api/src/test/java/org/dspace/orcid/OrcidQueueConsumerIT.java index 78c7ee44cc1d..2d4521de347d 100644 --- a/dspace-api/src/test/java/org/dspace/orcid/OrcidQueueConsumerIT.java +++ b/dspace-api/src/test/java/org/dspace/orcid/OrcidQueueConsumerIT.java @@ -565,9 +565,9 @@ public void testOrcidQueueRecordCreationForPublicationRelationMySELECTED() throw List newaftercreationOrcidQueueRecords = orcidQueueService.findAll(context); assertThat(newaftercreationOrcidQueueRecords, hasSize(2)); - assertThat(newaftercreationOrcidQueueRecords.get(0), matches(profile, publication, "Publication", INSERT)); - assertThat(newaftercreationOrcidQueueRecords.get(1), matches(profile, secondpublication, - "Publication", INSERT)); + assertThat(newaftercreationOrcidQueueRecords, hasItem(matches(profile, publication, "Publication", INSERT))); + assertThat(newaftercreationOrcidQueueRecords, hasItem(matches(profile, secondpublication, + "Publication", INSERT))); context.turnOffAuthorisationSystem(); RelationshipBuilder.deleteRelationship(secondrelselected.getID()); @@ -723,8 +723,8 @@ public void testOrcidQueueRecordCreationForPublicationRelationMINE() throws Exce List orcidQueueRecords = orcidQueueService.findAll(context); assertThat(orcidQueueRecords, hasSize(2)); - assertThat(orcidQueueRecords.get(0), matches(profile, thirdpublication, "Publication", INSERT)); - assertThat(orcidQueueRecords.get(1), matches(profile, publication, "Publication", INSERT)); + assertThat(orcidQueueRecords, hasItem(matches(profile, thirdpublication, "Publication", INSERT))); + assertThat(orcidQueueRecords, hasItem(matches(profile, publication, "Publication", INSERT))); addMetadata(publication, "dc", "contributor", "editor", "Editor", null); addMetadata(secondpublication, "dc", "contributor", "editor", "Editor", null); @@ -734,8 +734,8 @@ public void testOrcidQueueRecordCreationForPublicationRelationMINE() throws Exce List newOrcidQueueRecords = orcidQueueService.findAll(context); assertThat(newOrcidQueueRecords, hasSize(2)); - assertThat(orcidQueueRecords.get(0), equalTo(newOrcidQueueRecords.get(0))); - assertThat(orcidQueueRecords.get(1), equalTo(newOrcidQueueRecords.get(1))); + assertThat(orcidQueueRecords, hasItem(equalTo(newOrcidQueueRecords.get(0)))); + assertThat(orcidQueueRecords, hasItem(equalTo(newOrcidQueueRecords.get(1)))); context.turnOffAuthorisationSystem(); Relationship relbeingdeleted = @@ -757,8 +757,8 @@ public void testOrcidQueueRecordCreationForPublicationRelationMINE() throws Exce List newafterdeletionQueueRecords = orcidQueueService.findAll(context); assertThat(newafterdeletionQueueRecords, hasSize(2)); - assertThat(newafterdeletionQueueRecords.get(0), matches(profile, publication, "Publication", INSERT)); - assertThat(newafterdeletionQueueRecords.get(1), matches(profile, thirdpublication, "Publication", INSERT)); + assertThat(newafterdeletionQueueRecords, hasItem(matches(profile, publication, "Publication", INSERT))); + assertThat(newafterdeletionQueueRecords, hasItem(matches(profile, thirdpublication, "Publication", INSERT))); } @Test @@ -957,9 +957,9 @@ public void testOrcidQueueRecalculationForChangedPublicationRelationSettings() t List orcidQueueRecords = orcidQueueService.findAll(context); assertThat(orcidQueueRecords, hasSize(3)); - assertThat(orcidQueueRecords.get(0), matches(profile, publication, "Publication", INSERT)); - assertThat(orcidQueueRecords.get(1), matches(profile, secondpublication, "Publication", INSERT)); - assertThat(orcidQueueRecords.get(2), matches(profile, thirdpublication, "Publication", INSERT)); + assertThat(orcidQueueRecords, hasItem(matches(profile, publication, "Publication", INSERT))); + assertThat(orcidQueueRecords, hasItem(matches(profile, secondpublication, "Publication", INSERT))); + assertThat(orcidQueueRecords, hasItem(matches(profile, thirdpublication, "Publication", INSERT))); changeProfilePublicationSyncPreference(profile, MY_SELECTED); @@ -971,8 +971,8 @@ public void testOrcidQueueRecalculationForChangedPublicationRelationSettings() t List mineOrcidQueueRecords = orcidQueueService.findAll(context); assertThat(mineOrcidQueueRecords, hasSize(2)); - assertThat(mineOrcidQueueRecords.get(0), matches(profile, thirdpublication, "Publication", INSERT)); - assertThat(mineOrcidQueueRecords.get(1), matches(profile, secondpublication, "Publication", INSERT)); + assertThat(mineOrcidQueueRecords, hasItem(matches(profile, thirdpublication, "Publication", INSERT))); + assertThat(mineOrcidQueueRecords, hasItem(matches(profile, secondpublication, "Publication", INSERT))); changeProfilePublicationSyncPreference(profile, DISABLED); From f64f736624dbcf90a84bf9571410eb93ea81262b Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Thu, 7 Mar 2024 12:07:06 +0100 Subject: [PATCH 20/20] further IT for my_selected orcid sync option --- .../ResearcherProfileRestRepositoryIT.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ResearcherProfileRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ResearcherProfileRestRepositoryIT.java index 092b4e47479a..b21d8c1f5fe2 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ResearcherProfileRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ResearcherProfileRestRepositoryIT.java @@ -20,6 +20,7 @@ import static org.dspace.app.rest.matcher.ResourcePolicyMatcher.matchResourcePolicyProperties; import static org.dspace.profile.OrcidEntitySyncPreference.ALL; import static org.dspace.profile.OrcidEntitySyncPreference.MINE; +import static org.dspace.profile.OrcidEntitySyncPreference.MY_SELECTED; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; @@ -1239,6 +1240,19 @@ public void testPatchToSetOrcidSynchronizationPreferenceForPublications() throws .andExpect(status().isOk()) .andExpect(jsonPath("$.orcidSynchronization.publicationsPreference", is(MINE.name()))); + operations = asList(new ReplaceOperation("/orcid/publications", MY_SELECTED.name())); + + getClient(authToken).perform(patch("/api/eperson/profiles/{id}", ePersonId) + .content(getPatchContent(operations)) + .contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.orcidSynchronization.publicationsPreference", is(MY_SELECTED.name()))); + + getClient(authToken).perform(get("/api/eperson/profiles/{id}", ePersonId)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.orcidSynchronization.publicationsPreference", is(MY_SELECTED.name()))); + + operations = asList(new ReplaceOperation("/orcid/publications", "INVALID_VALUE")); getClient(authToken).perform(patch("/api/eperson/profiles/{id}", ePersonId) @@ -1298,6 +1312,19 @@ public void testPatchToSetOrcidSynchronizationPreferenceForFundings() throws Exc .andExpect(status().isOk()) .andExpect(jsonPath("$.orcidSynchronization.fundingsPreference", is(MINE.name()))); + operations = asList(new ReplaceOperation("/orcid/fundings", MY_SELECTED.name())); + + getClient(authToken).perform(patch("/api/eperson/profiles/{id}", ePersonId) + .content(getPatchContent(operations)) + .contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.orcidSynchronization.fundingsPreference", is(MY_SELECTED.name()))); + + getClient(authToken).perform(get("/api/eperson/profiles/{id}", ePersonId)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.orcidSynchronization.fundingsPreference", is(MY_SELECTED.name()))); + + operations = asList(new ReplaceOperation("/orcid/fundings", "INVALID_VALUE")); getClient(authToken).perform(patch("/api/eperson/profiles/{id}", ePersonId)