mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-12 12:33:18 +00:00
[DURACOM-125][#8736] Preserved order of modified MetadataValues
feat: - Introduced new Class with static methods usable to order `MetadataValue` lists; - Introduced ITs also for `PatchMetadata` replace operations; - Introduced new method `DspaceObject#getMetadataFieldId`. ref: - Replaced old sort method inside `ItemServiceImpl` with the new one
This commit is contained in:
@@ -48,6 +48,12 @@ public abstract class DSpaceObject implements Serializable, ReloadableEntity<jav
|
|||||||
@Transient
|
@Transient
|
||||||
private StringBuffer eventDetails = null;
|
private StringBuffer eventDetails = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The same order should be applied inside this comparator
|
||||||
|
* {@link MetadataValueComparators#defaultComparator} to preserve
|
||||||
|
* ordering while the list has been modified and not yet persisted
|
||||||
|
* and reloaded.
|
||||||
|
*/
|
||||||
@OneToMany(fetch = FetchType.LAZY, mappedBy = "dSpaceObject", cascade = CascadeType.ALL, orphanRemoval = true)
|
@OneToMany(fetch = FetchType.LAZY, mappedBy = "dSpaceObject", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
@OrderBy("metadataField, place")
|
@OrderBy("metadataField, place")
|
||||||
private List<MetadataValue> metadata = new ArrayList<>();
|
private List<MetadataValue> metadata = new ArrayList<>();
|
||||||
@@ -116,7 +122,7 @@ public abstract class DSpaceObject implements Serializable, ReloadableEntity<jav
|
|||||||
* @return summary of event details, or null if there are none.
|
* @return summary of event details, or null if there are none.
|
||||||
*/
|
*/
|
||||||
public String getDetails() {
|
public String getDetails() {
|
||||||
return (eventDetails == null ? null : eventDetails.toString());
|
return eventDetails == null ? null : eventDetails.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -145,7 +151,7 @@ public abstract class DSpaceObject implements Serializable, ReloadableEntity<jav
|
|||||||
* one
|
* one
|
||||||
*/
|
*/
|
||||||
public String getHandle() {
|
public String getHandle() {
|
||||||
return (CollectionUtils.isNotEmpty(handles) ? handles.get(0).getHandle() : null);
|
return CollectionUtils.isNotEmpty(handles) ? handles.get(0).getHandle() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setHandle(List<Handle> handle) {
|
void setHandle(List<Handle> handle) {
|
||||||
|
@@ -126,6 +126,11 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort the metadataValues if they have been modified,
|
||||||
|
// is used to preserve the default order.
|
||||||
|
if (dso.isMetadataModified()) {
|
||||||
|
values.sort(MetadataValueComparators.defaultComparator);
|
||||||
|
}
|
||||||
// Create an array of matching values
|
// Create an array of matching values
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
@@ -542,7 +547,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
|||||||
|
|
||||||
int add = 4 - tokens.length;
|
int add = 4 - tokens.length;
|
||||||
if (add > 0) {
|
if (add > 0) {
|
||||||
tokens = (String[]) ArrayUtils.addAll(tokens, new String[add]);
|
tokens = ArrayUtils.addAll(tokens, new String[add]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tokens;
|
return tokens;
|
||||||
@@ -603,9 +608,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
|||||||
//If two places are the same then the MetadataValue instance will be placed before the
|
//If two places are the same then the MetadataValue instance will be placed before the
|
||||||
//RelationshipMetadataValue instance.
|
//RelationshipMetadataValue instance.
|
||||||
//This is done to ensure that the order is correct.
|
//This is done to ensure that the order is correct.
|
||||||
metadataValues.sort(new Comparator<MetadataValue>() {
|
metadataValues.sort((o1, o2) -> {
|
||||||
@Override
|
|
||||||
public int compare(MetadataValue o1, MetadataValue o2) {
|
|
||||||
int compare = o1.getPlace() - o2.getPlace();
|
int compare = o1.getPlace() - o2.getPlace();
|
||||||
if (compare == 0) {
|
if (compare == 0) {
|
||||||
if (o1 instanceof RelationshipMetadataValue && o2 instanceof RelationshipMetadataValue) {
|
if (o1 instanceof RelationshipMetadataValue && o2 instanceof RelationshipMetadataValue) {
|
||||||
@@ -617,7 +620,6 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return compare;
|
return compare;
|
||||||
}
|
|
||||||
});
|
});
|
||||||
for (MetadataValue metadataValue : metadataValues) {
|
for (MetadataValue metadataValue : metadataValues) {
|
||||||
//Retrieve & store the place for each metadata value
|
//Retrieve & store the place for each metadata value
|
||||||
@@ -634,7 +636,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
|||||||
String authority = metadataValue.getAuthority();
|
String authority = metadataValue.getAuthority();
|
||||||
String relationshipId = StringUtils.split(authority, "::")[1];
|
String relationshipId = StringUtils.split(authority, "::")[1];
|
||||||
Relationship relationship = relationshipService.find(context, Integer.parseInt(relationshipId));
|
Relationship relationship = relationshipService.find(context, Integer.parseInt(relationshipId));
|
||||||
if (relationship.getLeftItem().equals((Item) dso)) {
|
if (relationship.getLeftItem().equals(dso)) {
|
||||||
relationship.setLeftPlace(mvPlace);
|
relationship.setLeftPlace(mvPlace);
|
||||||
} else {
|
} else {
|
||||||
relationship.setRightPlace(mvPlace);
|
relationship.setRightPlace(mvPlace);
|
||||||
|
@@ -12,7 +12,6 @@ import java.io.InputStream;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -288,9 +287,10 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl<Item> implements It
|
|||||||
return itemDAO.findAll(context, true, true);
|
return itemDAO.findAll(context, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Iterator<Item> findAllRegularItems(Context context) throws SQLException {
|
public Iterator<Item> findAllRegularItems(Context context) throws SQLException {
|
||||||
return itemDAO.findAllRegularItems(context);
|
return itemDAO.findAllRegularItems(context);
|
||||||
};
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<Item> findBySubmitter(Context context, EPerson eperson) throws SQLException {
|
public Iterator<Item> findBySubmitter(Context context, EPerson eperson) throws SQLException {
|
||||||
@@ -1054,7 +1054,7 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl<Item> implements It
|
|||||||
List<Collection> linkedCollections = item.getCollections();
|
List<Collection> linkedCollections = item.getCollections();
|
||||||
List<Collection> notLinkedCollections = new ArrayList<>(allCollections.size() - linkedCollections.size());
|
List<Collection> notLinkedCollections = new ArrayList<>(allCollections.size() - linkedCollections.size());
|
||||||
|
|
||||||
if ((allCollections.size() - linkedCollections.size()) == 0) {
|
if (allCollections.size() - linkedCollections.size() == 0) {
|
||||||
return notLinkedCollections;
|
return notLinkedCollections;
|
||||||
}
|
}
|
||||||
for (Collection collection : allCollections) {
|
for (Collection collection : allCollections) {
|
||||||
@@ -1149,6 +1149,7 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl<Item> implements It
|
|||||||
* @return <code>true</code> if the item is an inprogress submission, i.e. a WorkspaceItem or WorkflowItem
|
* @return <code>true</code> if the item is an inprogress submission, i.e. a WorkspaceItem or WorkflowItem
|
||||||
* @throws SQLException An exception that provides information on a database access error or other errors.
|
* @throws SQLException An exception that provides information on a database access error or other errors.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean isInProgressSubmission(Context context, Item item) throws SQLException {
|
public boolean isInProgressSubmission(Context context, Item item) throws SQLException {
|
||||||
return workspaceItemService.findByItem(context, item) != null
|
return workspaceItemService.findByItem(context, item) != null
|
||||||
|| workflowItemService.findByItem(context, item) != null;
|
|| workflowItemService.findByItem(context, item) != null;
|
||||||
@@ -1179,8 +1180,8 @@ prevent the generation of resource policy entry values with null dspace_object a
|
|||||||
if (!authorizeService
|
if (!authorizeService
|
||||||
.isAnIdenticalPolicyAlreadyInPlace(context, dso, defaultPolicy.getGroup(), Constants.READ,
|
.isAnIdenticalPolicyAlreadyInPlace(context, dso, defaultPolicy.getGroup(), Constants.READ,
|
||||||
defaultPolicy.getID()) &&
|
defaultPolicy.getID()) &&
|
||||||
((!appendMode && this.isNotAlreadyACustomRPOfThisTypeOnDSO(context, dso)) ||
|
(!appendMode && this.isNotAlreadyACustomRPOfThisTypeOnDSO(context, dso) ||
|
||||||
(appendMode && this.shouldBeAppended(context, dso, defaultPolicy)))) {
|
appendMode && this.shouldBeAppended(context, dso, defaultPolicy))) {
|
||||||
ResourcePolicy newPolicy = resourcePolicyService.clone(context, defaultPolicy);
|
ResourcePolicy newPolicy = resourcePolicyService.clone(context, defaultPolicy);
|
||||||
newPolicy.setdSpaceObject(dso);
|
newPolicy.setdSpaceObject(dso);
|
||||||
newPolicy.setAction(Constants.READ);
|
newPolicy.setAction(Constants.READ);
|
||||||
@@ -1611,7 +1612,7 @@ prevent the generation of resource policy entry values with null dspace_object a
|
|||||||
fullMetadataValueList.addAll(relationshipMetadataService.getRelationshipMetadata(item, true));
|
fullMetadataValueList.addAll(relationshipMetadataService.getRelationshipMetadata(item, true));
|
||||||
fullMetadataValueList.addAll(dbMetadataValues);
|
fullMetadataValueList.addAll(dbMetadataValues);
|
||||||
|
|
||||||
item.setCachedMetadata(sortMetadataValueList(fullMetadataValueList));
|
item.setCachedMetadata(MetadataValueComparators.sort(fullMetadataValueList));
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("Called getMetadata for " + item.getID() + " based on cache");
|
log.debug("Called getMetadata for " + item.getID() + " based on cache");
|
||||||
@@ -1653,28 +1654,6 @@ prevent the generation of resource policy entry values with null dspace_object a
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method will sort the List of MetadataValue objects based on the MetadataSchema, MetadataField Element,
|
|
||||||
* MetadataField Qualifier and MetadataField Place in that order.
|
|
||||||
* @param listToReturn The list to be sorted
|
|
||||||
* @return The list sorted on those criteria
|
|
||||||
*/
|
|
||||||
private List<MetadataValue> sortMetadataValueList(List<MetadataValue> listToReturn) {
|
|
||||||
Comparator<MetadataValue> comparator = Comparator.comparing(
|
|
||||||
metadataValue -> metadataValue.getMetadataField().getMetadataSchema().getName(),
|
|
||||||
Comparator.nullsFirst(Comparator.naturalOrder()));
|
|
||||||
comparator = comparator.thenComparing(metadataValue -> metadataValue.getMetadataField().getElement(),
|
|
||||||
Comparator.nullsFirst(Comparator.naturalOrder()));
|
|
||||||
comparator = comparator.thenComparing(metadataValue -> metadataValue.getMetadataField().getQualifier(),
|
|
||||||
Comparator.nullsFirst(Comparator.naturalOrder()));
|
|
||||||
comparator = comparator.thenComparing(metadataValue -> metadataValue.getPlace(),
|
|
||||||
Comparator.nullsFirst(Comparator.naturalOrder()));
|
|
||||||
|
|
||||||
Stream<MetadataValue> metadataValueStream = listToReturn.stream().sorted(comparator);
|
|
||||||
listToReturn = metadataValueStream.collect(Collectors.toList());
|
|
||||||
return listToReturn;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MetadataValue addMetadata(Context context, Item dso, String schema, String element, String qualifier,
|
public MetadataValue addMetadata(Context context, Item dso, String schema, String element, String qualifier,
|
||||||
String lang, String value, String authority, int confidence, int place) throws SQLException {
|
String lang, String value, String authority, int confidence, int place) throws SQLException {
|
||||||
|
@@ -19,6 +19,7 @@ import javax.persistence.Lob;
|
|||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.SequenceGenerator;
|
import javax.persistence.SequenceGenerator;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.Transient;
|
||||||
|
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.core.ReloadableEntity;
|
import org.dspace.core.ReloadableEntity;
|
||||||
@@ -171,6 +172,14 @@ public class MetadataValue implements ReloadableEntity<Integer> {
|
|||||||
this.metadataField = metadataField;
|
this.metadataField = metadataField;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code MetadataField#getID()}
|
||||||
|
*/
|
||||||
|
@Transient
|
||||||
|
protected Integer getMetadataFieldId() {
|
||||||
|
return getMetadataField().getID();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the metadata value.
|
* Get the metadata value.
|
||||||
*
|
*
|
||||||
|
@@ -0,0 +1,51 @@
|
|||||||
|
/**
|
||||||
|
* 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 java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class contains only static members that can be used
|
||||||
|
* to sort list of {@link MetadataValue}
|
||||||
|
*
|
||||||
|
* @author Vincenzo Mecca (vins01-4science - vincenzo.mecca at 4science.com)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final class MetadataValueComparators {
|
||||||
|
|
||||||
|
private MetadataValueComparators() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the default comparator that mimics the ordering
|
||||||
|
* applied by the standard {@code @OrderBy} annotation inside
|
||||||
|
* {@link DSpaceObject#getMetadata()}
|
||||||
|
*/
|
||||||
|
public static final Comparator<MetadataValue> defaultComparator =
|
||||||
|
Comparator.comparing(MetadataValue::getMetadataFieldId)
|
||||||
|
.thenComparing(
|
||||||
|
MetadataValue::getPlace,
|
||||||
|
Comparator.nullsFirst(Comparator.naturalOrder())
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method creates a new {@code List<MetadataValue>} ordered by the
|
||||||
|
* {@code MetadataComparators#defaultComparator}.
|
||||||
|
*
|
||||||
|
* @param metadataValues
|
||||||
|
* @return {@code List<MetadataValue>} ordered copy list using stream.
|
||||||
|
*/
|
||||||
|
public static final List<MetadataValue> sort(List<MetadataValue> metadataValues) {
|
||||||
|
return metadataValues
|
||||||
|
.stream()
|
||||||
|
.sorted(MetadataValueComparators.defaultComparator)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -11,8 +11,8 @@ import static com.jayway.jsonpath.JsonPath.read;
|
|||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
import static org.hamcrest.CoreMatchers.not;
|
import static org.hamcrest.CoreMatchers.not;
|
||||||
import static org.hamcrest.CoreMatchers.startsWith;
|
import static org.hamcrest.CoreMatchers.startsWith;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
@@ -23,8 +23,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
import org.dspace.app.rest.matcher.MetadataMatcher;
|
import org.dspace.app.rest.matcher.MetadataMatcher;
|
||||||
@@ -50,6 +53,7 @@ import org.dspace.content.service.EntityTypeService;
|
|||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
import org.dspace.content.service.RelationshipTypeService;
|
import org.dspace.content.service.RelationshipTypeService;
|
||||||
import org.dspace.content.service.WorkspaceItemService;
|
import org.dspace.content.service.WorkspaceItemService;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
import org.hamcrest.Matcher;
|
import org.hamcrest.Matcher;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
@@ -63,6 +67,13 @@ import org.springframework.http.MediaType;
|
|||||||
*/
|
*/
|
||||||
public class PatchMetadataIT extends AbstractEntityIntegrationTest {
|
public class PatchMetadataIT extends AbstractEntityIntegrationTest {
|
||||||
|
|
||||||
|
private static final String SECTIONS_TRADITIONALPAGEONE_DC_CONTRIBUTOR_AUTHOR =
|
||||||
|
"/sections/traditionalpageone/dc.contributor.author/%1$s";
|
||||||
|
|
||||||
|
private static final String getPath(Object element) {
|
||||||
|
return String.format(SECTIONS_TRADITIONALPAGEONE_DC_CONTRIBUTOR_AUTHOR, element);
|
||||||
|
}
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RelationshipTypeService relationshipTypeService;
|
private RelationshipTypeService relationshipTypeService;
|
||||||
|
|
||||||
@@ -75,6 +86,9 @@ public class PatchMetadataIT extends AbstractEntityIntegrationTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private WorkspaceItemService workspaceItemService;
|
private WorkspaceItemService workspaceItemService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigurationService configurationService;
|
||||||
|
|
||||||
private Collection collection;
|
private Collection collection;
|
||||||
private Collection collection2;
|
private Collection collection2;
|
||||||
private WorkspaceItem publicationWorkspaceItem;
|
private WorkspaceItem publicationWorkspaceItem;
|
||||||
@@ -297,8 +311,6 @@ public class PatchMetadataIT extends AbstractEntityIntegrationTest {
|
|||||||
.withEntityType("Publication")
|
.withEntityType("Publication")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
String adminToken = getAuthToken(admin.getEmail(), password);
|
|
||||||
|
|
||||||
// Make sure we grab the latest instance of the Item from the database before adding a regular author
|
// Make sure we grab the latest instance of the Item from the database before adding a regular author
|
||||||
WorkspaceItem publication = workspaceItemService.find(context, publicationWorkspaceItem.getID());
|
WorkspaceItem publication = workspaceItemService.find(context, publicationWorkspaceItem.getID());
|
||||||
itemService.addMetadata(context, publication.getItem(),
|
itemService.addMetadata(context, publication.getItem(),
|
||||||
@@ -920,6 +932,41 @@ public class PatchMetadataIT extends AbstractEntityIntegrationTest {
|
|||||||
replaceTraditionalPageOneAuthorTest(3, expectedOrder);
|
replaceTraditionalPageOneAuthorTest(3, expectedOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void replaceMultipleTraditionalPageOnePlainTextAuthorTest() throws Exception {
|
||||||
|
final boolean virtualMetadataEnabled =
|
||||||
|
configurationService.getBooleanProperty("item.enable-virtual-metadata", false);
|
||||||
|
|
||||||
|
configurationService.setProperty("item.enable-virtual-metadata", false);
|
||||||
|
try {
|
||||||
|
initPlainTextPublicationWorkspace();
|
||||||
|
|
||||||
|
Map<Integer, String> replacedAuthors =
|
||||||
|
Map.of(
|
||||||
|
0, authorsOriginalOrder.get(4),
|
||||||
|
1, authorsOriginalOrder.get(1),
|
||||||
|
2, authorsOriginalOrder.get(2),
|
||||||
|
3, authorsOriginalOrder.get(3),
|
||||||
|
4, authorsOriginalOrder.get(0)
|
||||||
|
);
|
||||||
|
|
||||||
|
List<String> expectedOrder =
|
||||||
|
List.of(
|
||||||
|
authorsOriginalOrder.get(4),
|
||||||
|
authorsOriginalOrder.get(1),
|
||||||
|
authorsOriginalOrder.get(2),
|
||||||
|
authorsOriginalOrder.get(3),
|
||||||
|
authorsOriginalOrder.get(0)
|
||||||
|
);
|
||||||
|
|
||||||
|
replaceTraditionalPageMultipleAuthorsTest(replacedAuthors, expectedOrder);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw e;
|
||||||
|
} finally {
|
||||||
|
configurationService.setProperty("item.enable-virtual-metadata", virtualMetadataEnabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test will add an author (dc.contributor.author) within a workspace publication's "traditionalpageone"
|
* This test will add an author (dc.contributor.author) within a workspace publication's "traditionalpageone"
|
||||||
@@ -1393,24 +1440,7 @@ public class PatchMetadataIT extends AbstractEntityIntegrationTest {
|
|||||||
ops.add(moveOperation);
|
ops.add(moveOperation);
|
||||||
String patchBody = getPatchContent(ops);
|
String patchBody = getPatchContent(ops);
|
||||||
|
|
||||||
String token = getAuthToken(admin.getEmail(), password);
|
assertReplacementOrder(expectedOrder, patchBody);
|
||||||
|
|
||||||
getClient(token).perform(patch("/api/submission/workspaceitems/" + publicationWorkspaceItem.getID())
|
|
||||||
.content(patchBody)
|
|
||||||
.contentType(javax.ws.rs.core.MediaType.APPLICATION_JSON_PATCH_JSON))
|
|
||||||
.andExpect(status().isOk());
|
|
||||||
|
|
||||||
String authorField = "dc.contributor.author";
|
|
||||||
getClient(token).perform(get("/api/submission/workspaceitems/" + publicationWorkspaceItem.getID()))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(content().contentType(contentType))
|
|
||||||
.andExpect(jsonPath("$.sections.traditionalpageone", Matchers.allOf(
|
|
||||||
Matchers.is(MetadataMatcher.matchMetadata(authorField, expectedOrder.get(0), 0)),
|
|
||||||
Matchers.is(MetadataMatcher.matchMetadata(authorField, expectedOrder.get(1), 1)),
|
|
||||||
Matchers.is(MetadataMatcher.matchMetadata(authorField, expectedOrder.get(2), 2)),
|
|
||||||
Matchers.is(MetadataMatcher.matchMetadata(authorField, expectedOrder.get(3), 3)),
|
|
||||||
Matchers.is(MetadataMatcher.matchMetadata(authorField, expectedOrder.get(4), 4))
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1450,33 +1480,66 @@ public class PatchMetadataIT extends AbstractEntityIntegrationTest {
|
|||||||
* @param expectedOrder A list of author names sorted in the expected order
|
* @param expectedOrder A list of author names sorted in the expected order
|
||||||
*/
|
*/
|
||||||
private void replaceTraditionalPageOneAuthorTest(int path, List<String> expectedOrder) throws Exception {
|
private void replaceTraditionalPageOneAuthorTest(int path, List<String> expectedOrder) throws Exception {
|
||||||
List<Operation> ops = new ArrayList<Operation>();
|
String patchBody =
|
||||||
MetadataValueRest value = new MetadataValueRest();
|
getPatchContent(
|
||||||
value.setValue(replacedAuthor);
|
List.of(
|
||||||
|
this.mapToReplaceOperation(path, replacedAuthor)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
assertReplacementOrder(expectedOrder, patchBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void replaceTraditionalPageMultipleAuthorsTest(
|
||||||
|
Map<Integer, String> values, List<String> expectedOrder
|
||||||
|
) throws Exception {
|
||||||
|
List<Operation> ops =
|
||||||
|
values
|
||||||
|
.entrySet()
|
||||||
|
.stream()
|
||||||
|
.sorted(Comparator.comparing(Map.Entry::getKey))
|
||||||
|
.map(entry -> mapToReplaceOperation(entry.getKey(), entry.getValue()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
ReplaceOperation replaceOperation = new ReplaceOperation("/sections/traditionalpageone/dc.contributor.author/"
|
|
||||||
+ path, value);
|
|
||||||
ops.add(replaceOperation);
|
|
||||||
String patchBody = getPatchContent(ops);
|
String patchBody = getPatchContent(ops);
|
||||||
|
|
||||||
|
assertReplacementOrder(expectedOrder, patchBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ReplaceOperation mapToReplaceOperation(int path, String author) {
|
||||||
|
return new ReplaceOperation(getPath(path), new MetadataValueRest(author));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertReplacementOrder(List<String> expectedOrder, String patchBody) throws Exception, SQLException {
|
||||||
String token = getAuthToken(admin.getEmail(), password);
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
getClient(token).perform(patch("/api/submission/workspaceitems/" + publicationWorkspaceItem.getID())
|
getClient(token)
|
||||||
|
.perform(
|
||||||
|
patch("/api/submission/workspaceitems/" + publicationWorkspaceItem.getID())
|
||||||
.content(patchBody)
|
.content(patchBody)
|
||||||
.contentType(javax.ws.rs.core.MediaType.APPLICATION_JSON_PATCH_JSON))
|
.contentType(javax.ws.rs.core.MediaType.APPLICATION_JSON_PATCH_JSON)
|
||||||
|
)
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
String authorField = "dc.contributor.author";
|
String authorField = "dc.contributor.author";
|
||||||
getClient(token).perform(get("/api/submission/workspaceitems/" + publicationWorkspaceItem.getID()))
|
getClient(token)
|
||||||
|
.perform(get("/api/submission/workspaceitems/" + publicationWorkspaceItem.getID()))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(
|
||||||
.andExpect(jsonPath("$.sections.traditionalpageone", Matchers.allOf(
|
content().contentType(contentType)
|
||||||
|
)
|
||||||
|
.andExpect(
|
||||||
|
jsonPath(
|
||||||
|
"$.sections.traditionalpageone",
|
||||||
|
Matchers.allOf(
|
||||||
Matchers.is(MetadataMatcher.matchMetadata(authorField, expectedOrder.get(0), 0)),
|
Matchers.is(MetadataMatcher.matchMetadata(authorField, expectedOrder.get(0), 0)),
|
||||||
Matchers.is(MetadataMatcher.matchMetadata(authorField, expectedOrder.get(1), 1)),
|
Matchers.is(MetadataMatcher.matchMetadata(authorField, expectedOrder.get(1), 1)),
|
||||||
Matchers.is(MetadataMatcher.matchMetadata(authorField, expectedOrder.get(2), 2)),
|
Matchers.is(MetadataMatcher.matchMetadata(authorField, expectedOrder.get(2), 2)),
|
||||||
Matchers.is(MetadataMatcher.matchMetadata(authorField, expectedOrder.get(3), 3)),
|
Matchers.is(MetadataMatcher.matchMetadata(authorField, expectedOrder.get(3), 3)),
|
||||||
Matchers.is(MetadataMatcher.matchMetadata(authorField, expectedOrder.get(4), 4))
|
Matchers.is(MetadataMatcher.matchMetadata(authorField, expectedOrder.get(4), 4))
|
||||||
)));
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1490,8 +1553,7 @@ public class PatchMetadataIT extends AbstractEntityIntegrationTest {
|
|||||||
List<Operation> ops = new ArrayList<Operation>();
|
List<Operation> ops = new ArrayList<Operation>();
|
||||||
MetadataValueRest value = new MetadataValueRest();
|
MetadataValueRest value = new MetadataValueRest();
|
||||||
value.setValue(addedAuthor);
|
value.setValue(addedAuthor);
|
||||||
AddOperation addOperation = new AddOperation("/sections/traditionalpageone/dc.contributor.author/" + path,
|
AddOperation addOperation = new AddOperation(getPath(path), value);
|
||||||
value);
|
|
||||||
ops.add(addOperation);
|
ops.add(addOperation);
|
||||||
String patchBody = getPatchContent(ops);
|
String patchBody = getPatchContent(ops);
|
||||||
|
|
||||||
@@ -1525,8 +1587,7 @@ public class PatchMetadataIT extends AbstractEntityIntegrationTest {
|
|||||||
*/
|
*/
|
||||||
private void removeTraditionalPageOneAuthorTest(int path, List<String> expectedOrder) throws Exception {
|
private void removeTraditionalPageOneAuthorTest(int path, List<String> expectedOrder) throws Exception {
|
||||||
List<Operation> ops = new ArrayList<Operation>();
|
List<Operation> ops = new ArrayList<Operation>();
|
||||||
RemoveOperation removeOperation = new RemoveOperation("/sections/traditionalpageone/dc.contributor.author/"
|
RemoveOperation removeOperation = new RemoveOperation(getPath(path));
|
||||||
+ path);
|
|
||||||
ops.add(removeOperation);
|
ops.add(removeOperation);
|
||||||
String patchBody = getPatchContent(ops);
|
String patchBody = getPatchContent(ops);
|
||||||
|
|
||||||
@@ -1600,8 +1661,10 @@ public class PatchMetadataIT extends AbstractEntityIntegrationTest {
|
|||||||
* @param path The "path" index to use for the Move operation
|
* @param path The "path" index to use for the Move operation
|
||||||
*/
|
*/
|
||||||
private MoveOperation getTraditionalPageOneMoveAuthorOperation(int from, int path) {
|
private MoveOperation getTraditionalPageOneMoveAuthorOperation(int from, int path) {
|
||||||
return new MoveOperation("/sections/traditionalpageone/dc.contributor.author/" + path,
|
return new MoveOperation(
|
||||||
"/sections/traditionalpageone/dc.contributor.author/" + from);
|
getPath(path),
|
||||||
|
getPath(from)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user