Skip to content

Commit

Permalink
DSC-1459 Allows multiple entity types for RelatedEntityItemEnhancer, …
Browse files Browse the repository at this point in the history
…provide a bridge between the ReferCrosswalk virtual and the ItemEnhancer
  • Loading branch information
abollini committed Mar 4, 2024
1 parent 59589a7 commit 0b64e6d
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> sourceEntityTypes;

/**
* the metadata used to navigate the relation, i.e. dc.contributor.author
Expand All @@ -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
Expand All @@ -81,7 +84,8 @@ public boolean enhance(Context context, Item item, boolean deepMode) {
throw new SQLRuntimeException(e);
}
} else {
Map<String, List<MetadataValue>> currMetadataValues = getCurrentVirtualsMap(item);
Map<String, List<MetadataValue>> currMetadataValues = relatedEntityItemEnhancerUtils
.getCurrentVirtualsMap(item, getVirtualQualifier());
Map<String, List<MetadataValueDTO>> toBeMetadataValues = getToBeVirtualMetadata(context, item);
if (!equivalent(currMetadataValues, toBeMetadataValues)) {
try {
Expand Down Expand Up @@ -212,7 +216,8 @@ private boolean cleanObsoleteVirtualFields(Context context, Item item) throws SQ
private List<MetadataValue> getObsoleteVirtualFields(Item item) {

List<MetadataValue> obsoleteVirtualFields = new ArrayList<>();
Map<String, List<MetadataValue>> currentVirtualsMap = getCurrentVirtualsMap(item);
Map<String, List<MetadataValue>> currentVirtualsMap = relatedEntityItemEnhancerUtils
.getCurrentVirtualsMap(item, getVirtualQualifier());
Set<String> virtualSources = getVirtualSources(item);
for (String authority : currentVirtualsMap.keySet()) {
if (!virtualSources.contains(authority)) {
Expand All @@ -235,41 +240,6 @@ private Set<String> getVirtualSources(Item item) {
.collect(Collectors.toSet());
}

private Map<String, List<MetadataValue>> getCurrentVirtualsMap(Item item) {
Map<String, List<MetadataValue>> currentVirtualsMap = new HashMap<String, List<MetadataValue>>();
List<MetadataValue> sources = itemService.getMetadata(item, VIRTUAL_METADATA_SCHEMA,
VIRTUAL_SOURCE_METADATA_ELEMENT, getVirtualQualifier(), Item.ANY);
List<MetadataValue> 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<MetadataValue> mvalues = currentVirtualsMap.get(authority);
if (mvalues == null) {
mvalues = new ArrayList<MetadataValue>();
}
if (i < generated.size()) {
mvalues.add(generated.get(i));
}
currentVirtualsMap.put(authority, mvalues);
}
return currentVirtualsMap;
}

private Optional<MetadataValue> getRelatedVirtualField(Item item, int pos) {
return getVirtualFields(item).stream()
.skip(pos)
Expand All @@ -278,7 +248,8 @@ private Optional<MetadataValue> getRelatedVirtualField(Item item, int pos) {

private boolean performEnhancement(Context context, Item item) throws SQLException {
boolean result = false;
Map<String, List<MetadataValue>> currentVirtualsMap = getCurrentVirtualsMap(item);
Map<String, List<MetadataValue>> currentVirtualsMap = relatedEntityItemEnhancerUtils
.getCurrentVirtualsMap(item, getVirtualQualifier());
Set<String> virtualSources = getVirtualSources(item);
for (String authority : virtualSources) {
boolean foundAtLeastOne = false;
Expand Down Expand Up @@ -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<String> sourceEntityTypes) {
this.sourceEntityTypes = sourceEntityTypes;
}

public void setRelatedItemMetadataFields(List<String> relatedItemMetadataFields) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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<String, List<MetadataValue>> getCurrentVirtualsMap(Item item, String virtualQualifier) {
Map<String, List<MetadataValue>> currentVirtualsMap = new HashMap<String, List<MetadataValue>>();
List<MetadataValue> sources = itemService.getMetadata(item, RelatedEntityItemEnhancer.VIRTUAL_METADATA_SCHEMA,
RelatedEntityItemEnhancer.VIRTUAL_SOURCE_METADATA_ELEMENT, virtualQualifier, Item.ANY);
List<MetadataValue> 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<MetadataValue> mvalues = currentVirtualsMap.get(authority);
if (mvalues == null) {
mvalues = new ArrayList<MetadataValue>();
}
if (i < generated.size()) {
mvalues.add(generated.get(i));
}
currentVirtualsMap.put(authority, mvalues);
}
return currentVirtualsMap;
}

}
Original file line number Diff line number Diff line change
@@ -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.<element> metadata using the <qualifier> provided in the form of
* <schema>-<element>-<qualifier> as source metadata.
* Source metadata that are not found in the cris.virtualsource.<element> 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<String, List<MetadataValue>> map = relatedEntityItemEnhancerUtils.getCurrentVirtualsMap(item,
virtualQualifier);
List<String> 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;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@
<context:annotation-config />

<bean class="org.dspace.content.enhancer.impl.RelatedEntityItemEnhancer" >
<property name="sourceEntityType" value="TestEntity" />
<property name="sourceEntityTypes">
<list>
<value>TestEntity</value>
</list>
</property>
<property name="sourceItemMetadataFields">
<list>
<value>dc.contributor.author</value>
Expand Down
4 changes: 3 additions & 1 deletion dspace/config/spring/api/crosswalks.xml
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,9 @@
</map>
</constructor-arg>
</bean>


<bean class="org.dspace.content.integration.crosswalks.virtualfields.VirtualFieldToEnhancedMetadata"
id="virtualFieldToEnhancedMetadata" />
<bean class="org.dspace.content.integration.crosswalks.virtualfields.VirtualFieldId" id="virtualFieldId"/>
<bean class="org.dspace.content.integration.crosswalks.virtualfields.VirtualFieldAuthority" id="virtualFieldAuthority"/>
<bean class="org.dspace.content.integration.crosswalks.virtualfields.VirtualFieldPrimaryDOI" id="virtualFieldPrimaryDOI"/>
Expand Down
36 changes: 14 additions & 22 deletions dspace/config/spring/api/metadata-enhancers.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,51 +23,43 @@
<bean id="org.dspace.content.enhancer.service.ItemEnhancerService"
class="org.dspace.content.enhancer.service.impl.ItemEnhancerServiceImpl" />

<bean class="org.dspace.content.enhancer.impl.RelatedEntityItemEnhancerUtils" />

<util:list id="researchOutputsEntityTypes">
<value>Publication</value>
<value>Product</value>
<value>Patent</value>
</util:list>

<bean class="org.dspace.content.enhancer.impl.RelatedEntityItemEnhancer" >
<property name="sourceEntityType" value="Publication" />
<property name="sourceEntityTypes" ref="researchOutputsEntityTypes" />
<property name="sourceItemMetadataFields">
<list>
<value>dc.contributor.author</value>
<value>dc.contributor.editor</value>
</list>
</property>
<property name="relatedItemMetadataField" value="person.affiliation.name" />
<property name="virtualQualifier" value="department" />
</bean>

<bean class="org.dspace.content.enhancer.impl.RelatedEntityItemEnhancer" >
<property name="sourceEntityType" value="Product" />
<property name="sourceItemMetadataFields">
<property name="relatedItemMetadataFields">
<list>
<value>dc.contributor.author</value>
<value>dc.contributor.editor</value>
<value>person.affiliation.name</value>
</list>
</property>
<property name="relatedItemMetadataField" value="person.affiliation.name" />
<property name="virtualQualifier" value="department" />
</bean>

<bean class="org.dspace.content.enhancer.impl.RelatedEntityItemEnhancer" >
<property name="sourceEntityType" value="Publication" />
<property name="sourceEntityTypes" ref="researchOutputsEntityTypes" />
<property name="sourceItemMetadataFields">
<list>
<value>dc.contributor.author</value>
<value>dc.contributor.editor</value>
</list>
</property>
<property name="relatedItemMetadataField" value="person.identifier.orcid" />
<property name="virtualQualifier" value="orcid" />
</bean>

<bean class="org.dspace.content.enhancer.impl.RelatedEntityItemEnhancer" >
<property name="sourceEntityType" value="Product" />
<property name="sourceItemMetadataFields">
<property name="relatedItemMetadataFields">
<list>
<value>dc.contributor.author</value>
<value>dc.contributor.editor</value>
<value>person.identifier.orcid</value>
</list>
</property>
<property name="relatedItemMetadataField" value="person.identifier.orcid" />
<property name="virtualQualifier" value="orcid" />
</bean>

Expand Down

0 comments on commit 0b64e6d

Please sign in to comment.