Merge pull request #2551 from atmire/w2p-65568_bugs-place-management-creating-relationships

Entities bug-fixes in place management
This commit is contained in:
Tim Donohue
2019-11-20 09:07:31 -06:00
committed by GitHub
13 changed files with 604 additions and 99 deletions

View File

@@ -193,7 +193,7 @@ public class MetadataImport {
* @param workflowNotify If the workflows should be used, whether to send notifications or not
* @param useTemplate Use collection template if create new item
* @return An array of BulkEditChange elements representing the items that have changed
* @throws MetadataImportException if something goes wrong
* @throws MetadataImportException if something goes wrong
*/
public List<BulkEditChange> runImport(boolean change,
boolean useWorkflow,
@@ -780,8 +780,8 @@ public class MetadataImport {
}
// Create the relationship
int leftPlace = relationshipService.findLeftPlaceByLeftItem(c, leftItem) + 1;
int rightPlace = relationshipService.findRightPlaceByRightItem(c, rightItem) + 1;
int leftPlace = relationshipService.findNextLeftPlaceByLeftItem(c, leftItem);
int rightPlace = relationshipService.findNextRightPlaceByRightItem(c, rightItem);
Relationship persistedRelationship = relationshipService.create(c, leftItem, rightItem,
foundRelationshipType, leftPlace, rightPlace);
relationshipService.update(c, persistedRelationship);

View File

@@ -146,7 +146,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
public List<MetadataValue> getMetadataByMetadataString(T dso, String mdString) {
StringTokenizer dcf = new StringTokenizer(mdString, ".");
String[] tokens = { "", "", "" };
String[] tokens = {"", "", ""};
int i = 0;
while (dcf.hasMoreTokens()) {
tokens[i] = dcf.nextToken().trim();
@@ -250,8 +250,11 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
}
}
MetadataValue metadataValue = metadataValueService.create(context, dso, metadataField);
//Set place to list length
metadataValue.setPlace(this.getMetadata(dso, Item.ANY, Item.ANY, Item.ANY, Item.ANY).size());
//Set place to list length of all metadatavalues for the given schema.element.qualifier combination.
// Subtract one to adhere to the 0 as first element rule
metadataValue.setPlace(
this.getMetadata(dso, metadataField.getMetadataSchema().getName(), metadataField.getElement(),
metadataField.getQualifier(), Item.ANY).size() - 1);
metadataValue.setLanguage(lang == null ? null : lang.trim());
@@ -533,7 +536,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
protected String[] getMDValueByField(String field) {
StringTokenizer dcf = new StringTokenizer(field, ".");
String[] tokens = { "", "", "" };
String[] tokens = {"", "", ""};
int i = 0;
while (dcf.hasMoreTokens()) {
tokens[i] = dcf.nextToken().trim();
@@ -571,7 +574,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
if (compare == 0) {
if (o1 instanceof RelationshipMetadataValue) {
return 1;
} else if (o2 instanceof RelationshipMetadataValue) {
} else if (o2 instanceof RelationshipMetadataValue) {
return -1;
}
}

View File

@@ -81,8 +81,12 @@ public class RelationshipServiceImpl implements RelationshipService {
if (isRelationshipValidToCreate(context, relationship)) {
if (authorizeService.authorizeActionBoolean(context, relationship.getLeftItem(), Constants.WRITE) ||
authorizeService.authorizeActionBoolean(context, relationship.getRightItem(), Constants.WRITE)) {
updatePlaceInRelationship(context, relationship, true);
return relationshipDAO.create(context, relationship);
// This order of execution should be handled in the creation (create, updateplace, update relationship)
// for a proper place allocation
Relationship relationshipToReturn = relationshipDAO.create(context, relationship);
updatePlaceInRelationship(context, relationshipToReturn);
update(context, relationshipToReturn);
return relationshipToReturn;
} else {
throw new AuthorizeException(
"You do not have write rights on this relationship's items");
@@ -94,18 +98,34 @@ public class RelationshipServiceImpl implements RelationshipService {
}
@Override
public void updatePlaceInRelationship(Context context, Relationship relationship, boolean isCreation)
public void updatePlaceInRelationship(Context context, Relationship relationship)
throws SQLException, AuthorizeException {
Item leftItem = relationship.getLeftItem();
// Max value is used to ensure that these will get added to the back of the list and thus receive the highest
// (last) place as it's set to a -1 for creation
if (relationship.getLeftPlace() == -1) {
relationship.setLeftPlace(Integer.MAX_VALUE);
}
Item rightItem = relationship.getRightItem();
if (relationship.getRightPlace() == -1) {
relationship.setRightPlace(Integer.MAX_VALUE);
}
List<Relationship> leftRelationships = findByItemAndRelationshipType(context,
leftItem,
relationship.getRelationshipType(), true);
Item rightItem = relationship.getRightItem();
List<Relationship> rightRelationships = findByItemAndRelationshipType(context,
rightItem,
relationship.getRelationshipType(),
false);
// These relationships are only deleted from the temporary lists incase they're present in them so that we can
// properly perform our place calculation later down the line in this method.
if (leftRelationships.contains(relationship)) {
leftRelationships.remove(relationship);
}
if (rightRelationships.contains(relationship)) {
rightRelationships.remove(relationship);
}
context.turnOffAuthorisationSystem();
//If useForPlace for the leftwardType is false for the relationshipType,
// we need to sort the relationships here based on leftplace.
@@ -141,10 +161,6 @@ public class RelationshipServiceImpl implements RelationshipService {
updateItem(context, rightItem);
}
if (isCreation) {
handleCreationPlaces(context, relationship);
}
context.restoreAuthSystemState();
}
@@ -156,43 +172,14 @@ public class RelationshipServiceImpl implements RelationshipService {
itemService.update(context, relatedItem);
}
//Sets the places for the Relationship properly if the updatePlaceInRelationship was called for a new creation
//of this Relationship
private void handleCreationPlaces(Context context, Relationship relationship) throws SQLException {
List<Relationship> leftRelationships;
List<Relationship> rightRelationships;
leftRelationships = findByItemAndRelationshipType(context,
relationship.getLeftItem(),
relationship.getRelationshipType(), true);
rightRelationships = findByItemAndRelationshipType(context,
relationship.getRightItem(),
relationship.getRelationshipType(),
false);
leftRelationships.sort((o1, o2) -> o2.getLeftPlace() - o1.getLeftPlace());
rightRelationships.sort((o1, o2) -> o2.getRightPlace() - o1.getRightPlace());
if (!leftRelationships.isEmpty()) {
relationship.setLeftPlace(leftRelationships.get(0).getLeftPlace() + 1);
} else {
relationship.setLeftPlace(0);
}
if (!rightRelationships.isEmpty()) {
relationship.setRightPlace(rightRelationships.get(0).getRightPlace() + 1);
} else {
relationship.setRightPlace(0);
}
@Override
public int findNextLeftPlaceByLeftItem(Context context, Item item) throws SQLException {
return relationshipDAO.findNextLeftPlaceByLeftItem(context, item);
}
@Override
public int findLeftPlaceByLeftItem(Context context, Item item) throws SQLException {
return relationshipDAO.findLeftPlaceByLeftItem(context, item);
}
@Override
public int findRightPlaceByRightItem(Context context, Item item) throws SQLException {
return relationshipDAO.findRightPlaceByRightItem(context, item);
public int findNextRightPlaceByRightItem(Context context, Item item) throws SQLException {
return relationshipDAO.findNextRightPlaceByRightItem(context, item);
}
private boolean isRelationshipValidToCreate(Context context, Relationship relationship) throws SQLException {
@@ -331,7 +318,7 @@ public class RelationshipServiceImpl implements RelationshipService {
if (authorizeService.authorizeActionBoolean(context, relationship.getLeftItem(), Constants.WRITE) ||
authorizeService.authorizeActionBoolean(context, relationship.getRightItem(), Constants.WRITE)) {
relationshipDAO.delete(context, relationship);
updatePlaceInRelationship(context, relationship, false);
updatePlaceInRelationship(context, relationship);
} else {
throw new AuthorizeException(
"You do not have write rights on this relationship's items");

View File

@@ -51,26 +51,26 @@ public interface RelationshipDAO extends GenericDAO<Relationship> {
List<Relationship> findByItem(Context context, Item item, Integer limit, Integer offset) throws SQLException;
/**
* This method returns the highest leftplace integer for all the relationships where this
* item is the leftitem so that we can set a proper leftplace attribute on the next relationship
* This method returns the next leftplace integer to use for a relationship with this item as the leftItem
*
* @param context The relevant DSpace context
* @param item The item to be matched on leftItem
* @return The integer for the highest leftPlace value for all the relatonship objects
* that have the given item as leftItem
* @return The next integer to be used for the leftplace of a relationship with the given item
* as a left item
* @throws SQLException If something goes wrong
*/
int findLeftPlaceByLeftItem(Context context, Item item) throws SQLException;
int findNextLeftPlaceByLeftItem(Context context, Item item) throws SQLException;
/**
* This method returns the highest rightplace integer for all the relationships where this
* item is the rightitem so that we can set a proper rightplace attribute on the next relationship
* This method returns the next rightplace integer to use for a relationship with this item as the rightItem
*
* @param context The relevant DSpace context
* @param item The item to be matched on rightItem
* @return The integer for the highest rightPlace value for all the relatonship objects
* that have the given item as rightItem
* @return The next integer to be used for the rightplace of a relationship with the given item
* as a right item
* @throws SQLException If something goes wrong
*/
int findRightPlaceByRightItem(Context context, Item item) throws SQLException;
int findNextRightPlaceByRightItem(Context context, Item item) throws SQLException;
/**
* This method returns a list of Relationship objects for the given RelationshipType object.
@@ -113,7 +113,7 @@ public interface RelationshipDAO extends GenericDAO<Relationship> {
* @throws SQLException If something goes wrong
*/
List<Relationship> findByItemAndRelationshipType(Context context, Item item, RelationshipType relationshipType,
Integer limit, Integer offset) throws SQLException;
Integer limit, Integer offset) throws SQLException;
/**
* This method returns a list of Relationship objects for the given RelationshipType object.
@@ -157,7 +157,6 @@ public interface RelationshipDAO extends GenericDAO<Relationship> {
List<Relationship> findByTypeName(Context context, String typeName, Integer limit, Integer offset)
throws SQLException;
/**
* Count total number of relationships (rows in relationship table)
*

View File

@@ -61,7 +61,7 @@ public class RelationshipDAOImpl extends AbstractHibernateDAO<Relationship> impl
}
@Override
public int findLeftPlaceByLeftItem(Context context, Item item) throws SQLException {
public int findNextLeftPlaceByLeftItem(Context context, Item item) throws SQLException {
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
@@ -70,25 +70,25 @@ public class RelationshipDAOImpl extends AbstractHibernateDAO<Relationship> impl
List<Relationship> list = list(context, criteriaQuery, false, Relationship.class, -1, -1);
list.sort((o1, o2) -> o2.getLeftPlace() - o1.getLeftPlace());
if (!list.isEmpty()) {
return list.get(0).getLeftPlace();
return list.get(0).getLeftPlace() + 1;
} else {
return 1;
return 0;
}
}
@Override
public int findRightPlaceByRightItem(Context context, Item item) throws SQLException {
public int findNextRightPlaceByRightItem(Context context, Item item) throws SQLException {
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
criteriaQuery.select(relationshipRoot);
criteriaQuery.where(criteriaBuilder.equal(relationshipRoot.get(Relationship_.rightItem), item));
List<Relationship> list = list(context, criteriaQuery, false, Relationship.class, -1, -1);
list.sort((o1, o2) -> o2.getLeftPlace() - o1.getLeftPlace());
list.sort((o1, o2) -> o2.getRightPlace() - o1.getRightPlace());
if (!list.isEmpty()) {
return list.get(0).getLeftPlace();
return list.get(0).getRightPlace() + 1;
} else {
return 1;
return 0;
}
}

View File

@@ -74,26 +74,26 @@ public interface RelationshipService extends DSpaceCRUDService<Relationship> {
public Relationship create(Context context, Relationship relationship) throws SQLException, AuthorizeException;
/**
* Retrieves the highest integer value for the leftplace property of a Relationship for all relationships
* that have the given item as a left item
* This method returns the next leftplace integer to use for a relationship with this item as the leftItem
*
* @param context The relevant DSpace context
* @param item The item that has to be the leftItem of a relationship for it to qualify
* @return The integer value of the highest left place property of all relationships
* that have the given item as a leftitem property
* @return The next integer to be used for the leftplace of a relationship with the given item
* as a left item
* @throws SQLException If something goes wrong
*/
int findLeftPlaceByLeftItem(Context context, Item item) throws SQLException;
int findNextLeftPlaceByLeftItem(Context context, Item item) throws SQLException;
/**
* Retrieves the highest integer value for the rightplace property of a Relationship for all relationships
* that have the given item as a right item
* This method returns the next rightplace integer to use for a relationship with this item as the rightItem
*
* @param context The relevant DSpace context
* @param item The item that has to be the rightitem of a relationship for it to qualify
* @return The integer value of the highest right place property of all relationships
* that have the given item as a rightitem property
* @return The next integer to be used for the rightplace of a relationship with the given item
* as a right item
* @throws SQLException If something goes wrong
*/
int findRightPlaceByRightItem(Context context, Item item) throws SQLException;
int findNextRightPlaceByRightItem(Context context, Item item) throws SQLException;
/**
* This method returns a list of Relationships for which the leftItem or rightItem is equal to the given
@@ -147,10 +147,9 @@ public interface RelationshipService extends DSpaceCRUDService<Relationship> {
* @param context The relevant DSpace context
* @param relationship The Relationship object that will have it's place updated and that will be used
* to retrieve the other relationships whose place might need to be updated
* @param isCreation Is the relationship new or did it already exist
* @throws SQLException If something goes wrong
*/
public void updatePlaceInRelationship(Context context, Relationship relationship, boolean isCreation)
public void updatePlaceInRelationship(Context context, Relationship relationship)
throws SQLException, AuthorizeException;
/**

View File

@@ -138,5 +138,79 @@ public class RelationshipMetadataServiceTest extends AbstractUnitTest {
assertThat(list.get(1).getMetadataField().getElement(), equalTo("isAuthorOfPublication"));
assertThat(list.get(1).getAuthority(), equalTo("virtual::" + relationship.getID()));
}
@Test
public void testGetNextRightPlace() throws Exception {
assertThat(relationshipService.findNextRightPlaceByRightItem(context, authorItem), equalTo(0));
context.turnOffAuthorisationSystem();
itemService.addMetadata(context, item, "relationship", "type", null, null, "Publication");
itemService.addMetadata(context, authorItem, "relationship", "type", null, null, "Author");
itemService.addMetadata(context, authorItem, "person", "familyName", null, null, "familyName");
itemService.addMetadata(context, authorItem, "person", "givenName", null, null, "firstName");
EntityType publicationEntityType = entityTypeService.create(context, "Publication");
EntityType authorEntityType = entityTypeService.create(context, "Author");
RelationshipType isAuthorOfPublication = relationshipTypeService
.create(context, publicationEntityType, authorEntityType, "isAuthorOfPublication", "isPublicationOfAuthor",
null, null, null, null);
Relationship relationship = relationshipService.create(context, item, authorItem, isAuthorOfPublication, 0, 0);
context.restoreAuthSystemState();
assertThat(relationshipService.findNextRightPlaceByRightItem(context, authorItem), equalTo(1));
context.turnOffAuthorisationSystem();
Community community = communityService.create(null, context);
Collection col = collectionService.create(context, community);
WorkspaceItem is = workspaceItemService.create(context, col, false);
Item secondItem = installItemService.installItem(context, is);
itemService.addMetadata(context, secondItem, "relationship", "type", null, null, "Publication");
Relationship secondRelationship = relationshipService.create(context, secondItem, authorItem,
isAuthorOfPublication, 0, 0);
context.restoreAuthSystemState();
assertThat(relationshipService.findNextRightPlaceByRightItem(context, authorItem), equalTo(2));
}
@Test
public void testGetNextLeftPlace() throws Exception {
assertThat(relationshipService.findNextLeftPlaceByLeftItem(context, item), equalTo(0));
context.turnOffAuthorisationSystem();
itemService.addMetadata(context, item, "relationship", "type", null, null, "Publication");
itemService.addMetadata(context, authorItem, "relationship", "type", null, null, "Author");
itemService.addMetadata(context, authorItem, "person", "familyName", null, null, "familyName");
itemService.addMetadata(context, authorItem, "person", "givenName", null, null, "firstName");
EntityType publicationEntityType = entityTypeService.create(context, "Publication");
EntityType authorEntityType = entityTypeService.create(context, "Author");
RelationshipType isAuthorOfPublication = relationshipTypeService
.create(context, publicationEntityType, authorEntityType, "isAuthorOfPublication", "isPublicationOfAuthor",
null, null, null, null);
Relationship relationship = relationshipService.create(context, item, authorItem, isAuthorOfPublication, 0, 0);
context.restoreAuthSystemState();
assertThat(relationshipService.findNextLeftPlaceByLeftItem(context, item), equalTo(1));
context.turnOffAuthorisationSystem();
Community community = communityService.create(null, context);
Collection col = collectionService.create(context, community);
WorkspaceItem is = workspaceItemService.create(context, col, false);
Item secondAuthor = installItemService.installItem(context, is);
itemService.addMetadata(context, secondAuthor, "relationship", "type", null, null, "Author");
itemService.addMetadata(context, secondAuthor, "person", "familyName", null, null, "familyName");
itemService.addMetadata(context, secondAuthor, "person", "givenName", null, null, "firstName");
Relationship secondRelationship = relationshipService.create(context, item, secondAuthor,
isAuthorOfPublication, 0, 0);
context.restoreAuthSystemState();
assertThat(relationshipService.findNextLeftPlaceByLeftItem(context, item), equalTo(2));
}
}

View File

@@ -0,0 +1,428 @@
/**
* 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;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.sql.SQLException;
import java.util.List;
import org.apache.logging.log4j.Logger;
import org.dspace.AbstractUnitTest;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.CollectionService;
import org.dspace.content.service.CommunityService;
import org.dspace.content.service.EntityTypeService;
import org.dspace.content.service.InstallItemService;
import org.dspace.content.service.ItemService;
import org.dspace.content.service.MetadataValueService;
import org.dspace.content.service.RelationshipService;
import org.dspace.content.service.RelationshipTypeService;
import org.dspace.content.service.WorkspaceItemService;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class RelationshipServiceImplPlaceTest extends AbstractUnitTest {
private static final Logger log = org.apache.logging.log4j.LogManager
.getLogger(RelationshipServiceImplPlaceTest.class);
protected RelationshipService relationshipService = ContentServiceFactory.getInstance().getRelationshipService();
protected RelationshipTypeService relationshipTypeService = ContentServiceFactory.getInstance()
.getRelationshipTypeService();
protected EntityTypeService entityTypeService = ContentServiceFactory.getInstance().getEntityTypeService();
protected CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
protected CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
protected InstallItemService installItemService = ContentServiceFactory.getInstance().getInstallItemService();
protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService();
protected MetadataValueService metadataValueService = ContentServiceFactory.getInstance().getMetadataValueService();
Community community;
Collection col;
Item item;
Item authorItem;
RelationshipType isAuthorOfPublication;
EntityType publicationEntityType;
EntityType authorEntityType;
String authorQualifier = "author";
String contributorElement = "contributor";
String dcSchema = "dc";
/**
* This method will be run before every test as per @Before. It will
* initialize resources required for the tests.
*/
@Before
@Override
public void init() {
super.init();
try {
context.turnOffAuthorisationSystem();
community = communityService.create(null, context);
col = collectionService.create(context, community);
WorkspaceItem is = workspaceItemService.create(context, col, false);
WorkspaceItem authorIs = workspaceItemService.create(context, col, false);
item = installItemService.installItem(context, is);
itemService.addMetadata(context, item, "relationship", "type", null, null, "Publication");
authorItem = installItemService.installItem(context, authorIs);
itemService.addMetadata(context, authorItem, "relationship", "type", null, null, "Person");
itemService.addMetadata(context, authorItem, "person", "familyName", null, null, "familyName");
itemService.addMetadata(context, authorItem, "person", "givenName", null, null, "firstName");
publicationEntityType = entityTypeService.create(context, "Publication");
authorEntityType = entityTypeService.create(context, "Person");
isAuthorOfPublication = relationshipTypeService
.create(context, publicationEntityType, authorEntityType,
"isAuthorOfPublication", "isPublicationOfAuthor",
null, null, null, null);
context.restoreAuthSystemState();
} catch (AuthorizeException ex) {
log.error("Authorization Error in init", ex);
fail("Authorization Error in init: " + ex.getMessage());
} catch (SQLException ex) {
log.error("SQL Error in init", ex);
fail("SQL Error in init: " + ex.getMessage());
}
}
/**
* This method will be run after every test as per @After. It will
* clean resources initialized by the @Before methods.
*/
@After
@Override
public void destroy() {
context.abort();
super.destroy();
}
/**
* This test will test the use case of having an item to which we add some metadata. After that, we'll add a single
* relationship to this Item. We'll test whether the places are correct, in this case it'll be the two metadata
* values that we created first, has to have place 0 and 1. The Relationship that we just created needs to have
* leftPlace 2 and the metadata value resulting from that Relationship needs to also have place 2.
* Once these assertions succeed, we basically repeat said process with new metadata values and a new relationship.
* We then test if the old assertions still hold true like they should and that the new ones behave as expected
* as well.
* @throws Exception If something goes wrong
*/
@Test
public void addMetadataAndRelationshipTest() throws Exception {
context.turnOffAuthorisationSystem();
// Here we add the first set of metadata to the item
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, one");
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, two");
// Here we create the first Relationship to the item
Relationship relationship = relationshipService
.create(context, item, authorItem, isAuthorOfPublication, -1, -1);
context.restoreAuthSystemState();
// The code below performs the mentioned assertions to ensure the place is correct
List<MetadataValue> list = itemService
.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
assertThat(list.size(), equalTo(3));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, two", null, 1, list.get(1));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyName, firstName",
"virtual::" + relationship.getID(), 2, list.get(2));
assertThat(relationship.getLeftPlace(), equalTo(2));
context.turnOffAuthorisationSystem();
// This is where we add the second set of metadata values
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, three");
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, four");
// Here we create an Item so that we can create another relationship with this item
WorkspaceItem authorIs = workspaceItemService.create(context, col, false);
Item secondAuthorItem = installItemService.installItem(context, authorIs);
itemService.addMetadata(context, secondAuthorItem, "relationship", "type", null, null, "Person");
itemService.addMetadata(context, secondAuthorItem, "person", "familyName", null, null, "familyNameTwo");
itemService.addMetadata(context, secondAuthorItem, "person", "givenName", null, null, "firstNameTwo");
Relationship relationshipTwo = relationshipService
.create(context, item, secondAuthorItem, isAuthorOfPublication, -1, -1);
context.restoreAuthSystemState();
// Here we retrieve the list of metadata again to perform the assertions on the places below as mentioned
list = itemService.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, two", null, 1, list.get(1));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyName, firstName",
"virtual::" + relationship.getID(), 2, list.get(2));
assertThat(relationship.getLeftPlace(), equalTo(2));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, three", null, 3, list.get(3));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, four", null, 4, list.get(4));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyNameTwo, firstNameTwo",
"virtual::" + relationshipTwo.getID(), 5, list.get(5));
assertThat(relationshipTwo.getLeftPlace(), equalTo(5));
}
/**
* This test is virtually the same as above, only this time we'll add Relationships with leftPlaces already set
* equal to what they HAVE to be. So in the first test addMetadataAndRelationshipTest, we didn't specify a place
* and left it up to the Service to determine it, here we provide a correct place already.
* We perform the exact same logic except that we give a proper place already to the Relationships and we
* perform the same checks
* @throws Exception If something goes wrong
*/
@Test
public void AddMetadataAndRelationshipWithSpecificPlaceTest() throws Exception {
context.turnOffAuthorisationSystem();
// Here we add the first set of metadata to the item
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, one");
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, two");
// Here we create the first Relationship to the item with the specific leftPlace: 2
Relationship relationship = relationshipService.create(context, item, authorItem, isAuthorOfPublication, 2, -1);
context.restoreAuthSystemState();
// The code below performs the mentioned assertions to ensure the place is correct
List<MetadataValue> list = itemService
.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
assertThat(list.size(), equalTo(3));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, two", null, 1, list.get(1));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyName, firstName",
"virtual::" + relationship.getID(), 2, list.get(2));
assertThat(relationship.getLeftPlace(), equalTo(2));
context.turnOffAuthorisationSystem();
// This is where we add the second set of metadata values
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, three");
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, four");
// Here we create an Item so that we can create another relationship with this item. We'll give this
// Relationship a specific place as well
WorkspaceItem authorIs = workspaceItemService.create(context, col, false);
Item secondAuthorItem = installItemService.installItem(context, authorIs);
itemService.addMetadata(context, secondAuthorItem, "relationship", "type", null, null, "Person");
itemService.addMetadata(context, secondAuthorItem, "person", "familyName", null, null, "familyNameTwo");
itemService.addMetadata(context, secondAuthorItem, "person", "givenName", null, null, "firstNameTwo");
Relationship relationshipTwo = relationshipService
.create(context, item, secondAuthorItem, isAuthorOfPublication, 5, -1);
context.restoreAuthSystemState();
// Here we retrieve the list of metadata again to perform the assertions on the places below as mentioned
list = itemService.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, two", null, 1, list.get(1));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyName, firstName",
"virtual::" + relationship.getID(), 2, list.get(2));
assertThat(relationship.getLeftPlace(), equalTo(2));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, three", null, 3, list.get(3));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, four", null, 4, list.get(4));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyNameTwo, firstNameTwo",
"virtual::" + relationshipTwo.getID(), 5, list.get(5));
assertThat(relationshipTwo.getLeftPlace(), equalTo(5));
}
/**
* In this test, our goal will be to add a bunch of metadata values to then remove one of them. We'll check the list
* of metadata values for the item and check that the places have not been altered for the metadata values IF an
* item.update hadn't been called yet. We'll then create a Relationship (by which an item.update will be called)
* and then we check that the places are set correctly.
* We then repeat this process once more and check that everything works as intended
* @throws Exception
*/
@Test
public void AddAndRemoveMetadataAndRelationshipsTest() throws Exception {
context.turnOffAuthorisationSystem();
// Here we add the first set of metadata to the item
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, one");
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, two");
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, three");
// Get a specific metadatavlaue to remove
MetadataValue metadataValueToRemove = itemService.getMetadata(item, "dc", "contributor", "author", Item.ANY)
.get(1);
// Remove the actual metadata value
item.removeMetadata(metadataValueToRemove);
metadataValueService.delete(context, metadataValueToRemove);
context.restoreAuthSystemState();
// Retrieve the list of mdv again
List<MetadataValue> list = itemService
.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
// Verify we only have 2 mdv left
assertThat(list.size(), equalTo(2));
// Check that these places are still intact after the deletion as the place doesn't get updated until an
// item.update has been called
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, three", null, 2, list.get(1));
context.turnOffAuthorisationSystem();
// Create a relationship with this item with a spcific place
Relationship relationship = relationshipService.create(context, item, authorItem, isAuthorOfPublication, 1, -1);
context.restoreAuthSystemState();
// Retrieve the list again and verify that the creation of the Relationship added an additional mdv
list = itemService.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
assertThat(list.size(), equalTo(3));
// Assert that the mdv are well placed
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyName, firstName",
"virtual::" + relationship.getID(), 1, list.get(1));
assertThat(relationship.getLeftPlace(), equalTo(1));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, three", null, 2, list.get(2));
context.turnOffAuthorisationSystem();
// Add two extra mdv
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, four");
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, five");
//This is author "test, four" that we're removing
metadataValueToRemove = itemService.getMetadata(item, "dc", "contributor", "author", Item.ANY).get(3);
item.removeMetadata(metadataValueToRemove);
metadataValueService.delete(context, metadataValueToRemove);
context.restoreAuthSystemState();
list = itemService.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
// Check that these places are still intact after the deletion as the place doesn't get updated until an
// item.update has been called
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyName, firstName",
"virtual::" + relationship.getID(), 1, list.get(1));
assertThat(relationship.getLeftPlace(), equalTo(1));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, three", null, 2, list.get(2));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, five", null, 4, list.get(3));
context.turnOffAuthorisationSystem();
// Create an additional item for another relationship
WorkspaceItem authorIs = workspaceItemService.create(context, col, false);
Item secondAuthorItem = installItemService.installItem(context, authorIs);
itemService.addMetadata(context, secondAuthorItem, "relationship", "type", null, null, "Person");
itemService.addMetadata(context, secondAuthorItem, "person", "familyName", null, null, "familyNameTwo");
itemService.addMetadata(context, secondAuthorItem, "person", "givenName", null, null, "firstNameTwo");
Relationship relationshipTwo = relationshipService
.create(context, item, secondAuthorItem, isAuthorOfPublication, 3, -1);
context.restoreAuthSystemState();
// Check that the other mdv are still okay and that the creation of the relationship added
// another correct mdv to the item
list = itemService.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyName, firstName",
"virtual::" + relationship.getID(), 1, list.get(1));
assertThat(relationship.getLeftPlace(), equalTo(1));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, three", null, 2, list.get(2));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyNameTwo, firstNameTwo",
"virtual::" + relationshipTwo.getID(), 3, list.get(3));
assertThat(relationshipTwo.getLeftPlace(), equalTo(3));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, five", null, 4, list.get(4));
}
@Test
public void AddAndUpdateMetadataAndRelationshipsTest() throws Exception {
context.turnOffAuthorisationSystem();
// Add metadata and relationships to the item
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, one");
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, two");
itemService.addMetadata(context, item, dcSchema, contributorElement, authorQualifier, null, "test, three");
Relationship relationship = relationshipService
.create(context, item, authorItem, isAuthorOfPublication, -1, -1);
context.restoreAuthSystemState();
// Get the list of mdv and assert that they're correct
List<MetadataValue> list = itemService
.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
assertThat(list.size(), equalTo(4));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, two", null, 1, list.get(1));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, three", null, 2, list.get(2));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyName, firstName",
"virtual::" + relationship.getID(), 3, list.get(3));
assertThat(relationship.getLeftPlace(), equalTo(3));
context.turnOffAuthorisationSystem();
MetadataValue metadataValueToUpdate = itemService.getMetadata(item, "dc", "contributor", "author", Item.ANY)
.get(1);
// Switching the places of this relationship and metadata value to verify in the test later on that this
// updating works
metadataValueToUpdate.setPlace(3);
metadataValueService.update(context, metadataValueToUpdate);
relationship.setLeftPlace(1);
relationshipService.update(context, relationship);
context.restoreAuthSystemState();
// Retrieve the list again and verify that the updating did indeed work
list = itemService.getMetadata(item, dcSchema, contributorElement, authorQualifier, Item.ANY);
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, one", null, 0, list.get(0));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, two", null, 3, list.get(3));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "test, three", null, 2, list.get(2));
assertMetadataValue(authorQualifier, contributorElement, dcSchema, "familyName, firstName",
"virtual::" + relationship.getID(), 1, list.get(1));
assertThat(relationship.getLeftPlace(), equalTo(1));
}
private void assertMetadataValue(String authorQualifier, String contributorElement, String dcSchema, String value,
String authority, int place, MetadataValue metadataValue) {
assertThat(metadataValue.getValue(), equalTo(value));
assertThat(metadataValue.getMetadataField().getMetadataSchema().getName(), equalTo(dcSchema));
assertThat(metadataValue.getMetadataField().getElement(), equalTo(contributorElement));
assertThat(metadataValue.getMetadataField().getQualifier(), equalTo(authorQualifier));
assertThat(metadataValue.getAuthority(), equalTo(authority));
assertThat(metadataValue.getPlace(), equalTo(place));
}
}

View File

@@ -114,11 +114,11 @@ public class RelationshipServiceImplTest {
Item item = mock(Item.class);
// Mock DAO to return mocked left place as 0
when(relationshipDAO.findLeftPlaceByLeftItem(context, item)).thenReturn(0);
when(relationshipDAO.findNextLeftPlaceByLeftItem(context, item)).thenReturn(0);
// The left place reported from out mocked item should match the DAO's report of the left place
assertEquals("TestFindLeftPlaceByLeftItem 0", relationshipDAO.findLeftPlaceByLeftItem(context, item),
relationshipService.findLeftPlaceByLeftItem(context, item));
assertEquals("TestFindLeftPlaceByLeftItem 0", relationshipDAO.findNextLeftPlaceByLeftItem(context, item),
relationshipService.findNextLeftPlaceByLeftItem(context, item));
}
@Test
@@ -127,11 +127,11 @@ public class RelationshipServiceImplTest {
Item item = mock(Item.class);
// Mock lower level DAO to return mocked right place as 0
when(relationshipDAO.findRightPlaceByRightItem(context, item)).thenReturn(0);
when(relationshipDAO.findNextRightPlaceByRightItem(context, item)).thenReturn(0);
// The right place reported from out mocked item should match the DAO's report of the right place
assertEquals("TestFindRightPlaceByRightItem 0", relationshipDAO.findRightPlaceByRightItem(context, item),
relationshipService.findRightPlaceByRightItem(context, item));
assertEquals("TestFindRightPlaceByRightItem 0", relationshipDAO.findNextRightPlaceByRightItem(context, item),
relationshipService.findNextRightPlaceByRightItem(context, item));
}
@Test

View File

@@ -138,24 +138,24 @@ public class RelationshipDAOImplTest extends AbstractIntegrationTest {
}
/**
* Test findLeftPlaceByLeftItem should return 0 given our test left Item itemOne.
* Test findNextLeftPlaceByLeftItem should return 0 given our test left Item itemOne.
*
* @throws Exception
*/
@Test
public void testFindLeftPlaceByLeftItem() throws Exception {
assertEquals("TestLeftPlaceByLeftItem 0", 0, relationshipService.findLeftPlaceByLeftItem(context,
public void testFindNextLeftPlaceByLeftItem() throws Exception {
assertEquals("TestNextLeftPlaceByLeftItem 0", 1, relationshipService.findNextLeftPlaceByLeftItem(context,
itemOne));
}
/**
* Test findRightPlaceByRightItem should return 0 given our test right Item itemTwo.
* Test findNextRightPlaceByRightItem should return 0 given our test right Item itemTwo.
*
* @throws Exception
*/
@Test
public void testFindRightPlaceByRightItem() throws Exception {
assertEquals("TestRightPlaceByRightItem 0", 0, relationshipService.findRightPlaceByRightItem(context,
public void testFindNextRightPlaceByRightItem() throws Exception {
assertEquals("TestNextRightPlaceByRightItem 0", 1, relationshipService.findNextRightPlaceByRightItem(context,
itemTwo));
}

View File

@@ -125,7 +125,8 @@ public class RelationshipRestRepository extends DSpaceRestRepository<Relationshi
if (authorizeService.authorizeActionBoolean(context, leftItem, Constants.WRITE) ||
authorizeService.authorizeActionBoolean(context, rightItem, Constants.WRITE)) {
Relationship relationship = relationshipService.create(context, leftItem, rightItem,
relationshipType, 0, 0, leftwardValue, rightwardValue);
relationshipType, -1, -1,
leftwardValue, rightwardValue);
// The above if check deals with the case that a Relationship can be created if the user has write
// rights on one of the two items. The following updateItem calls can however call the
// ItemService.update() functions which would fail if the user doesn't have permission on both items.
@@ -192,7 +193,7 @@ public class RelationshipRestRepository extends DSpaceRestRepository<Relationshi
relationship.setRightItem(rightItem);
try {
relationshipService.updatePlaceInRelationship(context, relationship, false);
relationshipService.updatePlaceInRelationship(context, relationship);
relationshipService.update(context, relationship);
context.commit();
context.reloadEntity(relationship);

View File

@@ -115,6 +115,8 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
.withTitle("Author1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("Donald")
.withRelationshipType("Person")
.build();
@@ -934,6 +936,12 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
context.turnOffAuthorisationSystem();
Item publication1 = ItemBuilder.createItem(context, col3)
.withTitle("Publication1")
.withIssueDate("2015-01-01")
.withRelationshipType("Publication")
.build();
Item author2 = ItemBuilder.createItem(context, col2)
.withTitle("Author2")
.withIssueDate("2016-02-13")
@@ -1144,6 +1152,12 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
context.turnOffAuthorisationSystem();
Item publication1 = ItemBuilder.createItem(context, col3)
.withTitle("Publication1")
.withIssueDate("2015-01-01")
.withRelationshipType("Publication")
.build();
Item author2 = ItemBuilder.createItem(context, col2)
.withTitle("Author2")
.withIssueDate("2016-02-13")

View File

@@ -86,9 +86,9 @@ public class CSVMetadataImportReferenceTest extends AbstractEntityIntegrationTes
}
}
if (placeDirection.equalsIgnoreCase("left")) {
assertEquals(relationship.getLeftPlace(), placeCount);
assertEquals(placeCount, relationship.getLeftPlace());
} else {
assertEquals(relationship.getRightPlace(), placeCount);
assertEquals(placeCount, relationship.getRightPlace());
}
assertEquals(expectedCount, foundCount);
}