diff --git a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java index 8345f6ba82..b617c9c8c4 100644 --- a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java @@ -117,6 +117,9 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl implements It @Autowired(required = true) protected VirtualMetadataPopulator virtualMetadataPopulator; + @Autowired(required = true) + private RelationshipMetadataService relationshipMetadataService; + protected ItemServiceImpl() { super(); } @@ -1334,27 +1337,6 @@ prevent the generation of resource policy entry values with null dspace_object a return this.getMetadata(item, schema, element, qualifier, lang, true); } - @Override - public List getRelationshipMetadata(Item item, boolean enableVirtualMetadata) { - Context context = new Context(); - List fullMetadataValueList = new LinkedList<>(); - try { - List list = item.getMetadata(); - String entityType = getEntityTypeStringFromMetadata(list); - if (StringUtils.isNotBlank(entityType)) { - List relationships = relationshipService.findByItem(context, item); - for (Relationship relationship : relationships) { - fullMetadataValueList - .addAll(handleItemRelationship(context, item, entityType, relationship, enableVirtualMetadata)); - } - - } - } catch (SQLException e) { - log.error("Lookup for Relationships for item with uuid: " + item.getID() + " caused DSpace to crash", e); - } - return fullMetadataValueList; - } - @Override public List getMetadata(Item item, String schema, String element, String qualifier, String lang, boolean enableVirtualMetadata) { @@ -1362,7 +1344,7 @@ prevent the generation of resource policy entry values with null dspace_object a //except for relation.type which is the type of item in the model if (StringUtils.equals(schema, MetadataSchemaEnum.RELATION.getName()) && !StringUtils.equals(element, "type")) { - List relationMetadata = getRelationshipMetadata(item, false); + List relationMetadata = relationshipMetadataService.getRelationshipMetadata(item, false); List listToReturn = new LinkedList<>(); for (MetadataValue metadataValue : relationMetadata) { if (StringUtils.equals(metadataValue.getMetadataField().getElement(), element)) { @@ -1378,7 +1360,7 @@ prevent the generation of resource policy entry values with null dspace_object a List fullMetadataValueList = new LinkedList<>(); if (enableVirtualMetadata) { - fullMetadataValueList.addAll(getRelationshipMetadata(item, true)); + fullMetadataValueList.addAll(relationshipMetadataService.getRelationshipMetadata(item, true)); } fullMetadataValueList.addAll(dbMetadataValues); @@ -1417,137 +1399,7 @@ prevent the generation of resource policy entry values with null dspace_object a return listToReturn; } - //This method processes the Relationship of an Item and will return a list of RelationshipMetadataValue objects - //that are generated for this specfic relationship for the item through the config in VirtualMetadataPopulator - private List handleItemRelationship(Context context, Item item, String entityType, - Relationship relationship, - boolean enableVirtualMetadata) - throws SQLException { - List resultingMetadataValueList = new LinkedList<>(); - RelationshipType relationshipType = relationship.getRelationshipType(); - HashMap hashMaps; - String relationName = ""; - Item otherItem = null; - int place = 0; - if (StringUtils.equals(relationshipType.getLeftType().getLabel(), entityType)) { - hashMaps = virtualMetadataPopulator.getMap().get(relationshipType.getLeftLabel()); - otherItem = relationship.getRightItem(); - relationName = relationship.getRelationshipType().getLeftLabel(); - place = relationship.getLeftPlace(); - } else if (StringUtils.equals(relationshipType.getRightType().getLabel(), entityType)) { - hashMaps = virtualMetadataPopulator.getMap().get(relationshipType.getRightLabel()); - otherItem = relationship.getLeftItem(); - relationName = relationship.getRelationshipType().getRightLabel(); - place = relationship.getRightPlace(); - } else { - //No virtual metadata can be created - return resultingMetadataValueList; - } - if (hashMaps != null && enableVirtualMetadata) { - resultingMetadataValueList.addAll(handleRelationshipTypeMetadataMapping(context, item, hashMaps, - otherItem, relationName, - relationship.getID(), place)); - } - RelationshipMetadataValue relationMetadataFromOtherItem = - getRelationMetadataFromOtherItem(context, otherItem, relationName, relationship.getID(), place); - if (relationMetadataFromOtherItem != null) { - resultingMetadataValueList.add(relationMetadataFromOtherItem); - } - return resultingMetadataValueList; - } - //This method will retrieve a list of RelationshipMetadataValue objects based on the config passed along in the - //hashmaps parameter. The beans will be used to retrieve the values for the RelationshipMetadataValue objects - //and the keys of the hashmap will be used to construct the RelationshipMetadataValue object. - private List handleRelationshipTypeMetadataMapping(Context context, Item item, - HashMap hashMaps, - Item otherItem, String relationName, - Integer relationshipId, int place) - throws SQLException { - List resultingMetadataValueList = new LinkedList<>(); - for (Map.Entry entry : hashMaps.entrySet()) { - String key = entry.getKey(); - VirtualMetadataConfiguration virtualBean = entry.getValue(); - for (String value : virtualBean.getValues(context, otherItem)) { - RelationshipMetadataValue metadataValue = constructMetadataValue(context, key); - if (metadataValue != null) { - metadataValue = constructResultingMetadataValue(item, value, metadataValue, relationshipId); - metadataValue.setUseForPlace(virtualBean.getUseForPlace()); - metadataValue.setPlace(place); - if (StringUtils.isNotBlank(metadataValue.getValue())) { - resultingMetadataValueList.add(metadataValue); - } - } - } - } - return resultingMetadataValueList; - } - - private RelationshipMetadataValue getRelationMetadataFromOtherItem(Context context, Item otherItem, - String relationName, - Integer relationshipId, int place) { - RelationshipMetadataValue metadataValue = constructMetadataValue(context, - MetadataSchemaEnum.RELATION - .getName() + "." + relationName); - if (metadataValue != null) { - metadataValue.setAuthority(Constants.VIRTUAL_AUTHORITY_PREFIX + relationshipId); - metadataValue.setValue(otherItem.getID().toString()); - metadataValue.setPlace(place); - return metadataValue; - } - return null; - } - - private String getEntityTypeStringFromMetadata(List list) { - for (MetadataValue mdv : list) { - if (StringUtils.equals(mdv.getMetadataField().getMetadataSchema().getName(), - "relationship") - && StringUtils.equals(mdv.getMetadataField().getElement(), - "type")) { - - return mdv.getValue(); - } - } - return null; - } - - private RelationshipMetadataValue constructResultingMetadataValue(Item item, String value, - RelationshipMetadataValue metadataValue, - Integer relationshipId) { - metadataValue.setValue(value); - metadataValue.setAuthority(Constants.VIRTUAL_AUTHORITY_PREFIX + relationshipId); - metadataValue.setConfidence(-1); - metadataValue.setDSpaceObject(item); - return metadataValue; - } - - //This method will construct a RelationshipMetadataValue object with proper schema, element and qualifier based - //on the key String parameter passed along to it - private RelationshipMetadataValue constructMetadataValue(Context context, String key) { - String[] splittedKey = key.split("\\."); - RelationshipMetadataValue metadataValue = new RelationshipMetadataValue(); - String metadataSchema = splittedKey.length > 0 ? splittedKey[0] : null; - String metadataElement = splittedKey.length > 1 ? splittedKey[1] : null; - String metadataQualifier = splittedKey.length > 2 ? splittedKey[2] : null; - MetadataField metadataField = null; - try { - metadataField = metadataFieldService - .findByElement(context, metadataSchema, metadataElement, metadataQualifier); - } catch (SQLException e) { - log.error("Could not find element with MetadataSchema: " + metadataSchema + - ", MetadataElement: " + metadataElement + " and MetadataQualifier: " + metadataQualifier, e); - return null; - } - if (metadataField == null) { - log.error("A MetadataValue was attempted to construct with MetadataField for parameters: " + - "metadataschema: {}, metadataelement: {}, metadataqualifier: {}", - metadataSchema, metadataElement, metadataQualifier); - return null; - } - metadataValue.setMetadataField(metadataField); - metadataValue.setLanguage(Item.ANY); - return metadataValue; - } } \ No newline at end of file diff --git a/dspace-api/src/main/java/org/dspace/content/RelationshipMetadataService.java b/dspace-api/src/main/java/org/dspace/content/RelationshipMetadataService.java new file mode 100644 index 0000000000..f691cff8da --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/content/RelationshipMetadataService.java @@ -0,0 +1,19 @@ +package org.dspace.content; + +import java.util.List; + +import org.dspace.content.virtual.VirtualMetadataPopulator; + +public interface RelationshipMetadataService { + + /** + * This method retrieves a list of MetadataValue objects that get constructed from processing + * the given Item's Relationships through the config given to the {@link VirtualMetadataPopulator} + * @param item The Item that will be processed through it's Relationships + * @param enableVirtualMetadata This parameter will determine whether the list of Relationship metadata + * should be populated with metadata that is being generated through the + * VirtualMetadataPopulator functionality or not + * @return The list of MetadataValue objects constructed through the Relationships + */ + public List getRelationshipMetadata(Item item, boolean enableVirtualMetadata); +} diff --git a/dspace-api/src/main/java/org/dspace/content/RelationshipMetadataServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/RelationshipMetadataServiceImpl.java new file mode 100644 index 0000000000..a18fb6d7e6 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/content/RelationshipMetadataServiceImpl.java @@ -0,0 +1,190 @@ +package org.dspace.content; + +import java.sql.SQLException; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.Logger; +import org.dspace.content.service.MetadataFieldService; +import org.dspace.content.service.RelationshipService; +import org.dspace.content.virtual.VirtualMetadataConfiguration; +import org.dspace.content.virtual.VirtualMetadataPopulator; +import org.dspace.core.Constants; +import org.dspace.core.Context; +import org.springframework.beans.factory.annotation.Autowired; + +public class RelationshipMetadataServiceImpl implements RelationshipMetadataService { + + /** + * log4j category + */ + private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(); + + @Autowired(required = true) + protected RelationshipService relationshipService; + + @Autowired(required = true) + protected VirtualMetadataPopulator virtualMetadataPopulator; + + @Autowired(required = true) + protected MetadataFieldService metadataFieldService; + + @Override + public List getRelationshipMetadata(Item item, boolean enableVirtualMetadata) { + Context context = new Context(); + List fullMetadataValueList = new LinkedList<>(); + try { + List list = item.getMetadata(); + String entityType = getEntityTypeStringFromMetadata(list); + if (StringUtils.isNotBlank(entityType)) { + List relationships = relationshipService.findByItem(context, item); + for (Relationship relationship : relationships) { + fullMetadataValueList + .addAll(handleItemRelationship(context, item, entityType, relationship, enableVirtualMetadata)); + } + + } + } catch (SQLException e) { + log.error("Lookup for Relationships for item with uuid: " + item.getID() + " caused DSpace to crash", e); + } + return fullMetadataValueList; + } + + private String getEntityTypeStringFromMetadata(List list) { + for (MetadataValue mdv : list) { + if (StringUtils.equals(mdv.getMetadataField().getMetadataSchema().getName(), + "relationship") + && StringUtils.equals(mdv.getMetadataField().getElement(), + "type")) { + + return mdv.getValue(); + } + } + return null; + } + + //This method processes the Relationship of an Item and will return a list of RelationshipMetadataValue objects + //that are generated for this specfic relationship for the item through the config in VirtualMetadataPopulator + private List handleItemRelationship(Context context, Item item, String entityType, + Relationship relationship, + boolean enableVirtualMetadata) + throws SQLException { + List resultingMetadataValueList = new LinkedList<>(); + RelationshipType relationshipType = relationship.getRelationshipType(); + HashMap hashMaps; + String relationName; + Item otherItem; + int place = 0; + if (StringUtils.equals(relationshipType.getLeftType().getLabel(), entityType)) { + hashMaps = virtualMetadataPopulator.getMap().get(relationshipType.getLeftLabel()); + otherItem = relationship.getRightItem(); + relationName = relationship.getRelationshipType().getLeftLabel(); + place = relationship.getLeftPlace(); + } else if (StringUtils.equals(relationshipType.getRightType().getLabel(), entityType)) { + hashMaps = virtualMetadataPopulator.getMap().get(relationshipType.getRightLabel()); + otherItem = relationship.getLeftItem(); + relationName = relationship.getRelationshipType().getRightLabel(); + place = relationship.getRightPlace(); + } else { + //No virtual metadata can be created + return resultingMetadataValueList; + } + + if (hashMaps != null && enableVirtualMetadata) { + resultingMetadataValueList.addAll(handleRelationshipTypeMetadataMapping(context, item, hashMaps, + otherItem, relationName, + relationship.getID(), place)); + } + RelationshipMetadataValue relationMetadataFromOtherItem = + getRelationMetadataFromOtherItem(context, otherItem, relationName, relationship.getID(), place); + if (relationMetadataFromOtherItem != null) { + resultingMetadataValueList.add(relationMetadataFromOtherItem); + } + return resultingMetadataValueList; + } + + //This method will retrieve a list of RelationshipMetadataValue objects based on the config passed along in the + //hashmaps parameter. The beans will be used to retrieve the values for the RelationshipMetadataValue objects + //and the keys of the hashmap will be used to construct the RelationshipMetadataValue object. + private List handleRelationshipTypeMetadataMapping(Context context, Item item, + HashMap hashMaps, Item otherItem, String relationName, + Integer relationshipId, int place) throws SQLException { + + List resultingMetadataValueList = new LinkedList<>(); + for (Map.Entry entry : hashMaps.entrySet()) { + String key = entry.getKey(); + VirtualMetadataConfiguration virtualBean = entry.getValue(); + + for (String value : virtualBean.getValues(context, otherItem)) { + RelationshipMetadataValue metadataValue = constructMetadataValue(context, key); + if (metadataValue != null) { + metadataValue = constructResultingMetadataValue(item, value, metadataValue, relationshipId); + metadataValue.setUseForPlace(virtualBean.getUseForPlace()); + metadataValue.setPlace(place); + if (StringUtils.isNotBlank(metadataValue.getValue())) { + resultingMetadataValueList.add(metadataValue); + } + } + } + } + return resultingMetadataValueList; + } + + //This method will construct a RelationshipMetadataValue object with proper schema, element and qualifier based + //on the key String parameter passed along to it + private RelationshipMetadataValue constructMetadataValue(Context context, String key) { + String[] splittedKey = key.split("\\."); + RelationshipMetadataValue metadataValue = new RelationshipMetadataValue(); + String metadataSchema = splittedKey.length > 0 ? splittedKey[0] : null; + String metadataElement = splittedKey.length > 1 ? splittedKey[1] : null; + String metadataQualifier = splittedKey.length > 2 ? splittedKey[2] : null; + MetadataField metadataField = null; + try { + metadataField = metadataFieldService + .findByElement(context, metadataSchema, metadataElement, metadataQualifier); + } catch (SQLException e) { + log.error("Could not find element with MetadataSchema: " + metadataSchema + + ", MetadataElement: " + metadataElement + " and MetadataQualifier: " + metadataQualifier, e); + return null; + } + if (metadataField == null) { + log.error("A MetadataValue was attempted to construct with MetadataField for parameters: " + + "metadataschema: {}, metadataelement: {}, metadataqualifier: {}", + metadataSchema, metadataElement, metadataQualifier); + return null; + } + metadataValue.setMetadataField(metadataField); + metadataValue.setLanguage(Item.ANY); + return metadataValue; + } + + + private RelationshipMetadataValue constructResultingMetadataValue(Item item, String value, + RelationshipMetadataValue metadataValue, + Integer relationshipId) { + metadataValue.setValue(value); + metadataValue.setAuthority(Constants.VIRTUAL_AUTHORITY_PREFIX + relationshipId); + metadataValue.setConfidence(-1); + metadataValue.setDSpaceObject(item); + return metadataValue; + } + + + private RelationshipMetadataValue getRelationMetadataFromOtherItem(Context context, Item otherItem, + String relationName, + Integer relationshipId, int place) { + RelationshipMetadataValue metadataValue = constructMetadataValue(context, + MetadataSchemaEnum.RELATION + .getName() + "." + relationName); + if (metadataValue != null) { + metadataValue.setAuthority(Constants.VIRTUAL_AUTHORITY_PREFIX + relationshipId); + metadataValue.setValue(otherItem.getID().toString()); + metadataValue.setPlace(place); + return metadataValue; + } + return null; + } +} diff --git a/dspace-api/src/main/java/org/dspace/content/service/ItemService.java b/dspace-api/src/main/java/org/dspace/content/service/ItemService.java index 05992764c1..91fb75a45e 100644 --- a/dspace-api/src/main/java/org/dspace/content/service/ItemService.java +++ b/dspace-api/src/main/java/org/dspace/content/service/ItemService.java @@ -654,19 +654,6 @@ public interface ItemService */ boolean isInProgressSubmission(Context context, Item item) throws SQLException; - /** - * This method retrieves a list of MetadataValue objects that get constructed from processing - * the given Item's Relationships through the config given to the {@link VirtualMetadataPopulator} - * @param item The Item that will be processed through it's Relationships - * @param enableVirtualMetadata This parameter will determine whether the list of Relationship metadata - * should be populated with metadata that is being generated through the - * VirtualMetadataPopulator functionality or not - * @return The list of MetadataValue objects constructed through the Relationships - */ - public List getRelationshipMetadata(Item item, boolean enableVirtualMetadata); - - - /** * Get metadata for the DSpace Object in a chosen schema. * See MetadataSchema for more information about schemas. diff --git a/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceTest.java b/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceTest.java new file mode 100644 index 0000000000..c5fff5086b --- /dev/null +++ b/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceTest.java @@ -0,0 +1,54 @@ +package org.dspace.content; + +import static org.mockito.Mockito.when; + +import java.util.LinkedList; + +import org.dspace.content.service.RelationshipService; +import org.dspace.core.Context; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class RelationshipMetadataServiceTest { + + @InjectMocks + private RelationshipMetadataServiceImpl relationshipMetadataService; + + @Mock + private RelationshipService relationshipService; + + @Mock + private Item item; + private Relationship firstRelationship; + private Relationship secondRelationship; + private LinkedList list; + private Context context; + + @Before + public void init() { + firstRelationship = new Relationship(); + secondRelationship = new Relationship(); + list = new LinkedList<>(); + list.add(firstRelationship); + list.add(secondRelationship); + } + + @Test + @Ignore + public void testGetRelationshipMetadata() throws Exception { + when(item.getMetadata()).thenReturn(new LinkedList<>()); + when(relationshipService.findByItem(context, item)).thenReturn(list); + + + String t = ""; + relationshipMetadataService.getRelationshipMetadata(item, true); + + + } +} diff --git a/dspace/config/spring/api/core-services.xml b/dspace/config/spring/api/core-services.xml index 43959b25fd..4a1acc2168 100644 --- a/dspace/config/spring/api/core-services.xml +++ b/dspace/config/spring/api/core-services.xml @@ -54,6 +54,7 @@ +