From 4e39c59b31f2e1c9a60138a9ccf6e66751ba582f Mon Sep 17 00:00:00 2001 From: mohamed eskander Date: Thu, 7 Dec 2023 12:03:20 +0200 Subject: [PATCH 1/9] [DSC-1386] Added support to create template item via struct builder --- .../org/dspace/administer/StructBuilder.java | 102 +++++++++++++++++- .../dspace/administer/StructBuilderIT.java | 29 +++++ dspace/config/sample-structure.xml | 70 ++++++++++++ 3 files changed, 200 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/administer/StructBuilder.java b/dspace-api/src/main/java/org/dspace/administer/StructBuilder.java index cb65604a262..c08566dc5b0 100644 --- a/dspace-api/src/main/java/org/dspace/administer/StructBuilder.java +++ b/dspace-api/src/main/java/org/dspace/administer/StructBuilder.java @@ -9,6 +9,7 @@ import static org.dspace.content.Item.ANY; import static org.dspace.content.MetadataSchemaEnum.CRIS; +import static org.dspace.content.authority.Choices.CF_UNSET; import static org.dspace.content.service.DSpaceObjectService.MD_COPYRIGHT_TEXT; import static org.dspace.content.service.DSpaceObjectService.MD_INTRODUCTORY_TEXT; import static org.dspace.content.service.DSpaceObjectService.MD_LICENSE; @@ -49,12 +50,14 @@ import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.content.Item; +import org.dspace.content.MetadataField; import org.dspace.content.MetadataFieldName; import org.dspace.content.MetadataSchemaEnum; import org.dspace.content.MetadataValue; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.CollectionService; import org.dspace.content.service.CommunityService; +import org.dspace.content.service.ItemService; import org.dspace.core.Context; import org.dspace.core.CrisConstants; import org.dspace.eperson.factory.EPersonServiceFactory; @@ -122,7 +125,8 @@ public class StructBuilder { = EPersonServiceFactory.getInstance().getEPersonService(); protected static final HandleService handleService = HandleServiceFactory.getInstance().getHandleService(); - + protected static final ItemService itemService + = ContentServiceFactory.getInstance().getItemService(); /** * Default constructor */ @@ -407,6 +411,9 @@ private static Element exportACollection(Collection collection) { Element element = new Element("collection"); element.setAttribute("identifier", collection.getHandle()); element.addContent(new Element("name").setText(collection.getName())); + + buildTemplateItem(collection, element); + element.addContent(new Element("description") .setText(collectionService.getMetadataFirstValue(collection, MetadataSchemaEnum.DC.getName(), "description", "abstract", Item.ANY))); @@ -833,6 +840,8 @@ private static Element[] handleCollections(Context context, collectionService.setMetadataSingleValue(context, collection, MD_SHORT_DESCRIPTION, Item.ANY, " "); + handleTemplateItem(context, collection, tn); + // import the rest of the metadata for (Map.Entry entry : collectionMap.entrySet()) { NodeList nl = (NodeList) xPath.compile(entry.getKey()).evaluate(tn, XPathConstants.NODESET); @@ -854,6 +863,8 @@ private static Element[] handleCollections(Context context, String fieldValue; + buildTemplateItem(collection, element); + fieldValue = collectionService.getMetadataFirstValue(collection, CollectionService.MD_SHORT_DESCRIPTION, Item.ANY); if (fieldValue != null) { @@ -930,4 +941,93 @@ private static Element[] handleCollections(Context context, return elements; } + + private static void handleTemplateItem(Context context, Collection collection, Node tn) + throws XPathExpressionException, SQLException, AuthorizeException { + + XPath xPath = XPathFactory.newInstance().newXPath(); + Node node = (Node) xPath.compile("templateItem").evaluate(tn, XPathConstants.NODE); + + if (node == null) { + return; + } + + Item templateItem = itemService.createTemplateItem(context, collection); + + NodeList metadataNodes = (NodeList) xPath.compile("metadata").evaluate(node, XPathConstants.NODESET); + + for (int i = 0; i < metadataNodes.getLength(); i++) { + Node metadataNode = metadataNodes.item(i); + MetadataFieldName metadataFieldName = buildMetadataFieldName(metadataNode); + + Node valueAttribute = (Node) xPath.compile("value").evaluate(metadataNode, XPathConstants.NODE); + Node authorityAttribute = (Node) xPath.compile("authority").evaluate(metadataNode, XPathConstants.NODE); + Node confidenceAttribute = (Node) xPath.compile("confidence").evaluate(metadataNode, XPathConstants.NODE); + + String authority = null; + int confidence = CF_UNSET; + + if (authorityAttribute != null) { + authority = authorityAttribute.getTextContent(); + confidence = confidenceAttribute != null ? Integer.parseInt(confidenceAttribute.getTextContent()) : 600; + } + + itemService.addMetadata(context, templateItem, metadataFieldName.schema, metadataFieldName.element, + metadataFieldName.qualifier, ANY, valueAttribute.getTextContent(), authority, confidence); + itemService.update(context, templateItem); + } + } + + private static MetadataFieldName buildMetadataFieldName(Node node) { + Node schemaAttribute = node.getAttributes().getNamedItem("schema"); + Node elementAttribute = node.getAttributes().getNamedItem("element"); + Node qualifierAttribute = node.getAttributes().getNamedItem("qualifier"); + + if (qualifierAttribute == null) { + return new MetadataFieldName(schemaAttribute.getTextContent(), elementAttribute.getTextContent()); + } else { + return new MetadataFieldName(schemaAttribute.getTextContent(), + elementAttribute.getTextContent(), qualifierAttribute.getTextContent()); + } + } + + private static void buildTemplateItem(Collection collection, Element element) { + + try { + Item templateItem = collection.getTemplateItem(); + + if (templateItem == null) { + return; + } + + Element templateItemElement = new Element("templateItem"); + + for (MetadataValue metadataValue : templateItem.getMetadata()) { + MetadataField metadataField = metadataValue.getMetadataField(); + Element metadata = new Element("metadata"); + metadata.setAttribute("schema", metadataField.getMetadataSchema().getName()); + metadata.setAttribute("element", metadataField.getElement()); + + if (metadataField.getQualifier() != null) { + metadata.setAttribute("qualifier", metadataField.getQualifier()); + } + + metadata.addContent(new Element("value").setText(metadataValue.getValue())); + + if (metadataValue.getAuthority() != null) { + metadata.addContent(new Element("authority").setText(metadataValue.getAuthority())); + metadata.addContent(new Element("confidence").setText( + String.valueOf(metadataValue.getConfidence()) + )); + } + + templateItemElement.addContent(metadata); + } + + element.addContent(templateItemElement); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + } diff --git a/dspace-api/src/test/java/org/dspace/administer/StructBuilderIT.java b/dspace-api/src/test/java/org/dspace/administer/StructBuilderIT.java index a113aa0438d..e69fc85b497 100644 --- a/dspace-api/src/test/java/org/dspace/administer/StructBuilderIT.java +++ b/dspace-api/src/test/java/org/dspace/administer/StructBuilderIT.java @@ -17,6 +17,7 @@ import java.nio.charset.StandardCharsets; import java.sql.SQLException; import java.util.Iterator; +import java.util.UUID; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; @@ -27,10 +28,12 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.content.Collection; import org.dspace.content.Community; +import org.dspace.content.Item; import org.dspace.content.MetadataSchemaEnum; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.CollectionService; import org.dspace.content.service.CommunityService; +import org.dspace.content.service.ItemService; import org.dspace.handle.Handle; import org.junit.AfterClass; import org.junit.Before; @@ -61,6 +64,8 @@ public class StructBuilderIT = ContentServiceFactory.getInstance().getCommunityService(); private static final CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService(); + private static final ItemService itemService + = ContentServiceFactory.getInstance().getItemService(); public StructBuilderIT() { } @@ -114,6 +119,21 @@ public void setUp() throws SQLException, AuthorizeException, IOException { " Another sidebar\n" + " \n" + " Collection 0.0.0\n" + + " \n" + + " \n" + + " template item\n" + + " \n" + + " \n" + + " Walter White\n" + + " " + UUID.randomUUID() + "\n" + + " 600\n" + + " \n" + + " \n" + + " Donald, Smith\n" + + " " + UUID.randomUUID() + "\n" + + " 400\n" + + " \n" + + " \n" + " A collection\n" + " Our next guest needs no introduction\n" + " 1776\n" + @@ -149,6 +169,11 @@ public void setUp() throws SQLException, AuthorizeException, IOException { " \n" + " \n" + " Collection 0.0\n" + + " \n" + + " \n" + + " template item\n" + + " \n" + + " \n" + " \n" + " \n" + " \n" + @@ -301,6 +326,10 @@ public void testExportStructure() MetadataSchemaEnum.DC.getName(), "title", null, null, "Collection 0.0"); + Item item = itemService.createTemplateItem(context, collection0_0); + itemService.addMetadata(context, item, MetadataSchemaEnum.DC.getName(), "title", null, + Item.ANY, "template item", null, -1); + // Export the current structure. System.out.println("exportStructure"); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); diff --git a/dspace/config/sample-structure.xml b/dspace/config/sample-structure.xml index 89c577bdcfa..1d9095841e0 100644 --- a/dspace/config/sample-structure.xml +++ b/dspace/config/sample-structure.xml @@ -10,6 +10,13 @@ Person Person person + + + + + + + @@ -21,6 +28,13 @@ Project Project project + + + + + + + @@ -32,6 +46,13 @@ Funding Funding funding + + + + + + + @@ -43,6 +64,13 @@ OrgUnit OrgUnit orgunit + + + + + + + @@ -54,6 +82,13 @@ Journal Journal journal + + + + + + + @@ -65,6 +100,13 @@ Publication Publication publication + + + + + + + @@ -76,6 +118,13 @@ Patent Patent patent + + + + + + + @@ -86,6 +135,13 @@ Dataset or other products Product + + + + + + + @@ -97,6 +153,13 @@ Event Event event + + + + + + + @@ -108,6 +171,13 @@ Equipment Equipment equipment + + + + + + + From 2cb2076f8cfe8badcfb97ea3d6b230154f54e65e Mon Sep 17 00:00:00 2001 From: mohamed eskander Date: Fri, 2 Feb 2024 18:09:35 +0200 Subject: [PATCH 2/9] [DSC-1386] refactoring --- dspace/config/sample-structure.xml | 140 ++++++++++++++--------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/dspace/config/sample-structure.xml b/dspace/config/sample-structure.xml index 1d9095841e0..bde920dea38 100644 --- a/dspace/config/sample-structure.xml +++ b/dspace/config/sample-structure.xml @@ -10,13 +10,13 @@ Person Person person - - - - - - - + + + + + + + @@ -28,13 +28,13 @@ Project Project project - - - - - - - + + + + + + + @@ -46,13 +46,13 @@ Funding Funding funding - - - - - - - + + + + + + + @@ -64,13 +64,13 @@ OrgUnit OrgUnit orgunit - - - - - - - + + + + + + + @@ -82,13 +82,13 @@ Journal Journal journal - - - - - - - + + + + + + + @@ -100,13 +100,13 @@ Publication Publication publication - - - - - - - + + + + + + + @@ -118,13 +118,13 @@ Patent Patent patent - - - - - - - + + + + + + + @@ -135,13 +135,13 @@ Dataset or other products Product - - - - - - - + + + + + + + @@ -153,13 +153,13 @@ Event Event event - - - - - - - + + + + + + + @@ -171,13 +171,13 @@ Equipment Equipment equipment - - - - - - - + + + + + + + From 81035478f3a7eaca3157b50ab4ef9b879b567356 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Fri, 9 Feb 2024 17:51:16 +0100 Subject: [PATCH 3/9] [maven-release-plugin] prepare release dspace-cris-2023.02.02 --- dspace-api/pom.xml | 2 +- dspace-iiif/pom.xml | 2 +- dspace-oai/pom.xml | 2 +- dspace-rdf/pom.xml | 2 +- dspace-rest/pom.xml | 4 ++-- dspace-server-webapp/pom.xml | 2 +- dspace-services/pom.xml | 2 +- dspace-sword/pom.xml | 2 +- dspace-swordv2/pom.xml | 2 +- dspace/modules/additions/pom.xml | 2 +- dspace/modules/pom.xml | 2 +- dspace/modules/rest/pom.xml | 2 +- dspace/modules/server-boot/pom.xml | 2 +- dspace/modules/server/pom.xml | 2 +- dspace/pom.xml | 2 +- pom.xml | 30 +++++++++++++++--------------- 16 files changed, 31 insertions(+), 31 deletions(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index 1c6879a5d70..a7d1fa104ed 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -12,7 +12,7 @@ org.dspace dspace-parent - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 .. diff --git a/dspace-iiif/pom.xml b/dspace-iiif/pom.xml index 3b56ba53e83..f6846b955fb 100644 --- a/dspace-iiif/pom.xml +++ b/dspace-iiif/pom.xml @@ -15,7 +15,7 @@ org.dspace dspace-parent - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 .. diff --git a/dspace-oai/pom.xml b/dspace-oai/pom.xml index 76718f44ba3..a3ab33551c0 100644 --- a/dspace-oai/pom.xml +++ b/dspace-oai/pom.xml @@ -8,7 +8,7 @@ dspace-parent org.dspace - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 .. diff --git a/dspace-rdf/pom.xml b/dspace-rdf/pom.xml index eb63a67e457..83af00bc343 100644 --- a/dspace-rdf/pom.xml +++ b/dspace-rdf/pom.xml @@ -9,7 +9,7 @@ org.dspace dspace-parent - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 .. diff --git a/dspace-rest/pom.xml b/dspace-rest/pom.xml index 257d0b3a91f..a77c960283e 100644 --- a/dspace-rest/pom.xml +++ b/dspace-rest/pom.xml @@ -3,7 +3,7 @@ org.dspace dspace-rest war - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 DSpace (Deprecated) REST Webapp DSpace RESTful Web Services API. NOTE: this REST API is DEPRECATED. Please consider using the REST API in the dspace-server-webapp instead! @@ -12,7 +12,7 @@ org.dspace dspace-parent - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 .. diff --git a/dspace-server-webapp/pom.xml b/dspace-server-webapp/pom.xml index c83aa538698..a26174341ef 100644 --- a/dspace-server-webapp/pom.xml +++ b/dspace-server-webapp/pom.xml @@ -14,7 +14,7 @@ org.dspace dspace-parent - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 .. diff --git a/dspace-services/pom.xml b/dspace-services/pom.xml index 39e2ccf36f3..8b67a90a8ea 100644 --- a/dspace-services/pom.xml +++ b/dspace-services/pom.xml @@ -9,7 +9,7 @@ org.dspace dspace-parent - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 .. diff --git a/dspace-sword/pom.xml b/dspace-sword/pom.xml index 10a44f3615f..803eba85911 100644 --- a/dspace-sword/pom.xml +++ b/dspace-sword/pom.xml @@ -15,7 +15,7 @@ org.dspace dspace-parent - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 .. diff --git a/dspace-swordv2/pom.xml b/dspace-swordv2/pom.xml index e76bfca65b9..1c8103016e5 100644 --- a/dspace-swordv2/pom.xml +++ b/dspace-swordv2/pom.xml @@ -13,7 +13,7 @@ org.dspace dspace-parent - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 .. diff --git a/dspace/modules/additions/pom.xml b/dspace/modules/additions/pom.xml index f5ae804f8b8..db2f30166a7 100644 --- a/dspace/modules/additions/pom.xml +++ b/dspace/modules/additions/pom.xml @@ -17,7 +17,7 @@ org.dspace modules - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 .. diff --git a/dspace/modules/pom.xml b/dspace/modules/pom.xml index 00f691235bc..5a4426dddfd 100644 --- a/dspace/modules/pom.xml +++ b/dspace/modules/pom.xml @@ -11,7 +11,7 @@ org.dspace dspace-parent - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 ../../pom.xml diff --git a/dspace/modules/rest/pom.xml b/dspace/modules/rest/pom.xml index 4dfa2939bf9..8b80b402166 100644 --- a/dspace/modules/rest/pom.xml +++ b/dspace/modules/rest/pom.xml @@ -13,7 +13,7 @@ org.dspace modules - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 .. diff --git a/dspace/modules/server-boot/pom.xml b/dspace/modules/server-boot/pom.xml index ee23c8ee7bc..90ceff73554 100644 --- a/dspace/modules/server-boot/pom.xml +++ b/dspace/modules/server-boot/pom.xml @@ -11,7 +11,7 @@ modules org.dspace - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 .. diff --git a/dspace/modules/server/pom.xml b/dspace/modules/server/pom.xml index 3797e809dca..0d26cdb5fa1 100644 --- a/dspace/modules/server/pom.xml +++ b/dspace/modules/server/pom.xml @@ -7,7 +7,7 @@ modules org.dspace - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 .. diff --git a/dspace/pom.xml b/dspace/pom.xml index 85b98dbb10d..b8cd8ad6c37 100644 --- a/dspace/pom.xml +++ b/dspace/pom.xml @@ -16,7 +16,7 @@ org.dspace dspace-parent - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 ../pom.xml diff --git a/pom.xml b/pom.xml index 8ec60b3a99d..c7b81d3eeb3 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.dspace dspace-parent pom - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 DSpace Parent Project DSpace-CRIS is an open source extension of DSpace (http://www.dspace.org) providing out of box support for the CRIS / RIMS and moder Institution Repository use cases with advanced features and optimized configurations @@ -979,14 +979,14 @@ org.dspace dspace-rest - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 jar classes org.dspace dspace-rest - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 war @@ -1137,62 +1137,62 @@ org.dspace dspace-api - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 org.dspace dspace-api test-jar - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 test org.dspace.modules additions - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 org.dspace dspace-sword - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 org.dspace dspace-swordv2 - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 org.dspace dspace-oai - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 org.dspace dspace-services - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 org.dspace dspace-server-webapp test-jar - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 test org.dspace dspace-rdf - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 org.dspace dspace-iiif - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 org.dspace dspace-server-webapp - cris-2023.02.02-SNAPSHOT + cris-2023.02.02 @@ -2037,7 +2037,7 @@ scm:git:git@github.com:4Science/DSpace.git scm:git:git@github.com:4Science/DSpace.git git@github.com:4Science/DSpace.git - dspace-cris-2023.02.02-SNAPSHOT + dspace-cris-2023.02.02 From af719dfd1dfef0b27b55dd8f7d4dddd4baa72cae Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Fri, 9 Feb 2024 17:51:21 +0100 Subject: [PATCH 4/9] [maven-release-plugin] prepare for next development iteration --- dspace-api/pom.xml | 2 +- dspace-iiif/pom.xml | 2 +- dspace-oai/pom.xml | 2 +- dspace-rdf/pom.xml | 2 +- dspace-rest/pom.xml | 4 ++-- dspace-server-webapp/pom.xml | 2 +- dspace-services/pom.xml | 2 +- dspace-sword/pom.xml | 2 +- dspace-swordv2/pom.xml | 2 +- dspace/modules/additions/pom.xml | 2 +- dspace/modules/pom.xml | 2 +- dspace/modules/rest/pom.xml | 2 +- dspace/modules/server-boot/pom.xml | 2 +- dspace/modules/server/pom.xml | 2 +- dspace/pom.xml | 2 +- pom.xml | 30 +++++++++++++++--------------- 16 files changed, 31 insertions(+), 31 deletions(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index a7d1fa104ed..b97879e1419 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -12,7 +12,7 @@ org.dspace dspace-parent - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT .. diff --git a/dspace-iiif/pom.xml b/dspace-iiif/pom.xml index f6846b955fb..43a4aa8457c 100644 --- a/dspace-iiif/pom.xml +++ b/dspace-iiif/pom.xml @@ -15,7 +15,7 @@ org.dspace dspace-parent - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT .. diff --git a/dspace-oai/pom.xml b/dspace-oai/pom.xml index a3ab33551c0..eeb37785fde 100644 --- a/dspace-oai/pom.xml +++ b/dspace-oai/pom.xml @@ -8,7 +8,7 @@ dspace-parent org.dspace - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT .. diff --git a/dspace-rdf/pom.xml b/dspace-rdf/pom.xml index 83af00bc343..834f1a084eb 100644 --- a/dspace-rdf/pom.xml +++ b/dspace-rdf/pom.xml @@ -9,7 +9,7 @@ org.dspace dspace-parent - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT .. diff --git a/dspace-rest/pom.xml b/dspace-rest/pom.xml index a77c960283e..96a76b6e0ec 100644 --- a/dspace-rest/pom.xml +++ b/dspace-rest/pom.xml @@ -3,7 +3,7 @@ org.dspace dspace-rest war - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT DSpace (Deprecated) REST Webapp DSpace RESTful Web Services API. NOTE: this REST API is DEPRECATED. Please consider using the REST API in the dspace-server-webapp instead! @@ -12,7 +12,7 @@ org.dspace dspace-parent - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT .. diff --git a/dspace-server-webapp/pom.xml b/dspace-server-webapp/pom.xml index a26174341ef..0ba8f40d86a 100644 --- a/dspace-server-webapp/pom.xml +++ b/dspace-server-webapp/pom.xml @@ -14,7 +14,7 @@ org.dspace dspace-parent - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT .. diff --git a/dspace-services/pom.xml b/dspace-services/pom.xml index 8b67a90a8ea..792f68b80a5 100644 --- a/dspace-services/pom.xml +++ b/dspace-services/pom.xml @@ -9,7 +9,7 @@ org.dspace dspace-parent - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT .. diff --git a/dspace-sword/pom.xml b/dspace-sword/pom.xml index 803eba85911..a525e6f9978 100644 --- a/dspace-sword/pom.xml +++ b/dspace-sword/pom.xml @@ -15,7 +15,7 @@ org.dspace dspace-parent - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT .. diff --git a/dspace-swordv2/pom.xml b/dspace-swordv2/pom.xml index 1c8103016e5..1cecf563f37 100644 --- a/dspace-swordv2/pom.xml +++ b/dspace-swordv2/pom.xml @@ -13,7 +13,7 @@ org.dspace dspace-parent - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT .. diff --git a/dspace/modules/additions/pom.xml b/dspace/modules/additions/pom.xml index db2f30166a7..3077c65c456 100644 --- a/dspace/modules/additions/pom.xml +++ b/dspace/modules/additions/pom.xml @@ -17,7 +17,7 @@ org.dspace modules - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT .. diff --git a/dspace/modules/pom.xml b/dspace/modules/pom.xml index 5a4426dddfd..fec235b81fd 100644 --- a/dspace/modules/pom.xml +++ b/dspace/modules/pom.xml @@ -11,7 +11,7 @@ org.dspace dspace-parent - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT ../../pom.xml diff --git a/dspace/modules/rest/pom.xml b/dspace/modules/rest/pom.xml index 8b80b402166..95587d4fc7f 100644 --- a/dspace/modules/rest/pom.xml +++ b/dspace/modules/rest/pom.xml @@ -13,7 +13,7 @@ org.dspace modules - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT .. diff --git a/dspace/modules/server-boot/pom.xml b/dspace/modules/server-boot/pom.xml index 90ceff73554..7de670e1788 100644 --- a/dspace/modules/server-boot/pom.xml +++ b/dspace/modules/server-boot/pom.xml @@ -11,7 +11,7 @@ modules org.dspace - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT .. diff --git a/dspace/modules/server/pom.xml b/dspace/modules/server/pom.xml index 0d26cdb5fa1..bf13d202b7b 100644 --- a/dspace/modules/server/pom.xml +++ b/dspace/modules/server/pom.xml @@ -7,7 +7,7 @@ modules org.dspace - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT .. diff --git a/dspace/pom.xml b/dspace/pom.xml index b8cd8ad6c37..826ab408e8e 100644 --- a/dspace/pom.xml +++ b/dspace/pom.xml @@ -16,7 +16,7 @@ org.dspace dspace-parent - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index c7b81d3eeb3..6f805739537 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.dspace dspace-parent pom - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT DSpace Parent Project DSpace-CRIS is an open source extension of DSpace (http://www.dspace.org) providing out of box support for the CRIS / RIMS and moder Institution Repository use cases with advanced features and optimized configurations @@ -979,14 +979,14 @@ org.dspace dspace-rest - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT jar classes org.dspace dspace-rest - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT war @@ -1137,62 +1137,62 @@ org.dspace dspace-api - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT org.dspace dspace-api test-jar - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT test org.dspace.modules additions - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT org.dspace dspace-sword - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT org.dspace dspace-swordv2 - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT org.dspace dspace-oai - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT org.dspace dspace-services - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT org.dspace dspace-server-webapp test-jar - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT test org.dspace dspace-rdf - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT org.dspace dspace-iiif - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT org.dspace dspace-server-webapp - cris-2023.02.02 + cris-2023.02.03-SNAPSHOT @@ -2037,7 +2037,7 @@ scm:git:git@github.com:4Science/DSpace.git scm:git:git@github.com:4Science/DSpace.git git@github.com:4Science/DSpace.git - dspace-cris-2023.02.02 + dspace-cris-2023.02.02-SNAPSHOT From ade2999cb172bbd5c562314b2dcc68732bbddb06 Mon Sep 17 00:00:00 2001 From: Andrea Bollini Date: Mon, 26 Feb 2024 19:01:50 +0100 Subject: [PATCH 5/9] DSC-714 expose the authority in the VocabularyEntryDetails when and only when it should be saved in the metadata --- .../authority/DSpaceControlledVocabulary.java | 1 + .../test/data/dspaceFolder/config/local.cfg | 3 +- .../model/VocabularyEntryDetailsRest.java | 12 + ...aryEntryDetailsChildrenLinkRepository.java | 2 +- ...ularyEntryDetailsParentLinkRepository.java | 2 +- .../VocabularyEntryDetailsRestRepository.java | 4 +- .../dspace/app/rest/utils/AuthorityUtils.java | 32 +- .../srsc-noauthority.xml | 2256 +++++++++++++++++ .../app/rest/VocabularyEntryDetailsIT.java | 98 + .../VocabularyEntryDetailsMatcher.java | 9 + 10 files changed, 2402 insertions(+), 17 deletions(-) create mode 100644 dspace-server-webapp/src/test/data/dspaceFolder/config/controlled-vocabularies/srsc-noauthority.xml diff --git a/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java b/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java index cfd8c53f79a..65d0f25c306 100644 --- a/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java +++ b/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java @@ -93,6 +93,7 @@ public boolean isPublic() { @Override public boolean storeAuthorityInMetadata() { + init(); return storeAuthority; } diff --git a/dspace-api/src/test/data/dspaceFolder/config/local.cfg b/dspace-api/src/test/data/dspaceFolder/config/local.cfg index 2f3a64218db..b02b9fd1550 100644 --- a/dspace-api/src/test/data/dspaceFolder/config/local.cfg +++ b/dspace-api/src/test/data/dspaceFolder/config/local.cfg @@ -226,4 +226,5 @@ choices.presentation.dspace.object.owner = suggest authority.controlled.dspace.object.owner = true # force the event system to work synchronously during test -system-event.thread.size = 0 \ No newline at end of file +system-event.thread.size = 0 +vocabulary.plugin.srsc-noauthority.authority.store = false \ No newline at end of file diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VocabularyEntryDetailsRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VocabularyEntryDetailsRest.java index 30e5eb71cbf..94765e4b91d 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VocabularyEntryDetailsRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VocabularyEntryDetailsRest.java @@ -10,6 +10,8 @@ import java.util.Map; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; import org.dspace.app.rest.RestResourceController; /** @@ -28,6 +30,8 @@ public class VocabularyEntryDetailsRest extends BaseObjectRest { public static final String CHILDREN = "children"; private String display; private String value; + @JsonInclude(Include.NON_NULL) + private String authority; private Map otherInformation; private boolean selectable; @JsonIgnore @@ -60,6 +64,14 @@ public void setValue(String value) { this.value = value; } + public void setAuthority(String authority) { + this.authority = authority; + } + + public String getAuthority() { + return authority; + } + public static String getName() { return NAME; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/VocabularyEntryDetailsChildrenLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/VocabularyEntryDetailsChildrenLinkRepository.java index d96e43c79aa..4a256cab644 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/VocabularyEntryDetailsChildrenLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/VocabularyEntryDetailsChildrenLinkRepository.java @@ -72,7 +72,7 @@ public Page getChildren(@Nullable HttpServletRequest pageable.getPageSize(), context.getCurrentLocale().toString()); for (Choice value : choices.values) { results.add(authorityUtils.convertEntryDetails(fix, value, vocabularyName, authority.isHierarchical(), - utils.obtainProjection())); + authority.storeAuthorityInMetadata(), utils.obtainProjection())); } Page resources = new PageImpl(results, pageable, choices.total); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/VocabularyEntryDetailsParentLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/VocabularyEntryDetailsParentLinkRepository.java index 0b91b3ecf68..37b62f857dc 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/VocabularyEntryDetailsParentLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/VocabularyEntryDetailsParentLinkRepository.java @@ -67,6 +67,6 @@ public VocabularyEntryDetailsRest getParent(@Nullable HttpServletRequest request throw new NotFoundException(); } return authorityUtils.convertEntryDetails(fix, choice, vocabularyName, authority.isHierarchical(), - utils.obtainProjection()); + authority.storeAuthorityInMetadata(), utils.obtainProjection()); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/VocabularyEntryDetailsRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/VocabularyEntryDetailsRestRepository.java index 31e8d7d3b92..0ddf0bdcae8 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/VocabularyEntryDetailsRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/VocabularyEntryDetailsRestRepository.java @@ -85,7 +85,7 @@ public VocabularyEntryDetailsRest findOne(Context context, String name) { fix = true; } VocabularyEntryDetailsRest entryDetails = authorityUtils.convertEntryDetails(fix, choice, vocabularyName, - source.isHierarchical(), utils.obtainProjection()); + source.isHierarchical(), source.storeAuthorityInMetadata(), utils.obtainProjection()); //FIXME hack to deal with an improper use on the angular side of the node id (otherinformation.id) to // build a vocabulary entry details ID if (source instanceof DSpaceControlledVocabulary && !StringUtils.startsWith(vocabularyId, vocabularyName) @@ -114,7 +114,7 @@ public Page findAllTop(@Parameter(value = "vocabular } for (Choice value : choices.values) { results.add(authorityUtils.convertEntryDetails(fix, value, vocabularyId, source.isHierarchical(), - utils.obtainProjection())); + source.storeAuthorityInMetadata(), utils.obtainProjection())); } Page resources = new PageImpl(results, pageable, choices.total); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/AuthorityUtils.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/AuthorityUtils.java index 418f5f8ab6c..2262f07da07 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/AuthorityUtils.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/AuthorityUtils.java @@ -75,21 +75,26 @@ public String getPresentation(String schema, String element, String qualifier) { /** * TODO the authorityName MUST be a part of Choice model * - * @param fix if true mean that we need to deal with a - * DSpaceControlledVocabulary that requires to have the - * vocabulary name in both the authority than in the entry - * id. An entry id with a double vocabulary name would cause issue to angular - * if the vocabulary entry was requested using just one occurrence of the name - * FIXME hack to deal with an improper use on the angular side of the node id - * (otherinformation.id) to build a vocabulary entry details ID - - * @param choice - * @param authorityName - * @param projection the name of the projection to use, or {@code null}. + * @param fix if true mean that we need to deal with a + * DSpaceControlledVocabulary that requires to have the + * vocabulary name in both the authority than in the entry + * id. An entry id with a double vocabulary name would + * cause issue to angular if the vocabulary entry was + * requested using just one occurrence of the name FIXME + * hack to deal with an improper use on the angular side + * of the node id (otherinformation.id) to build a + * vocabulary entry details ID + * @param choice the choice to convert + * @param authorityName the name of the authority to which the choice belongs + * @param isHierarchical true if it is an hierarchical vocabulary + * @param storeAuthority true if the authority is configured to store the + * authority in the metadata + * {@link ChoiceAuthority#storeAuthorityInMetadata()} + * @param projection the name of the projection to use, or {@code null}. * @return */ public VocabularyEntryDetailsRest convertEntryDetails(boolean fix, Choice choice, String authorityName, - boolean isHierarchical, Projection projection) { + boolean isHierarchical, boolean storeAuthority, Projection projection) { if (choice == null) { return null; } @@ -98,6 +103,9 @@ public VocabularyEntryDetailsRest convertEntryDetails(boolean fix, Choice choice if (!fix) { entry.setId(authorityName + ":" + entry.getId()); } + if (storeAuthority) { + entry.setAuthority(choice.authority); + } entry.setInHierarchicalVocabulary(isHierarchical); return entry; } diff --git a/dspace-server-webapp/src/test/data/dspaceFolder/config/controlled-vocabularies/srsc-noauthority.xml b/dspace-server-webapp/src/test/data/dspaceFolder/config/controlled-vocabularies/srsc-noauthority.xml new file mode 100644 index 00000000000..f37dda70f10 --- /dev/null +++ b/dspace-server-webapp/src/test/data/dspaceFolder/config/controlled-vocabularies/srsc-noauthority.xml @@ -0,0 +1,2256 @@ + + + + + + + + + + Religionshistoria + + + Kyrkovetenskap + + + Missionsvetenskap + + + Systematisk teologi + + + Islamologi + + + Tros- och livsåskådningsvetenskap + + + Religionssociologi + + + Religionspsykologi + + + Religionsfilosofi + + + Nya testamentets exegetik + + + Gamla testamentets exegetik + + + Dogmatik med symbolik + + + Religionsvetenskap/Teologi + + + + + + + Logik + + + Praktisk filosofi + + + Teoretisk filosofi + + + Vetenskapsteori + + + Filosofiämnen + + + + + Arkeologi + + + Arkeologi, klassisk + + + Arkeologi, medeltid + + + Arkeologi, nordeuropeisk + + + Arkeologi, utomeuropeisk + + + Afrikansk och jämförande arkeologi + + + Historisk osteologi + + + Arkeologiämnen + + + + + Historia + + + Idé- o lärdomshistoria + + + Ekonomisk historia + + + Kyrkohistoria + + + Teknikhistoria + + + Teknik och kultur + + + Teknik- och industrihistoria + + + Vetenskapshistoria + + + Rättshistoria + + + Medicinens historia + + + Agrarhistoria + + + Bok- och bibliotekshistoria + + + Historieämnen + + + + + Humanekologi + + + Kulturantropologi + + + Etnologi + + + + + Antikens kultur och samhälle + + + Bysantinologi + + + Historiska kulturer + + + Historisk-filosofiska ämnen + + + + + Estetik + + + Filmvetenskap + + + Konstvetenskap + + + Litteraturvetenskap + + + Musikvetenskap + + + Retorik + + + Teatervetenskap + + + Bebyggelseforskning + + + Estetiska ämnen + + + + + + + Svenska språket + + + Samiska + + + Norska språket + + + Danska språket + + + Nordiska språk + + + + + Germanistik + + + Engelska språket + + + Tyska språket + + + Nederländska + + + Övriga germanska språk + + + + + Franska språket + + + Italienska språket + + + Spanska språket + + + Portugisiska + + + Rumänska + + + Romanska språk + + + + + Finska språket + + + Estniska språket + + + Finsk-ugriska språk + + + + + Ryska språket + + + Polska språket + + + Slaviska språk + + + + + Latin + + + Klassisk grekiska + + + Nygrekiska + + + Klassiska språk + + + + + Sanskrit med indoeuropeisk språkforskning + + + Keltiska språk + + + Baltiska språk + + + Östasiatiska språk + + + Turkiska språk + + + Iranska språk + + + Arabiska + + + Kinesiska + + + Egyptologi + + + Indonesiska + + + Afrikanska språk + + + Bantuistik + + + Kaukasiska språk + + + Semitiska språk + + + Altaistik + + + Assyriologi + + + Indologi + + + Japanologi + + + Koreanologi + + + Övriga språk + + + Teckenspråk + + + + + Lingvistik + + + Fonetik + + + Barnspråk + + + Tvåspråkighet + + + Språkteknologi + + + Datorlingvistik + + + Lingvistikämnen + + + Språkvetenskap + + + Övrig humaniora och religionsvetenskap + + + HUMANIORA och RELIGIONSVETENSKAP + + + + + + + Förvaltningsrätt + + + Konstitutionell rätt + + + Socialrätt + + + Offentlig rätt + + + + + Civilprocess + + + Straffprocess + + + Förvaltningsprocess + + + Skiljemannarätt + + + Processrätt + + + Straffrätt + + + Finansrätt + + + + + Allmän avtalsrätt + + + Arbetsrätt + + + Affärsrätt + + + Bolagsrätt + + + Försäkringsrätt + + + Immaterialrätt + + + Sakrätt + + + Skadeståndsrätt + + + Speciell avtalsrätt + + + Civilrätt + + + + + Allmän rättslära + + + EU-rätt + + + Folkrätt + + + Internationell privat- och processrätt + + + Komparativ rätt + + + Marknads- och konkurrensrätt + + + Miljörätt + + + Övrig rätt + + + RÄTTSVETENSKAP/JURIDIK + + + + + + + + + Ämnesdidaktik + + + Vårdpedagogik + + + Musikpedagogik + + + Internationell pedagogik + + + Pedagogik + + + + + Tillämpad psykologi + + + Miljöpsykologi + + + Kognitionsforskning + + + Psykologi + + + + + Socialantropologi + + + Etnografi + + + Socialantrolopologi/etnografi + + + + + Familjeforskning + + + Ungdomsforskning + + + Handikappsforskning + + + Idrottsforskning + + + Socialt arbete + + + + + Kriminalvetenskap + + + Kriminologi + + + + + Rättssociologi + + + Sociologi + + + Demografi + + + + + Freds- och konfliktforskning + + + Freds- och utvecklingsforskning + + + Empirisk konfliktforskning + + + Forskning om Europa + + + Statsvetenskap + + + Pedagogiskt arbete + + + Socialvetenskap + + + + + Företagsekonomi + + + + + Kulturgeografi + + + Ekonomisk geografi + + + Kulturgeografi, ekonomisk geografi + + + + + Ekonometri + + + Nationalekonomi + + + Ekonomi + + + + + + + Informatik + + + Informatik och systemvetenskap + + + ADB + + + Data- och systemvetenskap + + + Databaser + + + Databehandling + + + Informations- och språkteknologi + + + Informationsbehandling + + + Informationsteknologi + + + Informatik, data- och systemvetenskap + + + + + Biostatistik + + + Statistik + + + Statistik, data- och systemvetenskap + + + + + Masskommunikation + + + Medie- och kommunikationsvetenskap + + + Biblioteks- och informationsvetenskap + + + Arbetsmarknadsforskning + + + Europeiskt forskningssamarbete + + + Forskning om offentlig sektor + + + Forskningspolitik + + + Militär underrättelse- och säkerhetstjänst + + + Övrig samhällsvetenskap + + + SAMHÄLLSVETENSKAP + + + + + + + Algebra och geometri + + + Analys + + + Matematisk logik + + + Diskret matematik + + + Algebra, geometri och analys + + + + + Numerisk analys + + + Matematisk statistik + + + Optimeringslära, systemteori + + + Teoretisk datalogi + + + Tillämpad matematik + + + Övrig matematik + + + MATEMATIK + + + + + + + + + Astropartikelfysik + + + Jonfysik + + + Elementarpartikelfysik + + + + + Tungjonsfysik + + + Mellanenergifysik + + + Lågenergifysik + + + Kärnfysik + + + + + Atomfysik + + + Molekylfysik + + + Kemisk fysik + + + Atom- och molekylfysik + + + + + Magnetism + + + Ytor och mellanytor + + + Halvledarfysik + + + Elektronstruktur + + + Supraledning + + + Defekter och diffusion + + + Struktur- och vibrationsfysik + + + Kritiska fenomen (fasövergångar) + + + Vätskefysik + + + Lågtemperaturfysik + + + Makromolekylfysik + + + Mesoskopisk fysik + + + Biologisk fysik + + + Kondenserade materiens fysik + + + + + Astronomi + + + Astropartikelfysik + + + Högenergiastrofysik + + + Solfysik + + + Planetsystemet + + + Galaktisk astronomi + + + Extragalaktisk astronomi + + + Stjärnors bildning och utveckling + + + Kosmologi + + + Astronomi och astrofysik + + + + + Rymdfysik + + + Plasmafysik + + + Fusion + + + Geokosmofysik och plasmafysik + + + + + Optik + + + Geofysik + + + Matematisk fysik + + + Beräkningsfysik + + + Relativitetsteori, gravitation + + + Statistisk fysik + + + Icke-linjär dynamik, kaos + + + Övrig fysik + + + Fysik + + + + + + + Kvantkemi + + + Statistisk mekanik + + + Bioinformatik + + + Teoretisk kemi + + + + + Biofysikalisk kemi + + + Kinetik + + + Spektroskopi + + + Yt- och kolloidkemi + + + Kemisk fysik + + + Fysikalisk kemi + + + + + Separationsmetoder + + + Elektrokemi + + + Spektroskopi + + + Analytisk kemi + + + Molekylär biofysik + + + + + Koordinationskemi + + + Lösningskemi + + + Fasta tillståndets kemi + + + Bio-oorganisk kemi + + + Oorganisk kemi + + + + + Organisk syntes + + + Fysikalisk organisk kemi + + + Bioorganisk kemi + + + Polymerkemi + + + Läkemedelskemi + + + Organisk kemi + + + + + Molekylärbiologi + + + Toxikologi + + + Strukturbiologi + + + Funktionsgenomik + + + Biokemi + + + + + Persistenta organiska föreningar + + + Tungmetaller och övriga metaller + + + Miljötoxikologi + + + Miljökemi + + + Övrig kemi + + + Kemi + + + + + + + Terrestisk ekologi + + + Limnisk ekologi + + + Marin ekologi + + + Etologi och beteendeekologi + + + Terrestisk, limnisk och marin ekologi + + + + + Mikrobiologi + + + Morfologi + + + Systematik och fylogeni + + + Växtfysiologi + + + Zoofysiologi + + + Utvecklingsbiologi + + + Organismbiologi + + + + + Cellbiologi + + + Molekylärbiologi + + + Immunologi + + + Toxikologi + + + Neurobiologi + + + Genetik + + + Cell- och molekylärbiologi + + + + + Bioinformatik + + + Funktionsgenomik + + + Övrig biologi + + + Biologi + + + + + + + Berggrundsgeologi och petrologi + + + Mineralvetenskap + + + Fasta jordens fysik + + + Endogen geovetenskap + + + + + Historisk geologi och paleontologi + + + Kvartärgeologi + + + Naturgeografi + + + Exogen geokemi + + + Sedimentologi + + + Exogen geovetenskap + + + + + Meteorologi + + + Hydrologi + + + Oceanografi + + + Klimatologi + + + Atmosfärs- och hydrosfärsvetenskap + + + Övrig geovetenskap + + + Geovetenskap + + + NATURVETENSKAP + + + + + + + + + Datalogi + + + Programvaruteknik + + + Kognitionsvetenskap + + + Datavetenskap + + + Reglerteknik + + + + + Telekommunikationsteori + + + Teletransmissionsteori + + + Teletrafiksystem + + + Datatransmission + + + Telekommunikation + + + Signalbehandling + + + Bildanalys + + + Datorteknik + + + Systemteknik + + + Övrig informationsteknik + + + Informationsteknik + + + + + Optisk fysik + + + Akustik + + + Materialfysik med ytfysik + + + Plasmafysik med fusion + + + Biofysik + + + Övrig teknisk fysik + + + Teknisk fysik + + + + + Elektroteknik + + + Elektronik + + + Elektrofysik + + + Fotonik + + + Elektronisk mät- och apparatteknik + + + Elkraftteknik + + + Övrig elektroteknik, elektronik och fotonik + + + Elektroteknik, elektronik och fotonik + + + + + + + Processkemi + + + Katalys + + + Molekylära transportprocesser i kemisk processteknik + + + Kemisk energiteknik + + + Cellulosa- och pappersteknik + + + Materialkemi + + + Elektrokemi + + + Yt- och kolloidkemi + + + Kärnkemi + + + Kemisk apparatteknik + + + Kemisk produktionsteknik + + + Kemisk process- och produktionsteknik + + + + + Metallurgisk processteknik + + + Metallurgisk produktionsteknik + + + Metallurgisk process- och produktionsteknik + + + Livsmedelsteknik + + + Övrig kemiteknik + + + Kemiteknik + + + + + Genteknik inkl. funktionsgenomik + + + Strukturbiokemi + + + Biokemisk och bioteknisk processteknik + + + Enzymteknik + + + Immunteknik + + + Bioteknisk separation + + + Bioanalytisk teknik + + + Bioorganisk syntes + + + Växtbioteknik + + + Bioinformatik + + + Övrig bioteknik + + + Bioteknik + + + + + Fastkroppsmekanik + + + Strömningsmekanik + + + Konstruktionsteknik + + + Mekanisk tillverkningsteknik + + + + + Mekanisk energiteknik + + + Termisk energiteknik + + + Mekanisk och termisk energiteknik + + + Farkostteknik + + + Övrig teknisk mekanik + + + Teknisk mekanik + + + + + Funktionella material + + + Konstruktionsmaterial + + + Ytbehandlingsteknik + + + Övrig bearbetning/sammanfogning + + + Övrig teknisk materialvetenskap + + + Teknisk materialvetenskap + + + + + + + Geoteknik + + + Gruvteknik + + + Geoteknik och gruvteknik + + + Byggnadsteknik + + + Byggproduktionsteknik + + + Vattenteknik + + + Lantmäteri + + + + + Arkitektur + + + Bebyggelsevård + + + Arkitektur och bebyggelsevård + + + Övrig samhällsbyggnadsteknik och arkitektur + + + Samhällsbyggnadsteknik och arkitektur + + + + + + + Produktionsteknik + + + Arbetsvetenskap och ergonomi + + + Produktion och arbetsvetenskap + + + Industriell organisation, administration och ekonomi + + + Fysisk planläggning + + + Övrig industriell teknik och ekonomi + + + Industriell teknik och ekonomi + + + + + Medicinsk teknik + + + Miljöteknik + + + Rymdteknik + + + Övriga teknikvetenskaper + + + TEKNIKVETENSKAP + + + + + + + Markfysik + + + Markkemi + + + Markbiologi + + + Jordmånslära + + + Markvetenskap + + + + + Växtförädling + + + Trädgårdsväxtodling + + + Jordbruksväxtodling + + + Skogsskötsel + + + Växt- och skogsskydd + + + Växtproduktion + + + + + Husdjursförädling + + + Husdjurens utfodring och vård + + + Vattenbruk + + + Fiske + + + Animalieproduktion + + + + + Livsmedelsvetenskap + + + Träfiber- och virkeslära + + + Fytokemi inklusive alger och industribioråvaror + + + Produktforskning + + + + + Landskapsarkitektur + + + Vegetationsbyggnad + + + Natur- och landskapsvård + + + Översiktlig planering + + + Landskapsplanering + + + + + Jordbruksteknik + + + Jordbrukets byggnadsteknik + + + Skogsteknik + + + Fjärranalys + + + Areell teknik + + + + + Jordbruksekonomi + + + Skogsekonomi + + + Skogsuppskattning och skogsindelning + + + Informationslära + + + Areell ekonomi + + + SKOGS- och JORDBRUKSVETENSKAP samt LANDSKAPSPLANERING + + + + + + + + + Anestesiologi + + + Intensivvård + + + Katastrofmedicin + + + Traumatologi + + + Anestesiologi och intensivvård + + + + + Endokrin kirurgi + + + Handkirurgi + + + Kirurgi + + + Kärlkirurgi + + + Neurokirurgi + + + Ortopedi + + + Otoneurologi + + + Pediatrisk kirurgi + + + Plastikkirurgi + + + Thoraxkirurgi + + + Transplantationskirurgi + + + Urologi och andrologi + + + Kirurgisk forskning + + + + + Obstetrik och gynekologi + + + Reproduktiv hälsa + + + Reproduktiv och perinatal omvårdnad + + + Obstetrik och kvinnosjukdomar + + + Onkologi + + + + + Audiologi + + + Logopedi och foniatrik + + + Otorhinolaryngologi + + + Kirurgi + + + + + + + Neurovetenskap + + + Neurobiologi + + + Medicinsk cellbiologi + + + Cellbiologi + + + + + Anatomi + + + Biomaterial + + + Histologi + + + Tumörbiologi + + + Morfologi + + + + + Rättsmedicin + + + Molekylär medicin + + + Patologi + + + Morfologi, cellbiologi, patologi + + + + + Dermatologi och venerologi + + + + + Medicinsk genetik + + + Rättsgenetik + + + Molekylärbiologi + + + Molekykär ekogenetik + + + Klinisk genetik + + + + + Barnkardiologi + + + Diabetologi + + + Endokrinologi + + + Gastroenterologi + + + Geriatrik och medicinsk gerontologi + + + Hematologi + + + Kardiologi + + + Kardiovaskulär medicin + + + Lungsjukdomar + + + Molekylär medicin (genetik och patologi) + + + Neurologi + + + Njursjukdomar + + + Palliativ medicin + + + Pediatrisk medicin + + + Prenatal- och perinatalforskning + + + Reumatologi + + + Transfusionsmedicin + + + Invärtesmedicin + + + Dermatologi och venerologi, klinisk genetik, invärtesmedicin + + + + + + + Farmakologi + + + Klinisk farmakologi + + + Toxikologi + + + Farmakologisk forskning + + + + + Experimentell hjärnforskning + + + Försöksdjursvetenskap + + + Klinisk fysiologi + + + Klinisk neurofysiologi + + + Medicinsk informatik + + + Medicinsk teknik + + + Molekylär neurobiologi + + + Neurobiologi + + + Neurofysiologi + + + Näringslära + + + Fysiologi + + + + + Oftalmiatrik + + + Optometri + + + Oftalmologi + + + + + Radiologi + + + Diagnostisk radiologi + + + Radiofysik + + + Strålningsbiologi + + + Radiologisk forskning + + + Fysiologi och farmakologi + + + + + + + Allmänmedicin + + + Arbetsfysiologi + + + Epidemiologi + + + Folkhälsovetenskap + + + Miljömedicin + + + Samhällsmedicin + + + Yrkesmedicin + + + Folkhälsomedicinska forskningsområden + + + Socialmedicin + + + + + + + Allergologi + + + Immungenetik + + + Immunbiologi + + + Klinisk immunologi + + + Tumörimmunologi + + + Immunologi + + + + + Bakteriologi + + + Klinisk bakteriologi + + + Klinisk virologi + + + Medicinsk mikrobiologi + + + Virologi + + + Mikrobiologi + + + Infektionssjukdomar + + + Mikrobiologi, immunologi, infektionssjukdomar + + + + + Biokemi + + + Klinisk kemi + + + Neurokemi + + + Rättskemi + + + Kemi + + + + + Barn- och ungdomspsykiatri + + + Beroendelära + + + Psykiatri + + + MEDICIN + + + + + Biokemi + + + Biomaterial + + + Cariologi + + + Cell- och molekylärbiologi + + + Endodonti + + + Farmakologisk forskning + + + Fysiologi + + + Gerodontologi + + + Kirurgisk forskning + + + Morfologi + + + Odontologisk beteendevetenskap + + + Oral mikrobiologi + + + Oral patologi och rättsodontologi + + + Oral protetik + + + Ortodonti + + + Parodontologi + + + Pedodonti + + + Radiologisk forskning + + + Övrig odontologi + + + ODONTOLOGI + + + + + Biofarmaci + + + Biologisk beroendeforskning + + + Farmaceutisk biokemi + + + Farmaceutisk farmakologi + + + Farmaceutisk kemi + + + Farmaceutisk mikrobiologi + + + Toxikologi + + + Farmakognosi + + + Galenisk farmaci + + + Samhällsfarmaci + + + Övrig farmaci + + + FARMACI + + + + + Biokemi och klinisk kemi + + + Cellbiologi och genomforskning + + + Husdjurens etologi + + + Farmakologisk forskning + + + Fysiologi och näringslära + + + Husdjurshygien + + + Kirurgi + + + Livsmedelshygien + + + Medicin + + + Mikrobiologi och immunologi + + + Morfologi + + + Obstetrik och gynekologi + + + Patologi + + + Radiologi + + + Veterinärmedicinsk epidemiologi + + + Övrig veterinärmedicin + + + VETERINÄRMEDICIN + + + + + Barn + + + Hushålls- och kostvetenskap + + + Hälso- och sjukvård i samhället + + + Kommunikation mellan människor + + + Teknik och social förändring + + + Vatten i natur och samhälle + + + + + Arbetsterapi + + + Medicinsk laboratorievetenskap + + + Omvårdnad + + + Sjukgymnastik/fysioterapi + + + Social omsorg/socialpedagogik + + + Vetenskapsteori med inriktning mot vård- och omsorgsområdet + + + Vårdvetenskap + + + Etnicitet + + + Genus + + + Kulturarv och kulturproduktion + + + Idrott + + + Äldre och åldrande + + + TVÄRVETENSKAPLIGA FORSKNINGSOMRÅDEN + + + Ämneskategorier för vetenskapliga publikationer + \ No newline at end of file diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/VocabularyEntryDetailsIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/VocabularyEntryDetailsIT.java index dad6cd8b460..340780dc583 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/VocabularyEntryDetailsIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/VocabularyEntryDetailsIT.java @@ -162,6 +162,74 @@ public void srscSearchTopTest() throws Exception { .andExpect(jsonPath("$.page.totalElements", Matchers.is(12))); } + public void srscSearchTopNoAuthorityTest() throws Exception { + String tokenAdmin = getAuthToken(admin.getEmail(), password); + String tokenEPerson = getAuthToken(eperson.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/submission/vocabularyEntryDetails/search/top") + .param("vocabulary", "srsc-noauthority")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.vocabularyEntryDetails", Matchers.containsInAnyOrder( + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB11", "HUMANITIES and RELIGION", + "HUMANITIES and RELIGION"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB12", "LAW/JURISPRUDENCE", + "LAW/JURISPRUDENCE"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB13", "SOCIAL SCIENCES", + "SOCIAL SCIENCES"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB14", "MATHEMATICS", + "MATHEMATICS"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB15", "NATURAL SCIENCES", + "NATURAL SCIENCES"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB16", "TECHNOLOGY", + "TECHNOLOGY"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB17", + "FORESTRY, AGRICULTURAL SCIENCES and LANDSCAPE PLANNING", + "FORESTRY, AGRICULTURAL SCIENCES and LANDSCAPE PLANNING"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB18", "MEDICINE", + "MEDICINE"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB19", "ODONTOLOGY", + "ODONTOLOGY"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB21", "PHARMACY", + "PHARMACY"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB22", "VETERINARY MEDICINE", + "VETERINARY MEDICINE"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB23", + "INTERDISCIPLINARY RESEARCH AREAS", "INTERDISCIPLINARY RESEARCH AREAS") + ))) + .andExpect(jsonPath("$.page.totalElements", Matchers.is(12))); + + getClient(tokenEPerson).perform(get("/api/submission/vocabularyEntryDetails/search/top") + .param("vocabulary", "srsc-noauthority")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.vocabularyEntryDetails", Matchers.containsInAnyOrder( + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB11", + "HUMANITIES and RELIGION", "HUMANITIES and RELIGION"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB12", "LAW/JURISPRUDENCE", + "LAW/JURISPRUDENCE"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB13", "SOCIAL SCIENCES", + "SOCIAL SCIENCES"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB14", "MATHEMATICS", + "MATHEMATICS"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB15", "NATURAL SCIENCES", + "NATURAL SCIENCES"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB16", "TECHNOLOGY", + "TECHNOLOGY"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB17", + "FORESTRY, AGRICULTURAL SCIENCES and LANDSCAPE PLANNING", + "FORESTRY, AGRICULTURAL SCIENCES and LANDSCAPE PLANNING"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB18", "MEDICINE", + "MEDICINE"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB19", "ODONTOLOGY", + "ODONTOLOGY"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB21", "PHARMACY", + "PHARMACY"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB22", "VETERINARY MEDICINE", + "VETERINARY MEDICINE"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB23", + "INTERDISCIPLINARY RESEARCH AREAS", "INTERDISCIPLINARY RESEARCH AREAS") + ))) + .andExpect(jsonPath("$.page.totalElements", Matchers.is(12))); + } + @Test public void srscSearchFirstLevel_MATHEMATICS_Test() throws Exception { String tokenAdmin = getAuthToken(admin.getEmail(), password); @@ -181,6 +249,25 @@ public void srscSearchFirstLevel_MATHEMATICS_Test() throws Exception { .andExpect(jsonPath("$.page.totalElements", Matchers.is(3))); } + @Test + public void srscSearchFirstLevel_MATHEMATICS_NoAuthorityTest() throws Exception { + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/submission/vocabularyEntryDetails/srsc-noauthority:SCB14/children")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.children", Matchers.containsInAnyOrder( + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB1401", + "Algebra, geometry and mathematical analysis", + "MATHEMATICS::Algebra, geometry and mathematical analysis"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB1402", + "Applied mathematics", "MATHEMATICS::Applied mathematics"), + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry("srsc-noauthority:SCB1409", "Other mathematics", + "MATHEMATICS::Other mathematics") + ))) + .andExpect(jsonPath("$._embedded.children[*].otherInformation.parent", + Matchers.everyItem(is("MATHEMATICS")))) + .andExpect(jsonPath("$.page.totalElements", Matchers.is(3))); + } + @Test public void srscSearchTopPaginationTest() throws Exception { String tokenAdmin = getAuthToken(admin.getEmail(), password); @@ -345,6 +432,17 @@ public void findParentByChildTest() throws Exception { ))); } + @Test + public void findParentByChildNoAuthorityTest() throws Exception { + String tokenEperson = getAuthToken(eperson.getEmail(), password); + getClient(tokenEperson).perform(get("/api/submission/vocabularyEntryDetails/srsc-noauthority:SCB180/parent")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", is( + VocabularyEntryDetailsMatcher.matchNoAuthorityEntry( + "srsc-noauthority:SCB18", "MEDICINE","MEDICINE") + ))); + } + @Test public void findParentByChildBadRequestTest() throws Exception { String tokenEperson = getAuthToken(eperson.getEmail(), password); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/VocabularyEntryDetailsMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/VocabularyEntryDetailsMatcher.java index 8eb2cba3c4b..d645ef1e05c 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/VocabularyEntryDetailsMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/VocabularyEntryDetailsMatcher.java @@ -8,6 +8,7 @@ package org.dspace.app.rest.matcher; import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; +import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; @@ -25,6 +26,14 @@ private VocabularyEntryDetailsMatcher() { public static Matcher matchAuthorityEntry(String id, String display, String value) { return allOf( matchProperties(id, display, value), + hasJsonPath("$.authority", is(id)), + matchLinks(id)); + } + + public static Matcher matchNoAuthorityEntry(String id, String display, String value) { + return allOf( + matchProperties(id, display, value), + hasNoJsonPath("$.authority"), matchLinks(id)); } From 96a5cbb90b1750758b984c1cbc434bf66d04a5e4 Mon Sep 17 00:00:00 2001 From: Andrea Bollini Date: Fri, 1 Mar 2024 08:52:55 +0100 Subject: [PATCH 6/9] DSC-1561 avoid tracking of placeholder for virtual metadata enhancement --- .../impl/RelatedEntityItemEnhancer.java | 382 ++++++++---------- .../app/matcher/MetadataValueMatcher.java | 7 +- .../consumer/ItemEnhancerConsumerIT.java | 101 +++-- .../enhancer/script/ItemEnhancerScriptIT.java | 69 ++-- 4 files changed, 251 insertions(+), 308 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/content/enhancer/impl/RelatedEntityItemEnhancer.java b/dspace-api/src/main/java/org/dspace/content/enhancer/impl/RelatedEntityItemEnhancer.java index f17e36ee90a..284f9b8bff8 100644 --- a/dspace-api/src/main/java/org/dspace/content/enhancer/impl/RelatedEntityItemEnhancer.java +++ b/dspace-api/src/main/java/org/dspace/content/enhancer/impl/RelatedEntityItemEnhancer.java @@ -11,10 +11,14 @@ import java.sql.SQLException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; -import java.util.Objects; +import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; +import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.dspace.content.Item; @@ -45,10 +49,19 @@ public class RelatedEntityItemEnhancer extends AbstractItemEnhancer { @Autowired private ItemService itemService; + /** + * the entity that can be extended by this enhancer, i.e. Publication + */ private String sourceEntityType; + /** + * the metadata used to navigate the relation, i.e. dc.contributor.author + */ private String sourceItemMetadataField; + /** + * the metadata that is copied from the linked entity, i.e. person.identifier.orcid + */ private String relatedItemMetadataField; @Override @@ -62,18 +75,17 @@ public boolean enhance(Context context, Item item, boolean deepMode) { if (!deepMode) { try { result = cleanObsoleteVirtualFields(context, item); - result = updateVirtualFieldsPlaces(context, item) || result; result = performEnhancement(context, item) || result; } catch (SQLException e) { LOGGER.error("An error occurs enhancing item with id {}: {}", item.getID(), e.getMessage(), e); throw new SQLRuntimeException(e); } } else { - List currMetadataValues = getCurrentVirtualMetadata(context, item); - List toBeMetadataValues = getToBeVirtualMetadata(context, item); + Map> currMetadataValues = getCurrentVirtualsMap(item); + Map> toBeMetadataValues = getToBeVirtualMetadata(context, item); if (!equivalent(currMetadataValues, toBeMetadataValues)) { try { - itemService.removeMetadataValues(context, item, currMetadataValues); + clearAllVirtualMetadata(context, item); addMetadata(context, item, toBeMetadataValues); } catch (SQLException e) { throw new SQLRuntimeException(e); @@ -84,20 +96,44 @@ public boolean enhance(Context context, Item item, boolean deepMode) { return result; } - private void addMetadata(Context context, Item item, List toBeMetadataValues) + private void clearAllVirtualMetadata(Context context, Item item) throws SQLException { + itemService.clearMetadata(context, item, VIRTUAL_METADATA_SCHEMA, VIRTUAL_SOURCE_METADATA_ELEMENT, + getVirtualQualifier(), Item.ANY); + itemService.clearMetadata(context, item, VIRTUAL_METADATA_SCHEMA, VIRTUAL_METADATA_ELEMENT, + getVirtualQualifier(), Item.ANY); + } + + private void addMetadata(Context context, Item item, Map> toBeMetadataValues) throws SQLException { - for (MetadataValueDTO dto : toBeMetadataValues) { - itemService.addMetadata(context, item, dto.getSchema(), dto.getElement(), dto.getQualifier(), null, - dto.getValue(), dto.getAuthority(), dto.getConfidence()); + for (Entry> metadataValues : toBeMetadataValues.entrySet()) { + addVirtualSourceField(context, item, metadataValues.getKey()); + for (MetadataValueDTO dto : metadataValues.getValue()) { + addVirtualField(context, item, dto.getValue(), dto.getAuthority(), dto.getLanguage(), + dto.getConfidence()); + } } } - private boolean equivalent(List currMetadataValues, List toBeMetadataValues) { + private boolean equivalent(Map> currMetadataValues, + Map> toBeMetadataValues) { if (currMetadataValues.size() != toBeMetadataValues.size()) { return false; } else { - for (int idx = 0; idx < currMetadataValues.size(); idx++) { - if (!equivalent(currMetadataValues.get(idx), toBeMetadataValues.get(idx))) { + for (String key : currMetadataValues.keySet()) { + if (!equivalent(currMetadataValues.get(key), toBeMetadataValues.get(key))) { + return false; + } + } + } + return true; + } + + private boolean equivalent(List metadataValue, List metadataValueDTO) { + if (metadataValue.size() != metadataValueDTO.size()) { + return false; + } else { + for (int i = 0; i < metadataValue.size(); i++) { + if (!equivalent(metadataValue.get(i), metadataValueDTO.get(i))) { return false; } } @@ -114,23 +150,14 @@ private boolean equivalent(MetadataValue metadataValue, MetadataValueDTO metadat && StringUtils.equals(metadataValue.getAuthority(), metadataValueDTO.getAuthority()); } - private List getToBeVirtualMetadata(Context context, Item item) { - List tobeVirtualMetadata = new ArrayList<>(); - List virtualSourceFields = getEnhanceableMetadataValue(item); - for (MetadataValue virtualSourceField : virtualSourceFields) { - MetadataValueDTO mv = new MetadataValueDTO(); - mv.setSchema(VIRTUAL_METADATA_SCHEMA); - mv.setElement(VIRTUAL_SOURCE_METADATA_ELEMENT); - mv.setQualifier(getVirtualQualifier()); - String authority = virtualSourceField.getAuthority(); + private Map> getToBeVirtualMetadata(Context context, Item item) { + Map> tobeVirtualMetadataMap = new HashMap>(); + + Set virtualSources = getVirtualSources(item); + for (String authority : virtualSources) { + List tobeVirtualMetadata = new ArrayList<>(); Item relatedItem = null; - if (StringUtils.isNotBlank(authority)) { - mv.setValue(authority); - relatedItem = findRelatedEntityItem(context, virtualSourceField); - } else { - mv.setValue(PLACEHOLDER_PARENT_METADATA_VALUE); - } - tobeVirtualMetadata.add(mv); + relatedItem = findRelatedEntityItem(context, authority); if (relatedItem == null) { MetadataValueDTO mvRelated = new MetadataValueDTO(); mvRelated.setSchema(VIRTUAL_METADATA_SCHEMA); @@ -138,44 +165,35 @@ private List getToBeVirtualMetadata(Context context, Item item mvRelated.setQualifier(getVirtualQualifier()); mvRelated.setValue(PLACEHOLDER_PARENT_METADATA_VALUE); tobeVirtualMetadata.add(mvRelated); - continue; - } - - List relatedItemMetadataValues = getMetadataValues(relatedItem, relatedItemMetadataField); - if (relatedItemMetadataValues.isEmpty()) { - MetadataValueDTO mvRelated = new MetadataValueDTO(); - mvRelated.setSchema(VIRTUAL_METADATA_SCHEMA); - mvRelated.setElement(VIRTUAL_METADATA_ELEMENT); - mvRelated.setQualifier(getVirtualQualifier()); - mvRelated.setValue(PLACEHOLDER_PARENT_METADATA_VALUE); - tobeVirtualMetadata.add(mvRelated); - continue; - } - for (MetadataValue relatedItemMetadataValue : relatedItemMetadataValues) { - MetadataValueDTO mvRelated = new MetadataValueDTO(); - mvRelated.setSchema(VIRTUAL_METADATA_SCHEMA); - mvRelated.setElement(VIRTUAL_METADATA_ELEMENT); - mvRelated.setQualifier(getVirtualQualifier()); - mvRelated.setValue(relatedItemMetadataValue.getValue()); - String authorityRelated = relatedItemMetadataValue.getAuthority(); - if (StringUtils.isNotBlank(authorityRelated)) { - mvRelated.setAuthority(authorityRelated); - mvRelated.setConfidence(Choices.CF_ACCEPTED); + } else { + List relatedItemMetadataValues = getMetadataValues(relatedItem, + relatedItemMetadataField); + if (relatedItemMetadataValues.isEmpty()) { + MetadataValueDTO mvRelated = new MetadataValueDTO(); + mvRelated.setSchema(VIRTUAL_METADATA_SCHEMA); + mvRelated.setElement(VIRTUAL_METADATA_ELEMENT); + mvRelated.setQualifier(getVirtualQualifier()); + mvRelated.setValue(PLACEHOLDER_PARENT_METADATA_VALUE); + tobeVirtualMetadata.add(mvRelated); + } else { + for (MetadataValue relatedItemMetadataValue : relatedItemMetadataValues) { + MetadataValueDTO mvRelated = new MetadataValueDTO(); + mvRelated.setSchema(VIRTUAL_METADATA_SCHEMA); + mvRelated.setElement(VIRTUAL_METADATA_ELEMENT); + mvRelated.setQualifier(getVirtualQualifier()); + mvRelated.setValue(relatedItemMetadataValue.getValue()); + String authorityRelated = relatedItemMetadataValue.getAuthority(); + if (StringUtils.isNotBlank(authorityRelated)) { + mvRelated.setAuthority(authorityRelated); + mvRelated.setConfidence(Choices.CF_ACCEPTED); + } + tobeVirtualMetadata.add(mvRelated); + } } - tobeVirtualMetadata.add(mvRelated); } + tobeVirtualMetadataMap.put(authority, tobeVirtualMetadata); } - return tobeVirtualMetadata; - } - - private List getCurrentVirtualMetadata(Context context, Item item) { - List currentVirtualMetadata = new ArrayList<>(); - List virtualSourceFields = getVirtualSourceFields(item); - for (MetadataValue virtualSourceField : virtualSourceFields) { - currentVirtualMetadata.add(virtualSourceField); - getRelatedVirtualField(item, virtualSourceField).ifPresent(currentVirtualMetadata::add); - } - return currentVirtualMetadata; + return tobeVirtualMetadataMap; } private boolean cleanObsoleteVirtualFields(Context context, Item item) throws SQLException { @@ -188,66 +206,17 @@ private boolean cleanObsoleteVirtualFields(Context context, Item item) throws SQ return result; } - private boolean updateVirtualFieldsPlaces(Context context, Item item) { - boolean result = false; - List virtualSourceFields = getVirtualSourceFields(item); - List enhanceableMetadataValue = getEnhanceableMetadataValue(item); - for (MetadataValue virtualSourceField : virtualSourceFields) { - Optional metadataWithPlaceToUpdate = metadataWithPlaceToUpdate(item, - enhanceableMetadataValue, virtualSourceField); - if (metadataWithPlaceToUpdate.isPresent()) { - updatePlaces(item, metadataWithPlaceToUpdate.get(), virtualSourceField); - result = true; - } - } - return result; - } - - private Optional metadataWithPlaceToUpdate(Item item, List enhanceableMetadataValue, - MetadataValue virtualSourceField) { - return findMetadataValueToUpdatePlace(enhanceableMetadataValue, virtualSourceField, - item); - } - - private boolean hasToUpdatePlace(MetadataValue metadataValue, MetadataValue virtualSourceField) { - return metadataValue.getPlace() != virtualSourceField.getPlace(); - } - - private void updatePlaces(Item item, MetadataValue mv, MetadataValue virtualSourceField) { - virtualSourceField.setPlace(mv.getPlace()); - getRelatedVirtualField(item, mv) - .ifPresent(relatedMv -> relatedMv.setPlace(mv.getPlace())); - } - - private Optional findMetadataValueToUpdatePlace(List enhanceableMetadataValue, - MetadataValue virtualSourceField, Item item) { - Optional exactMatch = enhanceableMetadataValue.stream() - .filter(metadataValue -> hasAuthorityEqualsTo(metadataValue, - virtualSourceField.getValue()) && !hasToUpdatePlace(metadataValue, virtualSourceField)) - .findFirst(); - if (exactMatch.isPresent()) { - enhanceableMetadataValue.remove(exactMatch.get()); - return Optional.empty(); - } else { - Optional authorityOnlyMatch = enhanceableMetadataValue.stream() - .filter(metadataValue -> hasAuthorityEqualsTo(metadataValue, - virtualSourceField.getValue()) && hasToUpdatePlace(metadataValue, virtualSourceField)) - .findFirst(); - enhanceableMetadataValue.remove(authorityOnlyMatch.get()); - return authorityOnlyMatch; - } - } - private List getObsoleteVirtualFields(Item item) { List obsoleteVirtualFields = new ArrayList<>(); - - List virtualSourceFields = getVirtualSourceFields(item); - List enhanceableMetadata = getEnhanceableMetadataValue(item); - for (MetadataValue virtualSourceField : virtualSourceFields) { - if (isRelatedSourceNoMorePresent(item, enhanceableMetadata, virtualSourceField)) { - obsoleteVirtualFields.add(virtualSourceField); - getRelatedVirtualField(item, virtualSourceField).ifPresent(obsoleteVirtualFields::add); + Map> currentVirtualsMap = getCurrentVirtualsMap(item); + Set virtualSources = getVirtualSources(item); + for (String authority : currentVirtualsMap.keySet()) { + if (!virtualSources.contains(authority)) { + for (MetadataValue mv : getVirtualSourceFields(item, authority)) { + obsoleteVirtualFields.add(mv); + getRelatedVirtualField(item, mv.getPlace()).ifPresent(obsoleteVirtualFields::add); + } } } @@ -255,142 +224,111 @@ private List getObsoleteVirtualFields(Item item) { } - /** - * This method will look in the enhanceableMetadata if the source metadata is still present. If so, it will remove - * form the list as it would not be used to validate other potential duplicate source metadata - * - * @param item - * @param enhanceableMetadata - * @param virtualSourceField - * @return true if the metadata containing a source of enhancement is still present in the list of the metadata to - * use to enhance the item - */ - private boolean isRelatedSourceNoMorePresent(Item item, List enhanceableMetadata, - MetadataValue virtualSourceField) { - Optional mv = enhanceableMetadata.stream() - .filter(metadataValue -> hasAuthorityEqualsTo(metadataValue, virtualSourceField.getValue())) - .findFirst(); - if (mv.isPresent()) { - enhanceableMetadata.remove(mv.get()); - return false; - } - return true; + private Set getVirtualSources(Item item) { + return itemService.getMetadataByMetadataString(item, sourceItemMetadataField).stream() + .filter(mv -> UUIDUtils.fromString(mv.getAuthority()) != null).map(mv -> mv.getAuthority()) + .collect(Collectors.toSet()); } - private Optional getRelatedVirtualField(Item item, MetadataValue virtualSourceField) { - return getVirtualFields(item).stream() - .filter(metadataValue -> metadataValue.getPlace() == virtualSourceField.getPlace()) - .findFirst(); - } + private Map> getCurrentVirtualsMap(Item item) { + Map> currentVirtualsMap = new HashMap>(); + List sources = itemService.getMetadata(item, VIRTUAL_METADATA_SCHEMA, + VIRTUAL_SOURCE_METADATA_ELEMENT, getVirtualQualifier(), Item.ANY); + List generated = itemService.getMetadata(item, VIRTUAL_METADATA_SCHEMA, VIRTUAL_METADATA_ELEMENT, + getVirtualQualifier(), Item.ANY); - private boolean performEnhancement(Context context, Item item) throws SQLException { - boolean result = false; - if (noEnhanceableMetadata(context, item)) { - return false; + if (sources.size() != generated.size()) { + LOGGER.error( + "inconsistent virtual metadata for the item {} got {} sources and {} generated virtual metadata", + item.getID().toString(), sources.size(), generated.size()); } - for (MetadataValue metadataValue : getEnhanceableMetadataValue(item)) { - - if (wasValueAlreadyUsedForEnhancement(item, metadataValue)) { - continue; - } - - Item relatedItem = findRelatedEntityItem(context, metadataValue); - if (relatedItem == null) { - addVirtualField(context, item, PLACEHOLDER_PARENT_METADATA_VALUE); - addVirtualSourceField(context, item, metadataValue); - continue; + for (int i = 0; i < Integer.max(sources.size(), generated.size()); i++) { + String authority; + if (i < sources.size()) { + authority = sources.get(i).getValue(); + } else { + // we have less source than virtual metadata let's generate a random uuid to + // associate with these extra metadata so that they will be managed as obsolete + // value + authority = UUID.randomUUID().toString(); } - - List relatedItemMetadataValues = getMetadataValues(relatedItem, relatedItemMetadataField); - if (relatedItemMetadataValues.isEmpty()) { - addVirtualField(context, item, PLACEHOLDER_PARENT_METADATA_VALUE); - addVirtualSourceField(context, item, metadataValue); - continue; + List mvalues = currentVirtualsMap.get(authority); + if (mvalues == null) { + mvalues = new ArrayList(); } - for (MetadataValue relatedItemMetadataValue : relatedItemMetadataValues) { - addVirtualField(context, item, relatedItemMetadataValue.getValue()); - addVirtualSourceField(context, item, metadataValue); + if (i < generated.size()) { + mvalues.add(generated.get(i)); } - result = true; + currentVirtualsMap.put(authority, mvalues); } - return result; - } - - private boolean noEnhanceableMetadata(Context context, Item item) { - - return getEnhanceableMetadataValue(item) - .stream() - .noneMatch(metadataValue -> validAuthority(context, metadataValue)); - } - - private boolean validAuthority(Context context, MetadataValue metadataValue) { - Item relatedItem = findRelatedEntityItem(context, metadataValue); - return Objects.nonNull(relatedItem); + return currentVirtualsMap; } - private List getEnhanceableMetadataValue(Item item) { - return getMetadataValues(item, sourceItemMetadataField); + private Optional getRelatedVirtualField(Item item, int pos) { + return getVirtualFields(item).stream() + .skip(pos) + .findFirst(); } - private boolean wasValueAlreadyUsedForEnhancement(Item item, MetadataValue metadataValue) { + private boolean performEnhancement(Context context, Item item) throws SQLException { + boolean result = false; + Map> currentVirtualsMap = getCurrentVirtualsMap(item); + Set virtualSources = getVirtualSources(item); + for (String authority : virtualSources) { + if (!currentVirtualsMap.containsKey(authority)) { + Item relatedItem = findRelatedEntityItem(context, authority); + if (relatedItem == null) { + addVirtualField(context, item, PLACEHOLDER_PARENT_METADATA_VALUE, null, null, Choices.CF_UNSET); + addVirtualSourceField(context, item, authority); + continue; + } - if (isPlaceholderAtPlace(getVirtualFields(item), metadataValue.getPlace())) { - return true; + List relatedItemMetadataValues = getMetadataValues(relatedItem, + relatedItemMetadataField); + if (relatedItemMetadataValues.isEmpty()) { + addVirtualField(context, item, PLACEHOLDER_PARENT_METADATA_VALUE, null, null, Choices.CF_UNSET); + addVirtualSourceField(context, item, authority); + continue; + } + for (MetadataValue relatedItemMetadataValue : relatedItemMetadataValues) { + addVirtualField(context, item, relatedItemMetadataValue.getValue(), + relatedItemMetadataValue.getAuthority(), relatedItemMetadataValue.getLanguage(), + relatedItemMetadataValue.getConfidence()); + addVirtualSourceField(context, item, authority); + } + result = true; + } } - - return getVirtualSourceFields(item).stream() - .anyMatch(virtualSourceField -> virtualSourceField.getPlace() == metadataValue.getPlace() - && hasAuthorityEqualsTo(metadataValue, virtualSourceField.getValue())); - - } - - private boolean isPlaceholderAtPlace(List metadataValues, int place) { - return place < metadataValues.size() ? isPlaceholder(metadataValues.get(place)) : false; - } - - private boolean hasAuthorityEqualsTo(MetadataValue metadataValue, String authority) { - return Objects.equals(metadataValue.getAuthority(), authority) - || (StringUtils.isBlank(metadataValue.getAuthority()) - && Objects.equals(PLACEHOLDER_PARENT_METADATA_VALUE, authority)); + return result; } - private Item findRelatedEntityItem(Context context, MetadataValue metadataValue) { + private Item findRelatedEntityItem(Context context, String authority) { try { - UUID relatedItemUUID = UUIDUtils.fromString(metadataValue.getAuthority()); + UUID relatedItemUUID = UUIDUtils.fromString(authority); return relatedItemUUID != null ? itemService.find(context, relatedItemUUID) : null; } catch (SQLException e) { throw new SQLRuntimeException(e); } } - private boolean isPlaceholder(MetadataValue metadataValue) { - return PLACEHOLDER_PARENT_METADATA_VALUE.equals(metadataValue.getValue()); - } - private List getMetadataValues(Item item, String metadataField) { return itemService.getMetadataByMetadataString(item, metadataField); } - private List getVirtualSourceFields(Item item) { - return getMetadataValues(item, getVirtualSourceMetadataField()); + private List getVirtualSourceFields(Item item, String authority) { + return getMetadataValues(item, getVirtualSourceMetadataField()).stream() + .filter(mv -> StringUtils.equals(authority, mv.getValue())).collect(Collectors.toList()); } private List getVirtualFields(Item item) { return getMetadataValues(item, getVirtualMetadataField()); } - private void addVirtualField(Context context, Item item, String value) throws SQLException { - itemService.addMetadata(context, item, VIRTUAL_METADATA_SCHEMA, VIRTUAL_METADATA_ELEMENT, - getVirtualQualifier(), null, value); - } - - private void addVirtualSourceField(Context context, Item item, MetadataValue sourceValue) throws SQLException { - if (StringUtils.isNotBlank(sourceValue.getAuthority())) { - addVirtualSourceField(context, item, sourceValue.getAuthority()); - } else { - addVirtualSourceField(context, item, PLACEHOLDER_PARENT_METADATA_VALUE); - } + private void addVirtualField(Context context, Item item, String value, String authority, String lang, + int confidence) throws SQLException { + itemService.addMetadata(context, item, VIRTUAL_METADATA_SCHEMA, VIRTUAL_METADATA_ELEMENT, getVirtualQualifier(), + lang, value, authority, confidence); } private void addVirtualSourceField(Context context, Item item, String sourceValueAuthority) throws SQLException { diff --git a/dspace-api/src/test/java/org/dspace/app/matcher/MetadataValueMatcher.java b/dspace-api/src/test/java/org/dspace/app/matcher/MetadataValueMatcher.java index 1439c9c37fa..55ceb779ba0 100644 --- a/dspace-api/src/test/java/org/dspace/app/matcher/MetadataValueMatcher.java +++ b/dspace-api/src/test/java/org/dspace/app/matcher/MetadataValueMatcher.java @@ -72,7 +72,8 @@ protected boolean matchesSafely(MetadataValue metadataValue) { Objects.equals(metadataValue.getMetadataField().toString('.'), field) && Objects.equals(metadataValue.getLanguage(), language) && Objects.equals(metadataValue.getAuthority(), authority) && - Objects.equals(metadataValue.getPlace(), place) && + (Objects.isNull(place) + || Objects.equals(metadataValue.getPlace(), place)) && Objects.equals(metadataValue.getConfidence(), confidence) && Objects.equals(metadataValue.getSecurityLevel(), securityLevel); } @@ -91,6 +92,10 @@ public static MetadataValueMatcher with(String field, String value) { return with(field, value, null, null, 0, -1); } + public static MetadataValueMatcher withNoPlace(String field, String value) { + return with(field, value, null, null, null, -1); + } + public static MetadataValueMatcher withSecurity(String field, String value, Integer securityLevel) { return with(field, value, null, null, 0, -1, securityLevel); } diff --git a/dspace-api/src/test/java/org/dspace/content/enhancer/consumer/ItemEnhancerConsumerIT.java b/dspace-api/src/test/java/org/dspace/content/enhancer/consumer/ItemEnhancerConsumerIT.java index 176f055a446..aa440574c07 100644 --- a/dspace-api/src/test/java/org/dspace/content/enhancer/consumer/ItemEnhancerConsumerIT.java +++ b/dspace-api/src/test/java/org/dspace/content/enhancer/consumer/ItemEnhancerConsumerIT.java @@ -8,6 +8,7 @@ package org.dspace.content.enhancer.consumer; import static org.dspace.app.matcher.MetadataValueMatcher.with; +import static org.dspace.app.matcher.MetadataValueMatcher.withNoPlace; import static org.dspace.core.CrisConstants.PLACEHOLDER_PARENT_METADATA_VALUE; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; @@ -141,31 +142,29 @@ public void testManyMetadataValuesEnhancement() throws Exception { publication = commitAndReload(publication); List values = publication.getMetadata(); - assertThat(values, hasSize(26)); + assertThat(values, hasSize(22)); assertThat(values, hasItem(with("dc.contributor.author", "Red Smith"))); assertThat(values, hasItem(with("dc.contributor.author", "Walter White", person1.getID().toString(), 1, 600))); assertThat(values, hasItem(with("dc.contributor.author", "John Smith", person2.getID().toString(), 2, 600))); assertThat(values, hasItem(with("dc.contributor.author", "Jesse Pinkman", person3.getID().toString(), 3, 600))); - assertThat(values, hasItem(with("cris.virtual.department", PLACEHOLDER_PARENT_METADATA_VALUE, 0))); - assertThat(values, hasItem(with("cris.virtualsource.department", PLACEHOLDER_PARENT_METADATA_VALUE, 0))); - assertThat(values, hasItem(with("cris.virtual.department", "4Science", 1))); - assertThat(values, hasItem(with("cris.virtualsource.department", person1.getID().toString(), 1))); - assertThat(values, hasItem(with("cris.virtual.department", PLACEHOLDER_PARENT_METADATA_VALUE, 2))); - assertThat(values, hasItem(with("cris.virtualsource.department", person2.getID().toString(), 2))); - assertThat(values, hasItem(with("cris.virtual.department", "University of Rome", 3))); - assertThat(values, hasItem(with("cris.virtualsource.department", person3.getID().toString(), 3))); + // virtual source and virtual metadata are not required to respect the order of the source metadata + assertThat(values, hasItem(withNoPlace("cris.virtualsource.department", person1.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.department", person2.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.department", person3.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtual.department", PLACEHOLDER_PARENT_METADATA_VALUE))); + assertThat(values, hasItem(withNoPlace("cris.virtual.department", "4Science"))); + assertThat(values, hasItem(withNoPlace("cris.virtual.department", "University of Rome"))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.author-orcid", person1.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.author-orcid", person2.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.author-orcid", person3.getID().toString()))); + // we can check with the position as all the values are expected to be placeholder assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 0))); - assertThat(values, hasItem(with("cris.virtualsource.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 0))); assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 1))); - assertThat(values, hasItem(with("cris.virtualsource.author-orcid", person1.getID().toString(), 1))); assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 2))); - assertThat(values, hasItem(with("cris.virtualsource.author-orcid", person2.getID().toString(), 2))); - assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 3))); - assertThat(values, hasItem(with("cris.virtualsource.author-orcid", person3.getID().toString(), 3))); - assertThat(getMetadataValues(publication, "cris.virtual.department"), hasSize(4)); - assertThat(getMetadataValues(publication, "cris.virtualsource.department"), hasSize(4)); - assertThat(getMetadataValues(publication, "cris.virtual.author-orcid"), hasSize(4)); - assertThat(getMetadataValues(publication, "cris.virtualsource.author-orcid"), hasSize(4)); + assertThat(getMetadataValues(publication, "cris.virtual.department"), hasSize(3)); + assertThat(getMetadataValues(publication, "cris.virtualsource.department"), hasSize(3)); + assertThat(getMetadataValues(publication, "cris.virtual.author-orcid"), hasSize(3)); + assertThat(getMetadataValues(publication, "cris.virtualsource.author-orcid"), hasSize(3)); } @@ -246,22 +245,28 @@ public void testEnhancementWithMetadataRemoval() throws Exception { assertThat(values, hasItem(with("dc.contributor.author", "Walter White", person1.getID().toString(), 0, 600))); assertThat(values, hasItem(with("dc.contributor.author", "John Smith", person2.getID().toString(), 1, 600))); assertThat(values, hasItem(with("dc.contributor.author", "Jesse Pinkman", person3.getID().toString(), 2, 600))); - assertThat(values, hasItem(with("cris.virtual.department", "4Science"))); - assertThat(values, hasItem(with("cris.virtualsource.department", person1.getID().toString()))); - assertThat(values, hasItem(with("cris.virtual.department", "Company", 1))); - assertThat(values, hasItem(with("cris.virtualsource.department", person2.getID().toString(), 1))); - assertThat(values, hasItem(with("cris.virtual.department", "University of Rome", 2))); - assertThat(values, hasItem(with("cris.virtualsource.department", person3.getID().toString(), 2))); - assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE))); - assertThat(values, hasItem(with("cris.virtualsource.author-orcid", person1.getID().toString()))); - assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE))); - assertThat(values, hasItem(with("cris.virtualsource.author-orcid", person2.getID().toString(), 1))); - assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE))); - assertThat(values, hasItem(with("cris.virtualsource.author-orcid", person3.getID().toString(), 2))); + // virtual source and virtual metadata are not required to respect the order of the source metadata + assertThat(values, hasItem(withNoPlace("cris.virtualsource.department", person1.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.department", person2.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.department", person3.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtual.department", "4Science"))); + assertThat(values, hasItem(withNoPlace("cris.virtual.department", "Company"))); + assertThat(values, hasItem(withNoPlace("cris.virtual.department", "University of Rome"))); assertThat(getMetadataValues(publication, "cris.virtual.department"), hasSize(3)); assertThat(getMetadataValues(publication, "cris.virtualsource.department"), hasSize(3)); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.author-orcid", person1.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.author-orcid", person2.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.author-orcid", person3.getID().toString()))); + // we can check with the position as all the values are expected to be placeholder + assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 0))); + assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 1))); + assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 2))); + assertThat(getMetadataValues(publication, "cris.virtual.author-orcid"), hasSize(3)); + assertThat(getMetadataValues(publication, "cris.virtualsource.author-orcid"), hasSize(3)); + + MetadataValue authorToRemove = getMetadataValues(publication, "dc.contributor.author").get(1); context.turnOffAuthorisationSystem(); @@ -274,14 +279,16 @@ public void testEnhancementWithMetadataRemoval() throws Exception { assertThat(values, hasSize(16)); assertThat(values, hasItem(with("dc.contributor.author", "Walter White", person1.getID().toString(), 0, 600))); assertThat(values, hasItem(with("dc.contributor.author", "Jesse Pinkman", person3.getID().toString(), 1, 600))); - assertThat(values, hasItem(with("cris.virtual.department", "4Science"))); - assertThat(values, hasItem(with("cris.virtualsource.department", person1.getID().toString()))); - assertThat(values, hasItem(with("cris.virtual.department", "University of Rome", 1))); - assertThat(values, hasItem(with("cris.virtualsource.department", person3.getID().toString(), 1))); + // virtual source and virtual metadata are not required to respect the order of the source metadata + assertThat(values, hasItem(withNoPlace("cris.virtualsource.department", person1.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.department", person3.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtual.department", "4Science"))); + assertThat(values, hasItem(withNoPlace("cris.virtual.department", "University of Rome"))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.author-orcid", person1.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.author-orcid", person3.getID().toString()))); + // we can check with the position as all the values are expected to be placeholder assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 0))); - assertThat(values, hasItem(with("cris.virtualsource.author-orcid", person1.getID().toString(), 0))); assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 1))); - assertThat(values, hasItem(with("cris.virtualsource.author-orcid", person3.getID().toString(), 1))); assertThat(getMetadataValues(publication, "cris.virtual.department"), hasSize(2)); assertThat(getMetadataValues(publication, "cris.virtualsource.department"), hasSize(2)); assertThat(getMetadataValues(publication, "cris.virtual.author-orcid"), hasSize(2)); @@ -348,16 +355,10 @@ public void testEnhancementAfterItemUpdate() throws Exception { with("dc.contributor.author", "Gus Fring", 3))); assertThat(getMetadataValues(publication, "cris.virtual.author-orcid"), contains( - with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE), - with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 1), - with("cris.virtual.author-orcid", "0000-0000-1111-2222", 2), - with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 3))); + with("cris.virtual.author-orcid", "0000-0000-1111-2222"))); assertThat(getMetadataValues(publication, "cris.virtualsource.author-orcid"), contains( - with("cris.virtualsource.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE), - with("cris.virtualsource.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 1), - with("cris.virtualsource.author-orcid", personId, 2), - with("cris.virtualsource.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 3))); + with("cris.virtualsource.author-orcid", personId))); context.turnOffAuthorisationSystem(); itemService.addMetadata(context, publication, "dc", "title", "alternative", null, "Other name"); @@ -372,16 +373,10 @@ public void testEnhancementAfterItemUpdate() throws Exception { with("dc.contributor.author", "Gus Fring", 3))); assertThat(getMetadataValues(publication, "cris.virtual.author-orcid"), contains( - with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE), - with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 1), - with("cris.virtual.author-orcid", "0000-0000-1111-2222", 2), - with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 3))); + with("cris.virtual.author-orcid", "0000-0000-1111-2222"))); - assertThat(getMetadataValues(publication, "cris.virtualsource.author-orcid"), contains( - with("cris.virtualsource.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE), - with("cris.virtualsource.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 1), - with("cris.virtualsource.author-orcid", personId, 2), - with("cris.virtualsource.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 3))); + assertThat(getMetadataValues(publication, "cris.virtualsource.author-orcid"), contains( + with("cris.virtualsource.author-orcid", personId))); } diff --git a/dspace-api/src/test/java/org/dspace/content/enhancer/script/ItemEnhancerScriptIT.java b/dspace-api/src/test/java/org/dspace/content/enhancer/script/ItemEnhancerScriptIT.java index 33913368b0a..f8b2b0d2d77 100644 --- a/dspace-api/src/test/java/org/dspace/content/enhancer/script/ItemEnhancerScriptIT.java +++ b/dspace-api/src/test/java/org/dspace/content/enhancer/script/ItemEnhancerScriptIT.java @@ -8,11 +8,13 @@ package org.dspace.content.enhancer.script; import static org.dspace.app.matcher.MetadataValueMatcher.with; +import static org.dspace.app.matcher.MetadataValueMatcher.withNoPlace; import static org.dspace.content.Item.ANY; import static org.dspace.content.enhancer.consumer.ItemEnhancerConsumer.ITEMENHANCER_ENABLED; import static org.dspace.core.CrisConstants.PLACEHOLDER_PARENT_METADATA_VALUE; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasSize; @@ -171,11 +173,14 @@ public void testItemsEnhancement() throws Exception { assertThat(firstPublication.getMetadata(), hasItem(with("cris.virtual.department", "4Science"))); assertThat(firstPublication.getMetadata(), hasItem(with("cris.virtualsource.department", firstAuthorId))); - assertThat(secondPublication.getMetadata(), hasItem(with("cris.virtual.department", "4Science"))); - assertThat(secondPublication.getMetadata(), hasItem(with("cris.virtualsource.department", firstAuthorId))); - assertThat(secondPublication.getMetadata(), hasItem(with("cris.virtual.department", "Company", 1))); - assertThat(secondPublication.getMetadata(), hasItem(with("cris.virtualsource.department", secondAuthorId, 1))); - + assertThat(getMetadataValues(secondPublication, "cris.virtual.department"), + containsInAnyOrder( + withNoPlace("cris.virtual.department", "4Science"), + withNoPlace("cris.virtual.department", "Company"))); + assertThat(getMetadataValues(secondPublication, "cris.virtualsource.department"), + containsInAnyOrder( + withNoPlace("cris.virtualsource.department", firstAuthorId), + withNoPlace("cris.virtualsource.department", secondAuthorId))); assertThat(getMetadataValues(thirdPublication, "cris.virtual.department"), empty()); assertThat(getMetadataValues(thirdPublication, "cris.virtualsource.department"), empty()); @@ -223,10 +228,13 @@ public void testItemEnhancementWithoutForce() throws Exception { assertThat(getMetadataValues(publication, "cris.virtual.department"), hasSize(2)); assertThat(getMetadataValues(publication, "cris.virtualsource.department"), hasSize(2)); - assertThat(publication.getMetadata(), hasItem(with("cris.virtual.department", "4Science"))); - assertThat(publication.getMetadata(), hasItem(with("cris.virtualsource.department", firstAuthorId))); - assertThat(publication.getMetadata(), hasItem(with("cris.virtual.department", "Company", 1))); - assertThat(publication.getMetadata(), hasItem(with("cris.virtualsource.department", secondAuthorId, 1))); + assertThat(getMetadataValues(publication, "cris.virtual.department"), containsInAnyOrder( + withNoPlace("cris.virtual.department", "4Science"), + withNoPlace("cris.virtual.department", "Company"))); + + assertThat(getMetadataValues(publication, "cris.virtualsource.department"), containsInAnyOrder( + withNoPlace("cris.virtualsource.department", firstAuthorId), + withNoPlace("cris.virtualsource.department", secondAuthorId))); context.turnOffAuthorisationSystem(); @@ -293,10 +301,12 @@ public void testItemEnhancementWithForce() throws Exception { assertThat(getMetadataValues(publication, "cris.virtual.department"), hasSize(2)); assertThat(getMetadataValues(publication, "cris.virtualsource.department"), hasSize(2)); - assertThat(publication.getMetadata(), hasItem(with("cris.virtual.department", "4Science"))); - assertThat(publication.getMetadata(), hasItem(with("cris.virtualsource.department", firstAuthorId))); - assertThat(publication.getMetadata(), hasItem(with("cris.virtual.department", "Company", 1))); - assertThat(publication.getMetadata(), hasItem(with("cris.virtualsource.department", secondAuthorId, 1))); + assertThat(getMetadataValues(publication, "cris.virtual.department"), containsInAnyOrder( + withNoPlace("cris.virtual.department", "4Science"), + withNoPlace("cris.virtual.department", "Company"))); + assertThat(getMetadataValues(publication, "cris.virtualsource.department"), containsInAnyOrder( + withNoPlace("cris.virtualsource.department", firstAuthorId), + withNoPlace("cris.virtualsource.department", secondAuthorId))); context.turnOffAuthorisationSystem(); @@ -375,17 +385,16 @@ public void testItemEnhancementMetadataPositions() throws Exception { assertThat(getMetadataValues(publication, "cris.virtual.department"), hasSize(4)); assertThat(getMetadataValues(publication, "cris.virtualsource.department"), hasSize(4)); - assertThat(publication.getMetadata(), hasItem(with("cris.virtual.department", - PLACEHOLDER_PARENT_METADATA_VALUE, 0))); - assertThat(publication.getMetadata(), hasItem(with("cris.virtualsource.department", firstAuthorId,0))); - assertThat(publication.getMetadata(), hasItem(with("cris.virtual.department", "4Science", 1))); - assertThat(publication.getMetadata(), hasItem(with("cris.virtualsource.department", secondAuthorId,1))); - assertThat(publication.getMetadata(), hasItem(with("cris.virtual.department", "Company", 2))); - assertThat(publication.getMetadata(), hasItem(with("cris.virtualsource.department", thirdAuthorId, 2))); - assertThat(publication.getMetadata(), hasItem(with("cris.virtual.department", - PLACEHOLDER_PARENT_METADATA_VALUE, 3))); - assertThat(publication.getMetadata(), hasItem(with("cris.virtualsource.department", fourthAuthorId,3))); - + assertThat(getMetadataValues(publication, "cris.virtual.department"), containsInAnyOrder( + withNoPlace("cris.virtual.department", PLACEHOLDER_PARENT_METADATA_VALUE), + withNoPlace("cris.virtual.department", "4Science"), + withNoPlace("cris.virtual.department", "Company"), + withNoPlace("cris.virtual.department", PLACEHOLDER_PARENT_METADATA_VALUE))); + assertThat(getMetadataValues(publication, "cris.virtualsource.department"), containsInAnyOrder( + withNoPlace("cris.virtualsource.department", firstAuthorId), + withNoPlace("cris.virtualsource.department", secondAuthorId), + withNoPlace("cris.virtualsource.department", thirdAuthorId), + withNoPlace("cris.virtualsource.department", fourthAuthorId))); } @Test @@ -420,15 +429,11 @@ public void testItemEnhancementSourceWithoutAuthority() throws Exception { publication = reload(publication); - assertThat(getMetadataValues(publication, "cris.virtual.department"), hasSize(2)); - assertThat(getMetadataValues(publication, "cris.virtualsource.department"), hasSize(2)); + assertThat(getMetadataValues(publication, "cris.virtual.department"), hasSize(1)); + assertThat(getMetadataValues(publication, "cris.virtualsource.department"), hasSize(1)); - assertThat(publication.getMetadata(), hasItem(with("cris.virtual.department", - PLACEHOLDER_PARENT_METADATA_VALUE, 0))); - assertThat(publication.getMetadata(), hasItem(with("cris.virtualsource.department", - PLACEHOLDER_PARENT_METADATA_VALUE,0))); - assertThat(publication.getMetadata(), hasItem(with("cris.virtual.department", "4Science", 1))); - assertThat(publication.getMetadata(), hasItem(with("cris.virtualsource.department", secondAuthorId,1))); + assertThat(publication.getMetadata(), hasItem(with("cris.virtual.department", "4Science", 0))); + assertThat(publication.getMetadata(), hasItem(with("cris.virtualsource.department", secondAuthorId,0))); } From f6b4127a6b759c05751bd3722fe180ebda828d09 Mon Sep 17 00:00:00 2001 From: Andrea Bollini Date: Fri, 1 Mar 2024 20:15:51 +0100 Subject: [PATCH 7/9] DSC-1561 extend RelatedEntityItemEnhancer to manage a list of metadata to use as source and a list of related item metadata from which extract the enhanced metadata --- .../impl/RelatedEntityItemEnhancer.java | 77 ++++++--- .../api/extra-metadata-enhancers-for-test.xml | 40 +++++ .../service/BulkImportWorkbookBuilderIT.java | 6 +- .../consumer/ItemEnhancerConsumerIT.java | 153 +++++++++++++----- .../enhancer/script/ItemEnhancerScriptIT.java | 59 +++++-- .../org/dspace/harvest/OAIHarvesterIT.java | 6 +- dspace/config/registries/cris-types.xml | 18 +-- .../config/spring/api/metadata-enhancers.xml | 46 ++++-- 8 files changed, 290 insertions(+), 115 deletions(-) create mode 100644 dspace-api/src/test/data/dspaceFolder/config/spring/api/extra-metadata-enhancers-for-test.xml diff --git a/dspace-api/src/main/java/org/dspace/content/enhancer/impl/RelatedEntityItemEnhancer.java b/dspace-api/src/main/java/org/dspace/content/enhancer/impl/RelatedEntityItemEnhancer.java index 284f9b8bff8..7a6f2927092 100644 --- a/dspace-api/src/main/java/org/dspace/content/enhancer/impl/RelatedEntityItemEnhancer.java +++ b/dspace-api/src/main/java/org/dspace/content/enhancer/impl/RelatedEntityItemEnhancer.java @@ -57,12 +57,12 @@ public class RelatedEntityItemEnhancer extends AbstractItemEnhancer { /** * the metadata used to navigate the relation, i.e. dc.contributor.author */ - private String sourceItemMetadataField; + private List sourceItemMetadataFields; /** * the metadata that is copied from the linked entity, i.e. person.identifier.orcid */ - private String relatedItemMetadataField; + private List relatedItemMetadataFields; @Override public boolean canEnhance(Context context, Item item) { @@ -166,16 +166,10 @@ private Map> getToBeVirtualMetadata(Context conte mvRelated.setValue(PLACEHOLDER_PARENT_METADATA_VALUE); tobeVirtualMetadata.add(mvRelated); } else { - List relatedItemMetadataValues = getMetadataValues(relatedItem, - relatedItemMetadataField); - if (relatedItemMetadataValues.isEmpty()) { - MetadataValueDTO mvRelated = new MetadataValueDTO(); - mvRelated.setSchema(VIRTUAL_METADATA_SCHEMA); - mvRelated.setElement(VIRTUAL_METADATA_ELEMENT); - mvRelated.setQualifier(getVirtualQualifier()); - mvRelated.setValue(PLACEHOLDER_PARENT_METADATA_VALUE); - tobeVirtualMetadata.add(mvRelated); - } else { + boolean foundAtLeastOneValue = false; + for (String relatedItemMetadataField : relatedItemMetadataFields) { + List relatedItemMetadataValues = getMetadataValues(relatedItem, + relatedItemMetadataField); for (MetadataValue relatedItemMetadataValue : relatedItemMetadataValues) { MetadataValueDTO mvRelated = new MetadataValueDTO(); mvRelated.setSchema(VIRTUAL_METADATA_SCHEMA); @@ -188,8 +182,17 @@ private Map> getToBeVirtualMetadata(Context conte mvRelated.setConfidence(Choices.CF_ACCEPTED); } tobeVirtualMetadata.add(mvRelated); + foundAtLeastOneValue = true; } } + if (!foundAtLeastOneValue) { + MetadataValueDTO mvRelated = new MetadataValueDTO(); + mvRelated.setSchema(VIRTUAL_METADATA_SCHEMA); + mvRelated.setElement(VIRTUAL_METADATA_ELEMENT); + mvRelated.setQualifier(getVirtualQualifier()); + mvRelated.setValue(PLACEHOLDER_PARENT_METADATA_VALUE); + tobeVirtualMetadata.add(mvRelated); + } } tobeVirtualMetadataMap.put(authority, tobeVirtualMetadata); } @@ -225,8 +228,10 @@ private List getObsoleteVirtualFields(Item item) { } private Set getVirtualSources(Item item) { - return itemService.getMetadataByMetadataString(item, sourceItemMetadataField).stream() - .filter(mv -> UUIDUtils.fromString(mv.getAuthority()) != null).map(mv -> mv.getAuthority()) + return sourceItemMetadataFields.stream() + .flatMap(field -> itemService.getMetadataByMetadataString(item, field).stream()) + .filter(mv -> UUIDUtils.fromString(mv.getAuthority()) != null) + .map(mv -> mv.getAuthority()) .collect(Collectors.toSet()); } @@ -276,7 +281,9 @@ private boolean performEnhancement(Context context, Item item) throws SQLExcepti Map> currentVirtualsMap = getCurrentVirtualsMap(item); Set virtualSources = getVirtualSources(item); for (String authority : virtualSources) { + boolean foundAtLeastOne = false; if (!currentVirtualsMap.containsKey(authority)) { + result = true; Item relatedItem = findRelatedEntityItem(context, authority); if (relatedItem == null) { addVirtualField(context, item, PLACEHOLDER_PARENT_METADATA_VALUE, null, null, Choices.CF_UNSET); @@ -284,20 +291,22 @@ private boolean performEnhancement(Context context, Item item) throws SQLExcepti continue; } - List relatedItemMetadataValues = getMetadataValues(relatedItem, - relatedItemMetadataField); - if (relatedItemMetadataValues.isEmpty()) { + for (String relatedItemMetadataField : relatedItemMetadataFields) { + List relatedItemMetadataValues = getMetadataValues(relatedItem, + relatedItemMetadataField); + for (MetadataValue relatedItemMetadataValue : relatedItemMetadataValues) { + foundAtLeastOne = true; + addVirtualField(context, item, relatedItemMetadataValue.getValue(), + relatedItemMetadataValue.getAuthority(), relatedItemMetadataValue.getLanguage(), + relatedItemMetadataValue.getConfidence()); + addVirtualSourceField(context, item, authority); + } + } + if (!foundAtLeastOne) { addVirtualField(context, item, PLACEHOLDER_PARENT_METADATA_VALUE, null, null, Choices.CF_UNSET); addVirtualSourceField(context, item, authority); continue; } - for (MetadataValue relatedItemMetadataValue : relatedItemMetadataValues) { - addVirtualField(context, item, relatedItemMetadataValue.getValue(), - relatedItemMetadataValue.getAuthority(), relatedItemMetadataValue.getLanguage(), - relatedItemMetadataValue.getConfidence()); - addVirtualSourceField(context, item, authority); - } - result = true; } } return result; @@ -340,12 +349,28 @@ public void setSourceEntityType(String sourceEntityType) { this.sourceEntityType = sourceEntityType; } + @Deprecated public void setSourceItemMetadataField(String sourceItemMetadataField) { - this.sourceItemMetadataField = sourceItemMetadataField; + LOGGER.warn( + "RelatedEntityItemEnhancer configured using the old single source item metadata field, " + + "please update the configuration to use the list"); + this.sourceItemMetadataFields = List.of(sourceItemMetadataField); } + @Deprecated public void setRelatedItemMetadataField(String relatedItemMetadataField) { - this.relatedItemMetadataField = relatedItemMetadataField; + LOGGER.warn( + "RelatedEntityItemEnhancer configured using the old single related item metadata field, " + + "please update the configuration to use the list"); + this.relatedItemMetadataFields = List.of(relatedItemMetadataField); + } + + public void setRelatedItemMetadataFields(List relatedItemMetadataFields) { + this.relatedItemMetadataFields = relatedItemMetadataFields; + } + + public void setSourceItemMetadataFields(List sourceItemMetadataFields) { + this.sourceItemMetadataFields = sourceItemMetadataFields; } } diff --git a/dspace-api/src/test/data/dspaceFolder/config/spring/api/extra-metadata-enhancers-for-test.xml b/dspace-api/src/test/data/dspaceFolder/config/spring/api/extra-metadata-enhancers-for-test.xml new file mode 100644 index 00000000000..0311d8a26aa --- /dev/null +++ b/dspace-api/src/test/data/dspaceFolder/config/spring/api/extra-metadata-enhancers-for-test.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + dc.contributor.author + dc.contributor.editor + + + + + person.affiliation.name + person.identifier.orcid + + + + + + diff --git a/dspace-api/src/test/java/org/dspace/app/bulkimport/service/BulkImportWorkbookBuilderIT.java b/dspace-api/src/test/java/org/dspace/app/bulkimport/service/BulkImportWorkbookBuilderIT.java index bef8ca45c09..4d4af87ddaa 100644 --- a/dspace-api/src/test/java/org/dspace/app/bulkimport/service/BulkImportWorkbookBuilderIT.java +++ b/dspace-api/src/test/java/org/dspace/app/bulkimport/service/BulkImportWorkbookBuilderIT.java @@ -221,7 +221,7 @@ public void testWorkbookBuildingFromItemDtos() throws Exception { with("dc.contributor.author", "White, Walter", authorId, 600), with("oairecerif.author.affiliation", PLACEHOLDER_PARENT_METADATA_VALUE), with("cris.virtual.department", PLACEHOLDER_PARENT_METADATA_VALUE), - with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE))); + with("cris.virtual.orcid", PLACEHOLDER_PARENT_METADATA_VALUE))); assertThat(getItemBitstreamsByBundle(firstItem, "ORIGINAL"), contains( bitstreamWith("Bitstream 1", "First bitstream content"), @@ -242,8 +242,8 @@ public void testWorkbookBuildingFromItemDtos() throws Exception { with("oairecerif.author.affiliation", "Company", 1), with("cris.virtual.department", PLACEHOLDER_PARENT_METADATA_VALUE), with("cris.virtual.department", PLACEHOLDER_PARENT_METADATA_VALUE), - with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE), - with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE) + with("cris.virtual.orcid", PLACEHOLDER_PARENT_METADATA_VALUE), + with("cris.virtual.orcid", PLACEHOLDER_PARENT_METADATA_VALUE) )); assertThat(getItemBitstreamsByBundle(secondItem, "ORIGINAL"), contains( diff --git a/dspace-api/src/test/java/org/dspace/content/enhancer/consumer/ItemEnhancerConsumerIT.java b/dspace-api/src/test/java/org/dspace/content/enhancer/consumer/ItemEnhancerConsumerIT.java index aa440574c07..b2b34c1074f 100644 --- a/dspace-api/src/test/java/org/dspace/content/enhancer/consumer/ItemEnhancerConsumerIT.java +++ b/dspace-api/src/test/java/org/dspace/content/enhancer/consumer/ItemEnhancerConsumerIT.java @@ -19,15 +19,19 @@ import java.sql.SQLException; import java.util.List; +import java.util.stream.Collectors; +import org.apache.commons.codec.binary.StringUtils; import org.dspace.AbstractIntegrationTestWithDatabase; import org.dspace.authorize.AuthorizeException; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; import org.dspace.builder.ItemBuilder; +import org.dspace.builder.MetadataFieldBuilder; import org.dspace.builder.WorkspaceItemBuilder; import org.dspace.content.Collection; import org.dspace.content.Item; +import org.dspace.content.MetadataSchema; import org.dspace.content.MetadataValue; import org.dspace.content.WorkspaceItem; import org.dspace.content.factory.ContentServiceFactory; @@ -84,8 +88,8 @@ public void testSingleMetadataValueEnhancement() throws Exception { assertThat(metadataValues, hasSize(11)); assertThat(metadataValues, hasItem(with("cris.virtual.department", "4Science"))); assertThat(metadataValues, hasItem(with("cris.virtualsource.department", personId))); - assertThat(metadataValues, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE))); - assertThat(metadataValues, hasItem(with("cris.virtualsource.author-orcid", personId))); + assertThat(metadataValues, hasItem(with("cris.virtual.orcid", PLACEHOLDER_PARENT_METADATA_VALUE))); + assertThat(metadataValues, hasItem(with("cris.virtualsource.orcid", personId))); MetadataValue virtualField = getFirstMetadataValue(publication, "cris.virtual.department"); @@ -102,8 +106,8 @@ public void testSingleMetadataValueEnhancement() throws Exception { assertThat(metadataValues, hasItem(with("dc.contributor.author", "Walter White", personId, 600))); assertThat(metadataValues, hasItem(with("cris.virtual.department", "4Science"))); assertThat(metadataValues, hasItem(with("cris.virtualsource.department", personId))); - assertThat(metadataValues, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE))); - assertThat(metadataValues, hasItem(with("cris.virtualsource.author-orcid", personId))); + assertThat(metadataValues, hasItem(with("cris.virtual.orcid", PLACEHOLDER_PARENT_METADATA_VALUE))); + assertThat(metadataValues, hasItem(with("cris.virtualsource.orcid", personId))); assertThat(virtualField, equalTo(getFirstMetadataValue(publication, "cris.virtual.department"))); assertThat(virtualSourceField, equalTo(getFirstMetadataValue(publication, "cris.virtualsource.department"))); @@ -135,7 +139,7 @@ public void testManyMetadataValuesEnhancement() throws Exception { .withAuthor("Red Smith") .withAuthor("Walter White", person1.getID().toString()) .withAuthor("John Smith", person2.getID().toString()) - .withAuthor("Jesse Pinkman", person3.getID().toString()) + .withEditor("Jesse Pinkman", person3.getID().toString()) .build(); context.restoreAuthSystemState(); @@ -146,7 +150,7 @@ public void testManyMetadataValuesEnhancement() throws Exception { assertThat(values, hasItem(with("dc.contributor.author", "Red Smith"))); assertThat(values, hasItem(with("dc.contributor.author", "Walter White", person1.getID().toString(), 1, 600))); assertThat(values, hasItem(with("dc.contributor.author", "John Smith", person2.getID().toString(), 2, 600))); - assertThat(values, hasItem(with("dc.contributor.author", "Jesse Pinkman", person3.getID().toString(), 3, 600))); + assertThat(values, hasItem(with("dc.contributor.editor", "Jesse Pinkman", person3.getID().toString(), 0, 600))); // virtual source and virtual metadata are not required to respect the order of the source metadata assertThat(values, hasItem(withNoPlace("cris.virtualsource.department", person1.getID().toString()))); assertThat(values, hasItem(withNoPlace("cris.virtualsource.department", person2.getID().toString()))); @@ -154,17 +158,17 @@ public void testManyMetadataValuesEnhancement() throws Exception { assertThat(values, hasItem(withNoPlace("cris.virtual.department", PLACEHOLDER_PARENT_METADATA_VALUE))); assertThat(values, hasItem(withNoPlace("cris.virtual.department", "4Science"))); assertThat(values, hasItem(withNoPlace("cris.virtual.department", "University of Rome"))); - assertThat(values, hasItem(withNoPlace("cris.virtualsource.author-orcid", person1.getID().toString()))); - assertThat(values, hasItem(withNoPlace("cris.virtualsource.author-orcid", person2.getID().toString()))); - assertThat(values, hasItem(withNoPlace("cris.virtualsource.author-orcid", person3.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.orcid", person1.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.orcid", person2.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.orcid", person3.getID().toString()))); // we can check with the position as all the values are expected to be placeholder - assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 0))); - assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 1))); - assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 2))); + assertThat(values, hasItem(with("cris.virtual.orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 0))); + assertThat(values, hasItem(with("cris.virtual.orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 1))); + assertThat(values, hasItem(with("cris.virtual.orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 2))); assertThat(getMetadataValues(publication, "cris.virtual.department"), hasSize(3)); assertThat(getMetadataValues(publication, "cris.virtualsource.department"), hasSize(3)); - assertThat(getMetadataValues(publication, "cris.virtual.author-orcid"), hasSize(3)); - assertThat(getMetadataValues(publication, "cris.virtualsource.author-orcid"), hasSize(3)); + assertThat(getMetadataValues(publication, "cris.virtual.orcid"), hasSize(3)); + assertThat(getMetadataValues(publication, "cris.virtualsource.orcid"), hasSize(3)); } @@ -256,15 +260,15 @@ public void testEnhancementWithMetadataRemoval() throws Exception { assertThat(getMetadataValues(publication, "cris.virtual.department"), hasSize(3)); assertThat(getMetadataValues(publication, "cris.virtualsource.department"), hasSize(3)); - assertThat(values, hasItem(withNoPlace("cris.virtualsource.author-orcid", person1.getID().toString()))); - assertThat(values, hasItem(withNoPlace("cris.virtualsource.author-orcid", person2.getID().toString()))); - assertThat(values, hasItem(withNoPlace("cris.virtualsource.author-orcid", person3.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.orcid", person1.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.orcid", person2.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.orcid", person3.getID().toString()))); // we can check with the position as all the values are expected to be placeholder - assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 0))); - assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 1))); - assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 2))); - assertThat(getMetadataValues(publication, "cris.virtual.author-orcid"), hasSize(3)); - assertThat(getMetadataValues(publication, "cris.virtualsource.author-orcid"), hasSize(3)); + assertThat(values, hasItem(with("cris.virtual.orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 0))); + assertThat(values, hasItem(with("cris.virtual.orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 1))); + assertThat(values, hasItem(with("cris.virtual.orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 2))); + assertThat(getMetadataValues(publication, "cris.virtual.orcid"), hasSize(3)); + assertThat(getMetadataValues(publication, "cris.virtualsource.orcid"), hasSize(3)); MetadataValue authorToRemove = getMetadataValues(publication, "dc.contributor.author").get(1); @@ -284,15 +288,15 @@ public void testEnhancementWithMetadataRemoval() throws Exception { assertThat(values, hasItem(withNoPlace("cris.virtualsource.department", person3.getID().toString()))); assertThat(values, hasItem(withNoPlace("cris.virtual.department", "4Science"))); assertThat(values, hasItem(withNoPlace("cris.virtual.department", "University of Rome"))); - assertThat(values, hasItem(withNoPlace("cris.virtualsource.author-orcid", person1.getID().toString()))); - assertThat(values, hasItem(withNoPlace("cris.virtualsource.author-orcid", person3.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.orcid", person1.getID().toString()))); + assertThat(values, hasItem(withNoPlace("cris.virtualsource.orcid", person3.getID().toString()))); // we can check with the position as all the values are expected to be placeholder - assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 0))); - assertThat(values, hasItem(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 1))); + assertThat(values, hasItem(with("cris.virtual.orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 0))); + assertThat(values, hasItem(with("cris.virtual.orcid", PLACEHOLDER_PARENT_METADATA_VALUE, 1))); assertThat(getMetadataValues(publication, "cris.virtual.department"), hasSize(2)); assertThat(getMetadataValues(publication, "cris.virtualsource.department"), hasSize(2)); - assertThat(getMetadataValues(publication, "cris.virtual.author-orcid"), hasSize(2)); - assertThat(getMetadataValues(publication, "cris.virtualsource.author-orcid"), hasSize(2)); + assertThat(getMetadataValues(publication, "cris.virtual.orcid"), hasSize(2)); + assertThat(getMetadataValues(publication, "cris.virtualsource.orcid"), hasSize(2)); } @@ -354,11 +358,11 @@ public void testEnhancementAfterItemUpdate() throws Exception { with("dc.contributor.author", "Walter White", personId, 2, 600), with("dc.contributor.author", "Gus Fring", 3))); - assertThat(getMetadataValues(publication, "cris.virtual.author-orcid"), contains( - with("cris.virtual.author-orcid", "0000-0000-1111-2222"))); + assertThat(getMetadataValues(publication, "cris.virtual.orcid"), contains( + with("cris.virtual.orcid", "0000-0000-1111-2222"))); - assertThat(getMetadataValues(publication, "cris.virtualsource.author-orcid"), contains( - with("cris.virtualsource.author-orcid", personId))); + assertThat(getMetadataValues(publication, "cris.virtualsource.orcid"), contains( + with("cris.virtualsource.orcid", personId))); context.turnOffAuthorisationSystem(); itemService.addMetadata(context, publication, "dc", "title", "alternative", null, "Other name"); @@ -372,12 +376,89 @@ public void testEnhancementAfterItemUpdate() throws Exception { with("dc.contributor.author", "Walter White", personId, 2, 600), with("dc.contributor.author", "Gus Fring", 3))); - assertThat(getMetadataValues(publication, "cris.virtual.author-orcid"), contains( - with("cris.virtual.author-orcid", "0000-0000-1111-2222"))); + assertThat(getMetadataValues(publication, "cris.virtual.orcid"), contains( + with("cris.virtual.orcid", "0000-0000-1111-2222"))); + + assertThat(getMetadataValues(publication, "cris.virtualsource.orcid"), contains( + with("cris.virtualsource.orcid", personId))); + + } + + @Test + public void testMultipleRelatedItemValuesEnhancement() throws Exception { + + context.turnOffAuthorisationSystem(); + MetadataSchema schema = ContentServiceFactory.getInstance() + .getMetadataSchemaService().find(context, "cris"); + MetadataFieldBuilder.createMetadataField(context, schema, "virtual", "testmultival", null); + MetadataFieldBuilder.createMetadataField(context, schema, "virtualsource", "testmultival", null); + + Item person1 = ItemBuilder.createItem(context, collection) + .withTitle("Walter White") + .withPersonMainAffiliation("4Science") + .withPersonMainAffiliation("DSpace") + .withOrcidIdentifier("orcid1") + .build(); + + Item person2 = ItemBuilder.createItem(context, collection) + .withTitle("John Smith") + .build(); + + Item person3 = ItemBuilder.createItem(context, collection) + .withTitle("Jesse Pinkman") + .withPersonMainAffiliation("University of Rome") + .build(); + + Item testEntity = ItemBuilder.createItem(context, collection) + .withTitle("Test publication") + // let's use our custom entity for test purpose, see extra-metadata-enhancers-for-test.xml + .withEntityType("TestEntity") + .withAuthor("Red Smith") + .withAuthor("Walter White", person1.getID().toString()) + .withAuthor("John Smith", person2.getID().toString()) + .withEditor("Jesse Pinkman", person3.getID().toString()) + .build(); + + context.restoreAuthSystemState(); + testEntity = commitAndReload(testEntity); - assertThat(getMetadataValues(publication, "cris.virtualsource.author-orcid"), contains( - with("cris.virtualsource.author-orcid", personId))); + List values = testEntity.getMetadata(); + assertThat(values, hasItem(with("dc.contributor.author", "Red Smith"))); + assertThat(values, hasItem(with("dc.contributor.author", "Walter White", person1.getID().toString(), 1, 600))); + assertThat(values, hasItem(with("dc.contributor.author", "John Smith", person2.getID().toString(), 2, 600))); + assertThat(values, hasItem(with("dc.contributor.editor", "Jesse Pinkman", person3.getID().toString(), 0, 600))); + // virtual source and virtual metadata are not required to respect the order of the source metadata + List posPerson1 = getPlacesAsVirtualSource(person1, testEntity, "cris.virtualsource.testmultival"); + List posPerson2 = getPlacesAsVirtualSource(person2, testEntity, "cris.virtualsource.testmultival"); + List posPerson3 = getPlacesAsVirtualSource(person3, testEntity, "cris.virtualsource.testmultival"); + assertThat(values, + hasItem(with("cris.virtualsource.testmultival", person1.getID().toString(), posPerson1.get(0)))); + assertThat(values, hasItem(with("cris.virtual.testmultival", "4Science", posPerson1.get(0)))); + assertThat(values, + hasItem(with("cris.virtualsource.testmultival", person1.getID().toString(), posPerson1.get(1)))); + assertThat(values, hasItem(with("cris.virtual.testmultival", "DSpace", posPerson1.get(1)))); + assertThat(values, + hasItem(with("cris.virtualsource.testmultival", person1.getID().toString(), posPerson1.get(2)))); + assertThat(values, hasItem(with("cris.virtual.testmultival", "orcid1", posPerson1.get(2)))); + + assertThat(values, + hasItem(with("cris.virtualsource.testmultival", person2.getID().toString(), posPerson2.get(0)))); + assertThat(values, + hasItem(with("cris.virtual.testmultival", PLACEHOLDER_PARENT_METADATA_VALUE, posPerson2.get(0)))); + + assertThat(values, + hasItem(with("cris.virtualsource.testmultival", person3.getID().toString(), posPerson3.get(0)))); + assertThat(values, hasItem(with("cris.virtual.testmultival", "University of Rome", posPerson3.get(0)))); + + assertThat(getMetadataValues(testEntity, "cris.virtualsource.testmultival"), hasSize(5)); + assertThat(getMetadataValues(testEntity, "cris.virtual.testmultival"), hasSize(5)); + + } + private List getPlacesAsVirtualSource(Item person1, Item publication, String metadata) { + return getMetadataValues(publication, metadata).stream() + .filter(mv -> StringUtils.equals(mv.getValue(), person1.getID().toString())).map(mv -> mv.getPlace()) + .collect(Collectors.toList()); } private MetadataValue getFirstMetadataValue(Item item, String metadataField) { diff --git a/dspace-api/src/test/java/org/dspace/content/enhancer/script/ItemEnhancerScriptIT.java b/dspace-api/src/test/java/org/dspace/content/enhancer/script/ItemEnhancerScriptIT.java index f8b2b0d2d77..6d67c67a10b 100644 --- a/dspace-api/src/test/java/org/dspace/content/enhancer/script/ItemEnhancerScriptIT.java +++ b/dspace-api/src/test/java/org/dspace/content/enhancer/script/ItemEnhancerScriptIT.java @@ -24,6 +24,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.UUID; import org.dspace.AbstractIntegrationTestWithDatabase; import org.dspace.app.launcher.ScriptLauncher; @@ -39,6 +40,7 @@ import org.dspace.content.WorkspaceItem; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.ItemService; +import org.dspace.core.CrisConstants; import org.dspace.core.ReloadableEntity; import org.dspace.event.factory.EventServiceFactory; import org.dspace.event.service.EventService; @@ -138,24 +140,38 @@ public void testItemsEnhancement() throws Exception { .withAuthor("Jesse Pinkman", secondAuthorId) .build(); - WorkspaceItem thirdPublication = WorkspaceItemBuilder.createWorkspaceItem(context, collection) - .withTitle("Test publication 3") + final String randomUUID = UUID.randomUUID().toString(); + Item thirdPublication = ItemBuilder.createItem(context, collection) + .withTitle("Test publication 3") + .withEntityType("Publication") + .withAuthor("Walter White", firstAuthorId) + .withAuthor("Jesse Pinkman", secondAuthorId) + // same author multiple time + .withAuthor("Walter White", firstAuthorId) + // an author is also an editor + .withEditor("Jesse Pinkman", secondAuthorId) + .withEditor("Editor WithExternaAuthority", "external-authority") + .withEditor("Editor WithExternaUUIDAuthority", randomUUID) + .build(); + + WorkspaceItem wsPublication = WorkspaceItemBuilder.createWorkspaceItem(context, collection) + .withTitle("Test workspace publication") .withEntityType("Publication") - .withAuthor("Jesse Pinkman", secondAuthorId) + .withEditor("Jesse Pinkman", secondAuthorId) .build(); context.commit(); firstPublication = reload(firstPublication); secondPublication = reload(secondPublication); - thirdPublication = reload(thirdPublication); + wsPublication = reload(wsPublication); assertThat(getMetadataValues(firstPublication, "cris.virtual.department"), empty()); assertThat(getMetadataValues(firstPublication, "cris.virtualsource.department"), empty()); assertThat(getMetadataValues(secondPublication, "cris.virtual.department"), empty()); assertThat(getMetadataValues(secondPublication, "cris.virtualsource.department"), empty()); - assertThat(getMetadataValues(thirdPublication, "cris.virtual.department"), empty()); - assertThat(getMetadataValues(thirdPublication, "cris.virtualsource.department"), empty()); + assertThat(getMetadataValues(wsPublication, "cris.virtual.department"), empty()); + assertThat(getMetadataValues(wsPublication, "cris.virtualsource.department"), empty()); TestDSpaceRunnableHandler runnableHandler = runScript(false); @@ -164,15 +180,16 @@ public void testItemsEnhancement() throws Exception { firstPublication = reload(firstPublication); secondPublication = reload(secondPublication); + thirdPublication = reload(thirdPublication); + wsPublication = reload(wsPublication); assertThat(getMetadataValues(firstPublication, "cris.virtual.department"), hasSize(1)); assertThat(getMetadataValues(firstPublication, "cris.virtualsource.department"), hasSize(1)); + assertThat(firstPublication.getMetadata(), hasItem(with("cris.virtual.department", "4Science"))); + assertThat(firstPublication.getMetadata(), hasItem(with("cris.virtualsource.department", firstAuthorId))); assertThat(getMetadataValues(secondPublication, "cris.virtual.department"), hasSize(2)); assertThat(getMetadataValues(secondPublication, "cris.virtualsource.department"), hasSize(2)); - - assertThat(firstPublication.getMetadata(), hasItem(with("cris.virtual.department", "4Science"))); - assertThat(firstPublication.getMetadata(), hasItem(with("cris.virtualsource.department", firstAuthorId))); assertThat(getMetadataValues(secondPublication, "cris.virtual.department"), containsInAnyOrder( withNoPlace("cris.virtual.department", "4Science"), @@ -181,8 +198,22 @@ public void testItemsEnhancement() throws Exception { containsInAnyOrder( withNoPlace("cris.virtualsource.department", firstAuthorId), withNoPlace("cris.virtualsource.department", secondAuthorId))); - assertThat(getMetadataValues(thirdPublication, "cris.virtual.department"), empty()); - assertThat(getMetadataValues(thirdPublication, "cris.virtualsource.department"), empty()); + + assertThat(getMetadataValues(thirdPublication, "cris.virtual.department"), hasSize(3)); + assertThat(getMetadataValues(thirdPublication, "cris.virtualsource.department"), hasSize(3)); + assertThat(getMetadataValues(thirdPublication, "cris.virtual.department"), + containsInAnyOrder( + withNoPlace("cris.virtual.department", "4Science"), + withNoPlace("cris.virtual.department", CrisConstants.PLACEHOLDER_PARENT_METADATA_VALUE), + withNoPlace("cris.virtual.department", "Company"))); + assertThat(getMetadataValues(thirdPublication, "cris.virtualsource.department"), + containsInAnyOrder( + withNoPlace("cris.virtualsource.department", randomUUID), + withNoPlace("cris.virtualsource.department", firstAuthorId), + withNoPlace("cris.virtualsource.department", secondAuthorId))); + + assertThat(getMetadataValues(wsPublication, "cris.virtual.department"), empty()); + assertThat(getMetadataValues(wsPublication, "cris.virtualsource.department"), empty()); } @@ -281,7 +312,7 @@ public void testItemEnhancementWithForce() throws Exception { Item publication = ItemBuilder.createItem(context, collection) .withTitle("Test publication 2 ") .withEntityType("Publication") - .withAuthor("Walter White", firstAuthorId) + .withEditor("Walter White", firstAuthorId) .withAuthor("Jesse Pinkman", secondAuthorId) .build(); @@ -310,7 +341,7 @@ public void testItemEnhancementWithForce() throws Exception { context.turnOffAuthorisationSystem(); - MetadataValue authorToRemove = getMetadataValues(publication, "dc.contributor.author").get(1); + MetadataValue authorToRemove = getMetadataValues(publication, "dc.contributor.author").get(0); itemService.removeMetadataValues(context, publication, List.of(authorToRemove)); replaceMetadata(firstAuthor, "person", "affiliation", "name", "University"); @@ -413,7 +444,7 @@ public void testItemEnhancementSourceWithoutAuthority() throws Exception { .withTitle("Test publication 2 ") .withEntityType("Publication") .withAuthor("Jesse Pinkman") - .withAuthor("Jesse Smith", secondAuthorId) + .withEditor("Jesse Smith", secondAuthorId) .build(); context.commit(); diff --git a/dspace-api/src/test/java/org/dspace/harvest/OAIHarvesterIT.java b/dspace-api/src/test/java/org/dspace/harvest/OAIHarvesterIT.java index b305ccc1806..9c402b4e3a0 100644 --- a/dspace-api/src/test/java/org/dspace/harvest/OAIHarvesterIT.java +++ b/dspace-api/src/test/java/org/dspace/harvest/OAIHarvesterIT.java @@ -781,7 +781,7 @@ public void testRunHarvestWithPublicationAndThenPerson() throws Exception { assertThat(values, hasItems(with("dc.identifier.doi", "10.1007/978-3-642-35233-1_18"))); assertThat(values, hasItems(with("oairecerif.author.affiliation", PLACEHOLDER_PARENT_METADATA_VALUE))); assertThat(values, hasItems(with("cris.virtual.department", PLACEHOLDER_PARENT_METADATA_VALUE))); - assertThat(values, hasItems(with("cris.virtual.author-orcid", PLACEHOLDER_PARENT_METADATA_VALUE))); + assertThat(values, hasItems(with("cris.virtual.orcid", PLACEHOLDER_PARENT_METADATA_VALUE))); assertThat(values, hasItems(with("cris.sourceId", "test-harvest::3"))); assertThat(values, hasItems(with("dspace.entity.type", "Publication"))); @@ -889,8 +889,8 @@ public void testRunHarvestWithPersonAndThenPublication() throws Exception { assertThat(values, hasItems(with("dspace.entity.type", "Publication"))); assertThat(values, hasItems(with("cris.virtual.department", PLACEHOLDER_PARENT_METADATA_VALUE))); assertThat(values, hasItems(with("cris.virtualsource.department", UUIDUtils.toString(person.getID())))); - assertThat(values, hasItems(with("cris.virtual.author-orcid", "0000-0002-9079-5932"))); - assertThat(values, hasItems(with("cris.virtualsource.author-orcid", + assertThat(values, hasItems(with("cris.virtual.orcid", "0000-0002-9079-5932"))); + assertThat(values, hasItems(with("cris.virtualsource.orcid", UUIDUtils.toString(person.getID())))); MetadataValue author = itemService.getMetadata(publication, "dc", "contributor", "author", Item.ANY).get(0); diff --git a/dspace/config/registries/cris-types.xml b/dspace/config/registries/cris-types.xml index 7f0f8d7ec63..90597ddffbc 100644 --- a/dspace/config/registries/cris-types.xml +++ b/dspace/config/registries/cris-types.xml @@ -152,14 +152,7 @@ cris virtual - author-orcid - - - - - cris - virtual - editor-orcid + orcid @@ -173,14 +166,7 @@ cris virtualsource - author-orcid - - - - - cris - virtualsource - editor-orcid + orcid diff --git a/dspace/config/spring/api/metadata-enhancers.xml b/dspace/config/spring/api/metadata-enhancers.xml index e36727959c2..eb87c320269 100644 --- a/dspace/config/spring/api/metadata-enhancers.xml +++ b/dspace/config/spring/api/metadata-enhancers.xml @@ -25,38 +25,50 @@ - + + + dc.contributor.author + dc.contributor.editor + + - - - - + + + + dc.contributor.author + dc.contributor.editor + + + + - + + + dc.contributor.author + dc.contributor.editor + + - + - + + + dc.contributor.author + dc.contributor.editor + + - + - - - - - - - - From e0bc2eb589b869f4f6de0dc817698add4f457999 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Wed, 6 Mar 2024 08:44:06 +0100 Subject: [PATCH 8/9] [DSC-1550] Add missing SupervisionOrder discovery configuration --- dspace/config/spring/api/discovery.xml | 82 +++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 3 deletions(-) diff --git a/dspace/config/spring/api/discovery.xml b/dspace/config/spring/api/discovery.xml index de6145afd67..3c7a70cf9e0 100644 --- a/dspace/config/spring/api/discovery.xml +++ b/dspace/config/spring/api/discovery.xml @@ -61,9 +61,6 @@ dc.contributor.editor - - - @@ -72,6 +69,9 @@ + + + @@ -91,6 +91,7 @@ + @@ -785,6 +786,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + search.resourcetype:WorkspaceItem AND supervised:true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Date: Mon, 11 Mar 2024 15:00:41 +0100 Subject: [PATCH 9/9] [DSC-1587] Add check for item submitter --- .../org/dspace/app/rest/converter/EditItemConverter.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EditItemConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EditItemConverter.java index f19ce63d6b5..8a2135e032b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EditItemConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EditItemConverter.java @@ -7,6 +7,7 @@ */ package org.dspace.app.rest.converter; +import java.util.Objects; import javax.servlet.http.HttpServletRequest; import org.apache.logging.log4j.Logger; @@ -138,7 +139,9 @@ protected void fillFromModel(EditItem obj, EditItemRest rest, Projection project } rest.setCollection(collection != null ? converter.toRest(collection, projection) : null); rest.setItem(converter.toRest(item, projection)); - rest.setSubmitter(converter.toRest(submitter, projection)); + if (Objects.nonNull(submitter)) { + rest.setSubmitter(converter.toRest(submitter, projection)); + } } private void addValidationErrorsToItem(EditItem obj, EditItemRest rest) {