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 7a6f2927092..4041df194ce 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 @@ -49,10 +49,13 @@ public class RelatedEntityItemEnhancer extends AbstractItemEnhancer { @Autowired private ItemService itemService; + @Autowired + private RelatedEntityItemEnhancerUtils relatedEntityItemEnhancerUtils; + /** - * the entity that can be extended by this enhancer, i.e. Publication + * the entities that can be extended by this enhancer, i.e. Publication */ - private String sourceEntityType; + private List sourceEntityTypes; /** * the metadata used to navigate the relation, i.e. dc.contributor.author @@ -66,7 +69,7 @@ public class RelatedEntityItemEnhancer extends AbstractItemEnhancer { @Override public boolean canEnhance(Context context, Item item) { - return sourceEntityType == null || sourceEntityType.equals(itemService.getEntityTypeLabel(item)); + return sourceEntityTypes == null || sourceEntityTypes.contains(itemService.getEntityTypeLabel(item)); } @Override @@ -81,7 +84,8 @@ public boolean enhance(Context context, Item item, boolean deepMode) { throw new SQLRuntimeException(e); } } else { - Map> currMetadataValues = getCurrentVirtualsMap(item); + Map> currMetadataValues = relatedEntityItemEnhancerUtils + .getCurrentVirtualsMap(item, getVirtualQualifier()); Map> toBeMetadataValues = getToBeVirtualMetadata(context, item); if (!equivalent(currMetadataValues, toBeMetadataValues)) { try { @@ -212,7 +216,8 @@ private boolean cleanObsoleteVirtualFields(Context context, Item item) throws SQ private List getObsoleteVirtualFields(Item item) { List obsoleteVirtualFields = new ArrayList<>(); - Map> currentVirtualsMap = getCurrentVirtualsMap(item); + Map> currentVirtualsMap = relatedEntityItemEnhancerUtils + .getCurrentVirtualsMap(item, getVirtualQualifier()); Set virtualSources = getVirtualSources(item); for (String authority : currentVirtualsMap.keySet()) { if (!virtualSources.contains(authority)) { @@ -235,41 +240,6 @@ private Set getVirtualSources(Item item) { .collect(Collectors.toSet()); } - 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); - - 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 (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 mvalues = currentVirtualsMap.get(authority); - if (mvalues == null) { - mvalues = new ArrayList(); - } - if (i < generated.size()) { - mvalues.add(generated.get(i)); - } - currentVirtualsMap.put(authority, mvalues); - } - return currentVirtualsMap; - } - private Optional getRelatedVirtualField(Item item, int pos) { return getVirtualFields(item).stream() .skip(pos) @@ -278,7 +248,8 @@ private Optional getRelatedVirtualField(Item item, int pos) { private boolean performEnhancement(Context context, Item item) throws SQLException { boolean result = false; - Map> currentVirtualsMap = getCurrentVirtualsMap(item); + Map> currentVirtualsMap = relatedEntityItemEnhancerUtils + .getCurrentVirtualsMap(item, getVirtualQualifier()); Set virtualSources = getVirtualSources(item); for (String authority : virtualSources) { boolean foundAtLeastOne = false; @@ -345,24 +316,8 @@ private void addVirtualSourceField(Context context, Item item, String sourceValu getVirtualQualifier(), null, sourceValueAuthority); } - public void setSourceEntityType(String sourceEntityType) { - this.sourceEntityType = sourceEntityType; - } - - @Deprecated - public void setSourceItemMetadataField(String 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) { - 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 setSourceEntityTypes(List sourceEntityTypes) { + this.sourceEntityTypes = sourceEntityTypes; } public void setRelatedItemMetadataFields(List relatedItemMetadataFields) { diff --git a/dspace-api/src/main/java/org/dspace/content/enhancer/impl/RelatedEntityItemEnhancerUtils.java b/dspace-api/src/main/java/org/dspace/content/enhancer/impl/RelatedEntityItemEnhancerUtils.java new file mode 100644 index 00000000000..064223b5642 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/content/enhancer/impl/RelatedEntityItemEnhancerUtils.java @@ -0,0 +1,72 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.content.enhancer.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.dspace.content.Item; +import org.dspace.content.MetadataValue; +import org.dspace.content.service.ItemService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * Utility methods used by {@link RelatedEntityItemEnhancer} + * + * @author Andrea Bollini (andrea.bollini at 4science.com) + * + */ +public class RelatedEntityItemEnhancerUtils { + + @Autowired + private ItemService itemService; + + private static final Logger LOGGER = LoggerFactory.getLogger(RelatedEntityItemEnhancerUtils.class); + + public Map> getCurrentVirtualsMap(Item item, String virtualQualifier) { + Map> currentVirtualsMap = new HashMap>(); + List sources = itemService.getMetadata(item, RelatedEntityItemEnhancer.VIRTUAL_METADATA_SCHEMA, + RelatedEntityItemEnhancer.VIRTUAL_SOURCE_METADATA_ELEMENT, virtualQualifier, Item.ANY); + List generated = itemService.getMetadata(item, + RelatedEntityItemEnhancer.VIRTUAL_METADATA_SCHEMA, RelatedEntityItemEnhancer.VIRTUAL_METADATA_ELEMENT, + virtualQualifier, Item.ANY); + + 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 (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 mvalues = currentVirtualsMap.get(authority); + if (mvalues == null) { + mvalues = new ArrayList(); + } + if (i < generated.size()) { + mvalues.add(generated.get(i)); + } + currentVirtualsMap.put(authority, mvalues); + } + return currentVirtualsMap; + } + +} diff --git a/dspace-api/src/main/java/org/dspace/content/integration/crosswalks/virtualfields/VirtualFieldToEnhancedMetadata.java b/dspace-api/src/main/java/org/dspace/content/integration/crosswalks/virtualfields/VirtualFieldToEnhancedMetadata.java new file mode 100644 index 00000000000..2ea11f6c4ea --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/content/integration/crosswalks/virtualfields/VirtualFieldToEnhancedMetadata.java @@ -0,0 +1,62 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.content.integration.crosswalks.virtualfields; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.dspace.content.Item; +import org.dspace.content.MetadataValue; +import org.dspace.content.enhancer.impl.RelatedEntityItemEnhancerUtils; +import org.dspace.content.factory.ContentServiceFactory; +import org.dspace.content.service.ItemService; +import org.dspace.core.Context; +import org.dspace.core.CrisConstants; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * Implementation of {@link VirtualField} that returns the values from the a + * cris.virtual. metadata using the provided in the form of + * -- as source metadata. + * Source metadata that are not found in the cris.virtualsource. leads to a PLACEHOLDER + * + * @author Andrea Bollini at 4science.comm + * + */ +public class VirtualFieldToEnhancedMetadata implements VirtualField { + + @Autowired + private ItemService itemService; + + @Autowired + private RelatedEntityItemEnhancerUtils relatedEntityItemEnhancerUtils; + + @Override + public String[] getMetadata(Context context, Item item, String fieldName) { + ItemService itemService = ContentServiceFactory.getInstance().getItemService(); + String[] fieldBits = fieldName.split("\\."); + if (fieldBits.length != 3) { + throw new IllegalArgumentException( + "VirtualFieldToEnhancedMetadata must be used specifying the EnhancedMetadata qualifier as " + + "element and the source metadata as qualifier, i.e. virtual.department.dc-contributor-author"); + } + String virtualQualifier = fieldBits[1]; + String metadata = fieldBits[2].replaceAll("-", "."); + Map> map = relatedEntityItemEnhancerUtils.getCurrentVirtualsMap(item, + virtualQualifier); + List values = itemService.getMetadataByMetadataString(item, metadata).stream() + .map(mv -> mv.getAuthority() != null && map.containsKey(mv.getAuthority()) + ? map.get(mv.getAuthority()).get(0).getValue() + : CrisConstants.PLACEHOLDER_PARENT_METADATA_VALUE) + .collect(Collectors.toList()); + String[] resultValues = values.toArray(new String[0]); + return resultValues; + } + +} 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 index 0311d8a26aa..a713d3acbcc 100644 --- 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 @@ -21,7 +21,11 @@ - + + + TestEntity + + dc.contributor.author diff --git a/dspace/config/spring/api/crosswalks.xml b/dspace/config/spring/api/crosswalks.xml index 9184a56482d..8d7bb2ae910 100644 --- a/dspace/config/spring/api/crosswalks.xml +++ b/dspace/config/spring/api/crosswalks.xml @@ -554,7 +554,9 @@ - + +