mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-14 21:43:11 +00:00
[CST-7754] LYRASIS: Supervisor orders (REST).
This commit is contained in:

committed by
eskander

parent
ec0853ddad
commit
dea4b5e17f
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* 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.app.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class provides an exception to be used when a conflict on a resource
|
||||||
|
* occurs.
|
||||||
|
*
|
||||||
|
* @author Mohamed Eskander (mohamed.eskander at 4science dot it)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ResourceConflictException extends RuntimeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final Object resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a ResourceConflictException with a message and the conflicting
|
||||||
|
* resource.
|
||||||
|
*
|
||||||
|
* @param message the error message
|
||||||
|
* @param resource the resource that caused the conflict
|
||||||
|
*/
|
||||||
|
public ResourceConflictException(String message, Object resource) {
|
||||||
|
super(message);
|
||||||
|
this.resource = resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getResource() {
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.discovery;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.apache.solr.common.SolrInputDocument;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.service.WorkspaceItemService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.discovery.indexobject.IndexableInProgressSubmission;
|
||||||
|
import org.dspace.discovery.indexobject.IndexableWorkflowItem;
|
||||||
|
import org.dspace.discovery.indexobject.IndexableWorkspaceItem;
|
||||||
|
import org.dspace.supervision.SupervisionOrder;
|
||||||
|
import org.dspace.supervision.service.SupervisionOrderService;
|
||||||
|
import org.dspace.workflow.WorkflowItemService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Mohamed Eskander (mohamed.eskander at 4science dot it)
|
||||||
|
*/
|
||||||
|
public class SolrServiceSupervisionOrderIndexingPlugin implements SolrServiceIndexPlugin {
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
private WorkspaceItemService workspaceItemService;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
private WorkflowItemService workflowItemService;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
private SupervisionOrderService supervisionOrderService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void additionalIndex(Context context, IndexableObject indexableObject, SolrInputDocument document) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
if (!(indexableObject instanceof IndexableWorkspaceItem) &&
|
||||||
|
!(indexableObject instanceof IndexableWorkflowItem)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Item item =
|
||||||
|
(((IndexableInProgressSubmission) indexableObject).getIndexedObject()).getItem();
|
||||||
|
|
||||||
|
if (Objects.isNull(item)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
addSupervisedField(context, item, document);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addSupervisedField(Context context, Item item, SolrInputDocument document) throws SQLException {
|
||||||
|
List<SupervisionOrder> supervisionOrders = supervisionOrderService.findByItem(context, item);
|
||||||
|
if (CollectionUtils.isNotEmpty(supervisionOrders)) {
|
||||||
|
document.addField("supervised", true);
|
||||||
|
} else {
|
||||||
|
document.addField("supervised", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -40,6 +40,11 @@ public class SolrServiceWorkspaceWorkflowRestrictionPlugin implements SolrServic
|
|||||||
*/
|
*/
|
||||||
public static final String DISCOVER_WORKFLOW_ADMIN_CONFIGURATION_NAME = "workflowAdmin";
|
public static final String DISCOVER_WORKFLOW_ADMIN_CONFIGURATION_NAME = "workflowAdmin";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the discover configuration used by administrators to search for workspace and workflow tasks
|
||||||
|
*/
|
||||||
|
public static final String DISCOVER_SUPERVISION_CONFIGURATION_NAME = "supervision";
|
||||||
|
|
||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
protected GroupService groupService;
|
protected GroupService groupService;
|
||||||
|
|
||||||
@@ -60,18 +65,22 @@ public class SolrServiceWorkspaceWorkflowRestrictionPlugin implements SolrServic
|
|||||||
);
|
);
|
||||||
boolean isWorkflowAdmin = isAdmin(context)
|
boolean isWorkflowAdmin = isAdmin(context)
|
||||||
&& DISCOVER_WORKFLOW_ADMIN_CONFIGURATION_NAME.equals(discoveryQuery.getDiscoveryConfigurationName());
|
&& DISCOVER_WORKFLOW_ADMIN_CONFIGURATION_NAME.equals(discoveryQuery.getDiscoveryConfigurationName());
|
||||||
|
|
||||||
|
boolean isSupervision =
|
||||||
|
DISCOVER_SUPERVISION_CONFIGURATION_NAME.equals(discoveryQuery.getDiscoveryConfigurationName());
|
||||||
|
|
||||||
EPerson currentUser = context.getCurrentUser();
|
EPerson currentUser = context.getCurrentUser();
|
||||||
|
|
||||||
// extra security check to avoid the possibility that an anonymous user
|
// extra security check to avoid the possibility that an anonymous user
|
||||||
// get access to workspace or workflow
|
// get access to workspace or workflow
|
||||||
if (currentUser == null && (isWorkflow || isWorkspace)) {
|
if (currentUser == null && (isWorkflow || isWorkspace || isSupervision)) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"An anonymous user cannot perform a workspace or workflow search");
|
"An anonymous user cannot perform a workspace or workflow search");
|
||||||
}
|
}
|
||||||
if (isWorkspace) {
|
if (isWorkspace) {
|
||||||
// insert filter by submitter
|
// insert filter by submitter
|
||||||
solrQuery.addFilterQuery("submitter_authority:(" + currentUser.getID() + ")");
|
solrQuery.addFilterQuery("submitter_authority:(" + currentUser.getID() + ")");
|
||||||
} else if (isWorkflow && !isWorkflowAdmin) {
|
} else if ((isWorkflow && !isWorkflowAdmin) || (isSupervision && !isAdmin(context))) {
|
||||||
// Retrieve all the groups the current user is a member of !
|
// Retrieve all the groups the current user is a member of !
|
||||||
Set<Group> groups;
|
Set<Group> groups;
|
||||||
try {
|
try {
|
||||||
|
@@ -22,6 +22,8 @@ import org.dspace.discovery.indexobject.factory.CollectionIndexFactory;
|
|||||||
import org.dspace.discovery.indexobject.factory.InprogressSubmissionIndexFactory;
|
import org.dspace.discovery.indexobject.factory.InprogressSubmissionIndexFactory;
|
||||||
import org.dspace.discovery.indexobject.factory.ItemIndexFactory;
|
import org.dspace.discovery.indexobject.factory.ItemIndexFactory;
|
||||||
import org.dspace.eperson.EPerson;
|
import org.dspace.eperson.EPerson;
|
||||||
|
import org.dspace.supervision.SupervisionOrder;
|
||||||
|
import org.dspace.supervision.service.SupervisionOrderService;
|
||||||
import org.dspace.util.SolrUtils;
|
import org.dspace.util.SolrUtils;
|
||||||
import org.dspace.workflow.WorkflowItem;
|
import org.dspace.workflow.WorkflowItem;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -39,6 +41,9 @@ public abstract class InprogressSubmissionIndexFactoryImpl
|
|||||||
@Autowired
|
@Autowired
|
||||||
protected ItemIndexFactory indexableItemService;
|
protected ItemIndexFactory indexableItemService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected SupervisionOrderService supervisionOrderService;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SolrInputDocument buildDocument(Context context, T indexableObject) throws SQLException, IOException {
|
public SolrInputDocument buildDocument(Context context, T indexableObject) throws SQLException, IOException {
|
||||||
@@ -60,6 +65,8 @@ public abstract class InprogressSubmissionIndexFactoryImpl
|
|||||||
submitter.getFullName());
|
submitter.getFullName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addSupervisedByFacetIndex(context, item, doc);
|
||||||
|
|
||||||
doc.addField("inprogress.item", new IndexableItem(inProgressSubmission.getItem()).getUniqueIndexID());
|
doc.addField("inprogress.item", new IndexableItem(inProgressSubmission.getItem()).getUniqueIndexID());
|
||||||
|
|
||||||
// get the location string (for searching by collection & community)
|
// get the location string (for searching by collection & community)
|
||||||
@@ -82,4 +89,13 @@ public abstract class InprogressSubmissionIndexFactoryImpl
|
|||||||
indexableItemService.addDiscoveryFields(doc, context, item, discoveryConfigurations);
|
indexableItemService.addDiscoveryFields(doc, context, item, discoveryConfigurations);
|
||||||
indexableCollectionService.storeCommunityCollectionLocations(doc, locations);
|
indexableCollectionService.storeCommunityCollectionLocations(doc, locations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addSupervisedByFacetIndex(Context context, Item item, SolrInputDocument doc) throws SQLException {
|
||||||
|
List<SupervisionOrder> supervisionOrders = supervisionOrderService.findByItem(context, item);
|
||||||
|
for (SupervisionOrder supervisionOrder : supervisionOrders) {
|
||||||
|
addFacetIndex(doc, "supervisedBy", supervisionOrder.getGroup().getID().toString(),
|
||||||
|
supervisionOrder.getGroup().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
* 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.supervision;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.SequenceGenerator;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.core.ReloadableEntity;
|
||||||
|
import org.dspace.eperson.Group;
|
||||||
|
import org.dspace.supervision.service.SupervisionOrderService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database entity representation of the supervision_orders table
|
||||||
|
*
|
||||||
|
* @author Mohamed Eskander (mohamed.eskander at 4science dot it)
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Table(name = "supervision_orders")
|
||||||
|
public class SupervisionOrder implements ReloadableEntity<Integer> {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(name = "id")
|
||||||
|
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "supervision_orders_seq")
|
||||||
|
@SequenceGenerator(name = "supervision_orders_seq", sequenceName = "supervision_orders_seq", allocationSize = 1)
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "item_id")
|
||||||
|
private Item item;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "eperson_group_id")
|
||||||
|
private Group group;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected constructor, create object using:
|
||||||
|
* {@link SupervisionOrderService#create(Context, Item, Group)}
|
||||||
|
*/
|
||||||
|
protected SupervisionOrder() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getID() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item getItem() {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItem(Item item) {
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Group getGroup() {
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGroup(Group group) {
|
||||||
|
this.group = group;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,126 @@
|
|||||||
|
/**
|
||||||
|
* 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.supervision;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.service.ItemService;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.eperson.EPerson;
|
||||||
|
import org.dspace.eperson.Group;
|
||||||
|
import org.dspace.eperson.service.GroupService;
|
||||||
|
import org.dspace.event.Event;
|
||||||
|
import org.dspace.supervision.dao.SupervisionOrderDao;
|
||||||
|
import org.dspace.supervision.service.SupervisionOrderService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of {@link SupervisionOrderService}
|
||||||
|
*
|
||||||
|
* @author Mohamed Eskander (mohamed.eskander at 4science dot it)
|
||||||
|
*/
|
||||||
|
public class SupervisionOrderServiceImpl implements SupervisionOrderService {
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
private SupervisionOrderDao supervisionDao;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
private GroupService groupService;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
private ItemService itemService;
|
||||||
|
|
||||||
|
protected SupervisionOrderServiceImpl() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SupervisionOrder create(Context context) throws SQLException, AuthorizeException {
|
||||||
|
return supervisionDao.create(context, new SupervisionOrder());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SupervisionOrder find(Context context, int id) throws SQLException {
|
||||||
|
return supervisionDao.findByID(context, SupervisionOrder.class, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Context context, SupervisionOrder supervisionOrder)
|
||||||
|
throws SQLException, AuthorizeException {
|
||||||
|
supervisionDao.save(context, supervisionOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Context context, List<SupervisionOrder> supervisionOrders)
|
||||||
|
throws SQLException, AuthorizeException {
|
||||||
|
if (CollectionUtils.isNotEmpty(supervisionOrders)) {
|
||||||
|
for (SupervisionOrder supervisionOrder : supervisionOrders) {
|
||||||
|
supervisionDao.save(context, supervisionOrder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(Context context, SupervisionOrder supervisionOrder) throws SQLException, AuthorizeException {
|
||||||
|
supervisionDao.delete(context, supervisionOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SupervisionOrder create(Context context, Item item, Group group) throws SQLException {
|
||||||
|
SupervisionOrder supervisionOrder = new SupervisionOrder();
|
||||||
|
supervisionOrder.setItem(item);
|
||||||
|
supervisionOrder.setGroup(group);
|
||||||
|
SupervisionOrder supOrder = supervisionDao.create(context, supervisionOrder);
|
||||||
|
context.addEvent(new Event(Event.MODIFY, Constants.ITEM, item.getID(), null,
|
||||||
|
itemService.getIdentifiers(context, item)));
|
||||||
|
return supOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SupervisionOrder> findAll(Context context) throws SQLException {
|
||||||
|
return supervisionDao.findAll(context, SupervisionOrder.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SupervisionOrder> findByItem(Context context, Item item) throws SQLException {
|
||||||
|
return supervisionDao.findByItem(context, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SupervisionOrder findByItemAndGroup(Context context, Item item, Group group) throws SQLException {
|
||||||
|
return supervisionDao.findByItemAndGroup(context, item, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSupervisor(Context context, EPerson ePerson, Item item) throws SQLException {
|
||||||
|
List<SupervisionOrder> supervisionOrders = findByItem(context, item);
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(supervisionOrders)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return supervisionOrders
|
||||||
|
.stream()
|
||||||
|
.map(SupervisionOrder::getGroup)
|
||||||
|
.anyMatch(group -> isMember(context, ePerson, group));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isMember(Context context, EPerson ePerson, Group group) {
|
||||||
|
try {
|
||||||
|
return groupService.isMember(context, ePerson, group);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* 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.supervision.dao;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.core.GenericDAO;
|
||||||
|
import org.dspace.eperson.Group;
|
||||||
|
import org.dspace.supervision.SupervisionOrder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database Access Object interface class for the SupervisionOrder object.
|
||||||
|
*
|
||||||
|
* The implementation of this class is responsible for all database calls for the SupervisionOrder object
|
||||||
|
* and is autowired by spring
|
||||||
|
*
|
||||||
|
* @author Mohamed Eskander (mohamed.eskander at 4science dot it)
|
||||||
|
*/
|
||||||
|
public interface SupervisionOrderDao extends GenericDAO<SupervisionOrder> {
|
||||||
|
|
||||||
|
List<SupervisionOrder> findByItem(Context context, Item item) throws SQLException;
|
||||||
|
SupervisionOrder findByItemAndGroup(Context context, Item item, Group group) throws SQLException;
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,59 @@
|
|||||||
|
/**
|
||||||
|
* 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.supervision.dao.impl;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
|
import javax.persistence.criteria.Root;
|
||||||
|
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.core.AbstractHibernateDAO;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.eperson.Group;
|
||||||
|
import org.dspace.supervision.SupervisionOrder;
|
||||||
|
import org.dspace.supervision.SupervisionOrder_;
|
||||||
|
import org.dspace.supervision.dao.SupervisionOrderDao;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hibernate implementation of the Database Access Object interface class for the SupervisionOrder object.
|
||||||
|
* This class is responsible for all database calls for the SupervisionOrder object
|
||||||
|
* and is autowired by spring
|
||||||
|
*
|
||||||
|
* @author Mohamed Eskander (mohamed.eskander at 4science dot it)
|
||||||
|
*/
|
||||||
|
public class SupervisionOrderDaoImpl extends AbstractHibernateDAO<SupervisionOrder> implements SupervisionOrderDao {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SupervisionOrder> findByItem(Context context, Item item) throws SQLException {
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, SupervisionOrder.class);
|
||||||
|
|
||||||
|
Root<SupervisionOrder> supervisionOrderRoot = criteriaQuery.from(SupervisionOrder.class);
|
||||||
|
criteriaQuery.select(supervisionOrderRoot);
|
||||||
|
criteriaQuery.where(criteriaBuilder.equal(supervisionOrderRoot.get(SupervisionOrder_.item), item));
|
||||||
|
|
||||||
|
return list(context, criteriaQuery, false, SupervisionOrder.class, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SupervisionOrder findByItemAndGroup(Context context, Item item, Group group) throws SQLException {
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, SupervisionOrder.class);
|
||||||
|
|
||||||
|
Root<SupervisionOrder> supervisionOrderRoot = criteriaQuery.from(SupervisionOrder.class);
|
||||||
|
criteriaQuery.select(supervisionOrderRoot);
|
||||||
|
criteriaQuery.where(criteriaBuilder.and(
|
||||||
|
criteriaBuilder.equal(supervisionOrderRoot.get(SupervisionOrder_.item), item),
|
||||||
|
criteriaBuilder.equal(supervisionOrderRoot.get(SupervisionOrder_.group), group)
|
||||||
|
));
|
||||||
|
|
||||||
|
return singleResult(context, criteriaQuery);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* 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.supervision.enumeration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Mohamed Eskander (mohamed.eskander at 4science dot it)
|
||||||
|
*/
|
||||||
|
public enum SupervisionOrderType {
|
||||||
|
OBSERVER,
|
||||||
|
EDITOR
|
||||||
|
}
|
@@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* 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.supervision.factory;
|
||||||
|
|
||||||
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
|
import org.dspace.supervision.service.SupervisionOrderService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract factory to get services for the supervision package,
|
||||||
|
* use SupervisionOrderServiceFactory.getInstance() to retrieve an implementation
|
||||||
|
*
|
||||||
|
* @author Mohamed Eskander (mohamed.eskander at 4science dot it)
|
||||||
|
*/
|
||||||
|
public abstract class SupervisionOrderServiceFactory {
|
||||||
|
|
||||||
|
public abstract SupervisionOrderService getSupervisionOrderService();
|
||||||
|
|
||||||
|
public static SupervisionOrderServiceFactory getInstance() {
|
||||||
|
return DSpaceServicesFactory.getInstance()
|
||||||
|
.getServiceManager()
|
||||||
|
.getServiceByName("supervisionOrderServiceFactory",
|
||||||
|
SupervisionOrderServiceFactory.class);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* 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.supervision.factory;
|
||||||
|
|
||||||
|
import org.dspace.supervision.service.SupervisionOrderService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory implementation to get services for the supervision package,
|
||||||
|
* use SupervisionOrderServiceFactory.getInstance() to retrieve an implementation
|
||||||
|
*
|
||||||
|
* @author Mohamed Eskander (mohamed.eskander at 4science dot it)
|
||||||
|
*/
|
||||||
|
public class SupervisionOrderServiceFactoryImpl extends SupervisionOrderServiceFactory {
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
private SupervisionOrderService supervisionOrderService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SupervisionOrderService getSupervisionOrderService() {
|
||||||
|
return supervisionOrderService;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* 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.supervision.service;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.eperson.EPerson;
|
||||||
|
import org.dspace.eperson.Group;
|
||||||
|
import org.dspace.service.DSpaceCRUDService;
|
||||||
|
import org.dspace.supervision.SupervisionOrder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service interface class for the SupervisionOrder object.
|
||||||
|
*
|
||||||
|
* @author Mohamed Eskander (mohamed.eskander at 4science dot it)
|
||||||
|
*/
|
||||||
|
public interface SupervisionOrderService extends DSpaceCRUDService<SupervisionOrder> {
|
||||||
|
|
||||||
|
SupervisionOrder create(Context context, Item item, Group group) throws SQLException;
|
||||||
|
List<SupervisionOrder> findAll(Context context) throws SQLException;
|
||||||
|
List<SupervisionOrder> findByItem(Context context, Item item) throws SQLException;
|
||||||
|
SupervisionOrder findByItemAndGroup(Context context, Item item, Group group) throws SQLException;
|
||||||
|
boolean isSupervisor(Context context, EPerson ePerson, Item item) throws SQLException;
|
||||||
|
}
|
@@ -0,0 +1,20 @@
|
|||||||
|
--
|
||||||
|
-- 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/
|
||||||
|
--
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Table to store supervision orders
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CREATE TABLE supervision_orders
|
||||||
|
(
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
item_id UUID REFERENCES Item(uuid) ON DELETE CASCADE,
|
||||||
|
eperson_group_id UUID REFERENCES epersongroup(uuid) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE SEQUENCE supervision_orders_seq;
|
@@ -0,0 +1,20 @@
|
|||||||
|
--
|
||||||
|
-- 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/
|
||||||
|
--
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Table to store supervision orders
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CREATE TABLE supervision_orders
|
||||||
|
(
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
item_id UUID REFERENCES Item(uuid) ON DELETE CASCADE,
|
||||||
|
eperson_group_id UUID REFERENCES epersongroup(uuid) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE SEQUENCE supervision_orders_seq;
|
@@ -0,0 +1,20 @@
|
|||||||
|
--
|
||||||
|
-- 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/
|
||||||
|
--
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Table to store supervision orders
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CREATE TABLE supervision_orders
|
||||||
|
(
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
item_id UUID REFERENCES Item(uuid) ON DELETE CASCADE,
|
||||||
|
eperson_group_id UUID REFERENCES epersongroup(uuid) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE SEQUENCE supervision_orders_seq;
|
@@ -49,6 +49,8 @@ import org.dspace.orcid.service.OrcidTokenService;
|
|||||||
import org.dspace.scripts.factory.ScriptServiceFactory;
|
import org.dspace.scripts.factory.ScriptServiceFactory;
|
||||||
import org.dspace.scripts.service.ProcessService;
|
import org.dspace.scripts.service.ProcessService;
|
||||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
|
import org.dspace.supervision.factory.SupervisionOrderServiceFactory;
|
||||||
|
import org.dspace.supervision.service.SupervisionOrderService;
|
||||||
import org.dspace.versioning.factory.VersionServiceFactory;
|
import org.dspace.versioning.factory.VersionServiceFactory;
|
||||||
import org.dspace.versioning.service.VersionHistoryService;
|
import org.dspace.versioning.service.VersionHistoryService;
|
||||||
import org.dspace.versioning.service.VersioningService;
|
import org.dspace.versioning.service.VersioningService;
|
||||||
@@ -102,6 +104,8 @@ public abstract class AbstractBuilder<T, S> {
|
|||||||
static OrcidHistoryService orcidHistoryService;
|
static OrcidHistoryService orcidHistoryService;
|
||||||
static OrcidQueueService orcidQueueService;
|
static OrcidQueueService orcidQueueService;
|
||||||
static OrcidTokenService orcidTokenService;
|
static OrcidTokenService orcidTokenService;
|
||||||
|
static SupervisionOrderService supervisionOrderService;
|
||||||
|
|
||||||
|
|
||||||
protected Context context;
|
protected Context context;
|
||||||
|
|
||||||
@@ -161,6 +165,7 @@ public abstract class AbstractBuilder<T, S> {
|
|||||||
orcidHistoryService = OrcidServiceFactory.getInstance().getOrcidHistoryService();
|
orcidHistoryService = OrcidServiceFactory.getInstance().getOrcidHistoryService();
|
||||||
orcidQueueService = OrcidServiceFactory.getInstance().getOrcidQueueService();
|
orcidQueueService = OrcidServiceFactory.getInstance().getOrcidQueueService();
|
||||||
orcidTokenService = OrcidServiceFactory.getInstance().getOrcidTokenService();
|
orcidTokenService = OrcidServiceFactory.getInstance().getOrcidTokenService();
|
||||||
|
supervisionOrderService = SupervisionOrderServiceFactory.getInstance().getSupervisionOrderService();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -194,6 +199,7 @@ public abstract class AbstractBuilder<T, S> {
|
|||||||
requestItemService = null;
|
requestItemService = null;
|
||||||
versioningService = null;
|
versioningService = null;
|
||||||
orcidTokenService = null;
|
orcidTokenService = null;
|
||||||
|
supervisionOrderService = null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,94 @@
|
|||||||
|
/**
|
||||||
|
* 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.builder;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.eperson.Group;
|
||||||
|
import org.dspace.supervision.SupervisionOrder;
|
||||||
|
import org.dspace.supervision.service.SupervisionOrderService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract builder to construct SupervisionOrder Objects
|
||||||
|
*
|
||||||
|
* @author Mohamed Eskander (mohamed.eskander at 4science dot it)
|
||||||
|
*/
|
||||||
|
public class SupervisionOrderBuilder
|
||||||
|
extends AbstractBuilder<SupervisionOrder, SupervisionOrderService> {
|
||||||
|
|
||||||
|
private static final Logger log = LogManager.getLogger(SupervisionOrderBuilder.class);
|
||||||
|
|
||||||
|
private SupervisionOrder supervisionOrder;
|
||||||
|
|
||||||
|
protected SupervisionOrderBuilder(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SupervisionOrderBuilder createSupervisionOrder(Context context, Item item, Group group) {
|
||||||
|
SupervisionOrderBuilder builder = new SupervisionOrderBuilder(context);
|
||||||
|
return builder.create(context, item, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SupervisionOrderBuilder create(Context context, Item item, Group group) {
|
||||||
|
try {
|
||||||
|
this.context = context;
|
||||||
|
this.supervisionOrder = getService().create(context, item, group);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error in SupervisionOrderBuilder.create(..), error: ", e);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cleanup() throws Exception {
|
||||||
|
delete(supervisionOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SupervisionOrder build() throws SQLException, AuthorizeException {
|
||||||
|
try {
|
||||||
|
getService().update(context, supervisionOrder);
|
||||||
|
context.dispatchEvents();
|
||||||
|
indexingService.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error in SupervisionOrderBuilder.build(), error: ", e);
|
||||||
|
}
|
||||||
|
return supervisionOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(Context context, SupervisionOrder supervisionOrder) throws Exception {
|
||||||
|
if (Objects.nonNull(supervisionOrder)) {
|
||||||
|
getService().delete(context, supervisionOrder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SupervisionOrderService getService() {
|
||||||
|
return supervisionOrderService;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void delete(SupervisionOrder supervisionOrder) throws Exception {
|
||||||
|
try (Context context = new Context()) {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
context.setDispatcher("noindex");
|
||||||
|
SupervisionOrder attached = context.reloadEntity(supervisionOrder);
|
||||||
|
if (attached != null) {
|
||||||
|
getService().delete(context, attached);
|
||||||
|
}
|
||||||
|
context.complete();
|
||||||
|
indexingService.commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* 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.app.rest.converter;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.model.SupervisionOrderRest;
|
||||||
|
import org.dspace.app.rest.projection.Projection;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.eperson.Group;
|
||||||
|
import org.dspace.supervision.SupervisionOrder;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is responsible to convert SupervisionOrder to its rest model
|
||||||
|
*
|
||||||
|
* @author Mohamed Eskander (mohamed.eskander at 4science dot it)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class SupervisionOrderConverter
|
||||||
|
implements DSpaceConverter<SupervisionOrder, SupervisionOrderRest> {
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
@Autowired
|
||||||
|
private ConverterService converter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SupervisionOrderRest convert(SupervisionOrder modelObject, Projection projection) {
|
||||||
|
|
||||||
|
SupervisionOrderRest rest = new SupervisionOrderRest();
|
||||||
|
Item item = modelObject.getItem();
|
||||||
|
Group group = modelObject.getGroup();
|
||||||
|
|
||||||
|
rest.setId(modelObject.getID());
|
||||||
|
|
||||||
|
if (Objects.nonNull(item)) {
|
||||||
|
rest.setItem(converter.toRest(item, projection));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Objects.nonNull(group)) {
|
||||||
|
rest.setGroup(converter.toRest(group, projection));
|
||||||
|
}
|
||||||
|
|
||||||
|
rest.setProjection(projection);
|
||||||
|
|
||||||
|
return rest;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<SupervisionOrder> getModelClass() {
|
||||||
|
return SupervisionOrder.class;
|
||||||
|
}
|
||||||
|
}
|
@@ -22,13 +22,19 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.app.exception.ResourceAlreadyExistsException;
|
import org.dspace.app.exception.ResourceAlreadyExistsException;
|
||||||
|
import org.dspace.app.exception.ResourceConflictException;
|
||||||
|
import org.dspace.app.rest.converter.ConverterService;
|
||||||
|
import org.dspace.app.rest.model.RestModel;
|
||||||
import org.dspace.app.rest.utils.ContextUtil;
|
import org.dspace.app.rest.utils.ContextUtil;
|
||||||
|
import org.dspace.app.rest.utils.Utils;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.eperson.InvalidReCaptchaException;
|
import org.dspace.eperson.InvalidReCaptchaException;
|
||||||
import org.dspace.orcid.exception.OrcidValidationException;
|
import org.dspace.orcid.exception.OrcidValidationException;
|
||||||
import org.dspace.services.ConfigurationService;
|
import org.dspace.services.ConfigurationService;
|
||||||
import org.springframework.beans.TypeMismatchException;
|
import org.springframework.beans.TypeMismatchException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
import org.springframework.data.repository.support.QueryMethodParameterConversionException;
|
import org.springframework.data.repository.support.QueryMethodParameterConversionException;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
@@ -60,6 +66,13 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExcep
|
|||||||
public class DSpaceApiExceptionControllerAdvice extends ResponseEntityExceptionHandler {
|
public class DSpaceApiExceptionControllerAdvice extends ResponseEntityExceptionHandler {
|
||||||
private static final Logger log = LogManager.getLogger();
|
private static final Logger log = LogManager.getLogger();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Lazy
|
||||||
|
private ConverterService converterService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Utils utils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default collection of HTTP error codes to log as ERROR with full stack trace.
|
* Default collection of HTTP error codes to log as ERROR with full stack trace.
|
||||||
*/
|
*/
|
||||||
@@ -235,6 +248,12 @@ public class DSpaceApiExceptionControllerAdvice extends ResponseEntityExceptionH
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(ResourceConflictException.class)
|
||||||
|
protected ResponseEntity<? extends RestModel> resourceConflictException(ResourceConflictException ex) {
|
||||||
|
RestModel resource = converterService.toRest(ex.getResource(), utils.obtainProjection());
|
||||||
|
return new ResponseEntity<RestModel>(resource, HttpStatus.CONFLICT);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send the error to the response.
|
* Send the error to the response.
|
||||||
* 5xx errors will be logged as ERROR with a full stack trace. 4xx errors
|
* 5xx errors will be logged as ERROR with a full stack trace. 4xx errors
|
||||||
|
@@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import org.dspace.app.rest.RestResourceController;
|
||||||
|
import org.dspace.supervision.SupervisionOrder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The REST Resource of {@link SupervisionOrder}.
|
||||||
|
*
|
||||||
|
* @author Mohamed Eskander (mohamed.eskander at 4science.it)
|
||||||
|
*/
|
||||||
|
public class SupervisionOrderRest extends BaseObjectRest<Integer> {
|
||||||
|
|
||||||
|
public static final String NAME = "supervisionorder";
|
||||||
|
public static final String CATEGORY = RestAddressableModel.CORE;
|
||||||
|
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private ItemRest item;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private GroupRest group;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemRest getItem() {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItem(ItemRest item) {
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GroupRest getGroup() {
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGroup(GroupRest group) {
|
||||||
|
this.group = group;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return CATEGORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class getController() {
|
||||||
|
return RestResourceController.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
}
|
@@ -14,10 +14,18 @@ import org.dspace.app.rest.RestResourceController;
|
|||||||
*
|
*
|
||||||
* @author Andrea Bollini (andrea.bollini at 4science.it)
|
* @author Andrea Bollini (andrea.bollini at 4science.it)
|
||||||
*/
|
*/
|
||||||
|
@LinksRest(links = {
|
||||||
|
@LinkRest(
|
||||||
|
name = WorkspaceItemRest.SUPERVISION_ORDERS,
|
||||||
|
method = "getSupervisionOrders"
|
||||||
|
)
|
||||||
|
})
|
||||||
public class WorkspaceItemRest extends AInprogressSubmissionRest {
|
public class WorkspaceItemRest extends AInprogressSubmissionRest {
|
||||||
public static final String NAME = "workspaceitem";
|
public static final String NAME = "workspaceitem";
|
||||||
public static final String CATEGORY = RestAddressableModel.SUBMISSION;
|
public static final String CATEGORY = RestAddressableModel.SUBMISSION;
|
||||||
|
|
||||||
|
public static final String SUPERVISION_ORDERS = "supervisionOrders";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCategory() {
|
public String getCategory() {
|
||||||
return CATEGORY;
|
return CATEGORY;
|
||||||
|
@@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* 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.app.rest.model.hateoas;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.model.SupervisionOrderRest;
|
||||||
|
import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource;
|
||||||
|
import org.dspace.app.rest.utils.Utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SupervisionOrder Rest HAL Resource. The HAL Resource wraps the REST Resource
|
||||||
|
* adding support for the links and embedded resources
|
||||||
|
*
|
||||||
|
* @author Mohamed Eskander (mohamed.eskander at 4science dot it)
|
||||||
|
*/
|
||||||
|
@RelNameDSpaceResource(SupervisionOrderRest.NAME)
|
||||||
|
public class SupervisionOrderResource extends DSpaceResource<SupervisionOrderRest> {
|
||||||
|
public SupervisionOrderResource(SupervisionOrderRest data, Utils utils) {
|
||||||
|
super(data, utils);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,219 @@
|
|||||||
|
/**
|
||||||
|
* 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.app.rest.repository;
|
||||||
|
|
||||||
|
import static org.dspace.authorize.ResourcePolicy.TYPE_SUBMISSION;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.app.exception.ResourceConflictException;
|
||||||
|
import org.dspace.app.rest.Parameter;
|
||||||
|
import org.dspace.app.rest.SearchRestMethod;
|
||||||
|
import org.dspace.app.rest.converter.ConverterService;
|
||||||
|
import org.dspace.app.rest.exception.MissingParameterException;
|
||||||
|
import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
|
||||||
|
import org.dspace.app.rest.exception.UnprocessableEntityException;
|
||||||
|
import org.dspace.app.rest.model.SupervisionOrderRest;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
|
import org.dspace.content.Bitstream;
|
||||||
|
import org.dspace.content.Bundle;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.service.ItemService;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.eperson.Group;
|
||||||
|
import org.dspace.eperson.service.GroupService;
|
||||||
|
import org.dspace.supervision.SupervisionOrder;
|
||||||
|
import org.dspace.supervision.enumeration.SupervisionOrderType;
|
||||||
|
import org.dspace.supervision.service.SupervisionOrderService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the repository responsible to manage SupervisionOrderRest object
|
||||||
|
*
|
||||||
|
* @author Mohamed Eskander (mohamed.eskander at 4science dot it)
|
||||||
|
*/
|
||||||
|
@Component(SupervisionOrderRest.CATEGORY + "." + SupervisionOrderRest.NAME)
|
||||||
|
public class SupervisionOrderRestRepository extends DSpaceRestRepository<SupervisionOrderRest, Integer> {
|
||||||
|
|
||||||
|
private static final Logger log =
|
||||||
|
org.apache.logging.log4j.LogManager.getLogger(SupervisionOrderRestRepository.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SupervisionOrderService supervisionOrderService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConverterService converterService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ItemService itemService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private GroupService groupService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuthorizeService authorizeService;
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('ADMIN')")
|
||||||
|
@Override
|
||||||
|
public SupervisionOrderRest findOne(Context context, Integer id) {
|
||||||
|
try {
|
||||||
|
SupervisionOrder supervisionOrder = supervisionOrderService.find(context, id);
|
||||||
|
if (Objects.isNull(supervisionOrder)) {
|
||||||
|
throw new ResourceNotFoundException("Couldn't find supervision order for id: " + id);
|
||||||
|
}
|
||||||
|
return converterService.toRest(supervisionOrder, utils.obtainProjection());
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Something went wrong with getting supervision order with id:" + id, e);
|
||||||
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('ADMIN')")
|
||||||
|
@Override
|
||||||
|
public Page<SupervisionOrderRest> findAll(Context context, Pageable pageable) {
|
||||||
|
try {
|
||||||
|
List<SupervisionOrder> supervisionOrders = supervisionOrderService.findAll(context);
|
||||||
|
return converterService.toRestPage(supervisionOrders, pageable, utils.obtainProjection());
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Something went wrong with getting supervision orders", e);
|
||||||
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('ADMIN')")
|
||||||
|
@Override
|
||||||
|
public SupervisionOrderRest createAndReturn(Context context) throws AuthorizeException, SQLException {
|
||||||
|
HttpServletRequest req = getRequestService().getCurrentRequest().getHttpServletRequest();
|
||||||
|
SupervisionOrder supervisionOrder;
|
||||||
|
String itemId = req.getParameter("uuid");
|
||||||
|
String groupId = req.getParameter("group");
|
||||||
|
String type = req.getParameter("type");
|
||||||
|
|
||||||
|
validateParameters(itemId, groupId, type);
|
||||||
|
|
||||||
|
Item item = itemService.find(context, UUID.fromString(itemId));
|
||||||
|
if (item == null) {
|
||||||
|
throw new UnprocessableEntityException("Item with uuid: " + itemId + " not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
Group group = groupService.find(context, UUID.fromString(groupId));
|
||||||
|
if (group == null) {
|
||||||
|
throw new UnprocessableEntityException("Group with uuid: " + groupId + " not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
supervisionOrder = supervisionOrderService.findByItemAndGroup(context, item, group);
|
||||||
|
if (Objects.nonNull(supervisionOrder)) {
|
||||||
|
throw new ResourceConflictException(
|
||||||
|
"There is a conflict supervision order with itemId <" + itemId + "> and groupId <" + groupId + ">",
|
||||||
|
supervisionOrder
|
||||||
|
);
|
||||||
|
}
|
||||||
|
supervisionOrder = supervisionOrderService.create(context, item, group);
|
||||||
|
addGroupPoliciesToItem(context, item, group, type);
|
||||||
|
return converterService.toRest(supervisionOrder, utils.obtainProjection());
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('ADMIN')")
|
||||||
|
@Override
|
||||||
|
protected void delete(Context context, Integer id)
|
||||||
|
throws AuthorizeException, RepositoryMethodNotImplementedException {
|
||||||
|
|
||||||
|
try {
|
||||||
|
SupervisionOrder supervisionOrder = supervisionOrderService.find(context, id);
|
||||||
|
if (Objects.isNull(supervisionOrder)) {
|
||||||
|
throw new ResourceNotFoundException(
|
||||||
|
SupervisionOrderRest.CATEGORY + "." + SupervisionOrderRest.NAME +
|
||||||
|
" with id: " + id + " not found"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
supervisionOrderService.delete(context, supervisionOrder);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('ADMIN')")
|
||||||
|
@SearchRestMethod(name = "byItem")
|
||||||
|
public Page<SupervisionOrderRest> findByItem(@Parameter(value = "uuid", required = true) String itemId,
|
||||||
|
Pageable pageable) {
|
||||||
|
try {
|
||||||
|
Context context = obtainContext();
|
||||||
|
Item item = itemService.find(context, UUID.fromString(itemId));
|
||||||
|
if (Objects.isNull(item)) {
|
||||||
|
throw new ResourceNotFoundException("no item is found for the uuid < " + itemId + " >");
|
||||||
|
}
|
||||||
|
return converterService.toRestPage(supervisionOrderService.findByItem(context, item),
|
||||||
|
pageable, utils.obtainProjection());
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<SupervisionOrderRest> getDomainClass() {
|
||||||
|
return SupervisionOrderRest.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateParameters(String itemId, String groupId, String type) {
|
||||||
|
if (Objects.isNull(itemId)) {
|
||||||
|
throw new MissingParameterException("Missing item (uuid) parameter");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Objects.isNull(groupId)) {
|
||||||
|
throw new MissingParameterException("Missing group (uuid) parameter");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Objects.isNull(type)) {
|
||||||
|
throw new MissingParameterException("Missing type parameter");
|
||||||
|
} else if (!type.equals(SupervisionOrderType.EDITOR.toString()) &&
|
||||||
|
!type.equals(SupervisionOrderType.OBSERVER.toString())) {
|
||||||
|
throw new IllegalArgumentException("wrong type value, Type must be (EDITOR or OBSERVER)");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addGroupPoliciesToItem(Context context, Item item, Group group, String type)
|
||||||
|
throws SQLException, AuthorizeException {
|
||||||
|
|
||||||
|
if (StringUtils.isNotEmpty(type)) {
|
||||||
|
if (type.equals("EDITOR")) {
|
||||||
|
addGroupPolicyToItem(context, item, Constants.READ, group, TYPE_SUBMISSION);
|
||||||
|
addGroupPolicyToItem(context, item, Constants.WRITE, group, TYPE_SUBMISSION);
|
||||||
|
} else if (type.equals("OBSERVER")) {
|
||||||
|
addGroupPolicyToItem(context, item, Constants.READ, group, TYPE_SUBMISSION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addGroupPolicyToItem(Context context, Item item, int action, Group group, String policyType)
|
||||||
|
throws AuthorizeException, SQLException {
|
||||||
|
authorizeService.addPolicy(context, item, action, group, policyType);
|
||||||
|
List<Bundle> bundles = item.getBundles();
|
||||||
|
for (Bundle bundle : bundles) {
|
||||||
|
authorizeService.addPolicy(context, bundle, action, group, policyType);
|
||||||
|
List<Bitstream> bits = bundle.getBitstreams();
|
||||||
|
for (Bitstream bitstream : bits) {
|
||||||
|
authorizeService.addPolicy(context, bitstream, action, group, policyType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* 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.app.rest.repository;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.model.SupervisionOrderRest;
|
||||||
|
import org.dspace.app.rest.model.WorkspaceItemRest;
|
||||||
|
import org.dspace.app.rest.projection.Projection;
|
||||||
|
import org.dspace.content.WorkspaceItem;
|
||||||
|
import org.dspace.content.service.WorkspaceItemService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.supervision.service.SupervisionOrderService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link repository for the supervision orders of an WorkspaceItem
|
||||||
|
*
|
||||||
|
* @author Mohamed Eskander (mohamed.eskander at 4science dot it)
|
||||||
|
*/
|
||||||
|
@Component(WorkspaceItemRest.CATEGORY + "." + WorkspaceItemRest.NAME + "." + WorkspaceItemRest.SUPERVISION_ORDERS)
|
||||||
|
public class WorkspaceItemSupervisionOrdersLinkRepository
|
||||||
|
extends AbstractDSpaceRestRepository implements LinkRestRepository {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
WorkspaceItemService workspaceItemService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
SupervisionOrderService supervisionOrderService;
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('ADMIN')")
|
||||||
|
public Page<SupervisionOrderRest> getSupervisionOrders(@Nullable HttpServletRequest request,
|
||||||
|
Integer id,
|
||||||
|
@Nullable Pageable optionalPageable,
|
||||||
|
Projection projection) {
|
||||||
|
try {
|
||||||
|
Context context = obtainContext();
|
||||||
|
WorkspaceItem workspaceItem = workspaceItemService.find(context, id);
|
||||||
|
if (workspaceItem == null) {
|
||||||
|
throw new ResourceNotFoundException("No such workspace item: " + id);
|
||||||
|
}
|
||||||
|
return converter.toRestPage(
|
||||||
|
supervisionOrderService.findByItem(context, workspaceItem.getItem()),
|
||||||
|
optionalPageable, projection);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -20,6 +20,7 @@ import org.dspace.eperson.EPerson;
|
|||||||
import org.dspace.eperson.service.EPersonService;
|
import org.dspace.eperson.service.EPersonService;
|
||||||
import org.dspace.services.RequestService;
|
import org.dspace.services.RequestService;
|
||||||
import org.dspace.services.model.Request;
|
import org.dspace.services.model.Request;
|
||||||
|
import org.dspace.supervision.service.SupervisionOrderService;
|
||||||
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
|
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
|
||||||
import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService;
|
import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService;
|
||||||
import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService;
|
import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService;
|
||||||
@@ -56,6 +57,9 @@ public class WorkflowRestPermissionEvaluatorPlugin extends RestObjectPermissionE
|
|||||||
@Autowired
|
@Autowired
|
||||||
private EPersonService ePersonService;
|
private EPersonService ePersonService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SupervisionOrderService supervisionOrderService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId,
|
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId,
|
||||||
String targetType, DSpaceRestPermission permission) {
|
String targetType, DSpaceRestPermission permission) {
|
||||||
@@ -89,6 +93,11 @@ public class WorkflowRestPermissionEvaluatorPlugin extends RestObjectPermissionE
|
|||||||
if (claimedTaskService.findByWorkflowIdAndEPerson(context, workflowItem, ePerson) != null) {
|
if (claimedTaskService.findByWorkflowIdAndEPerson(context, workflowItem, ePerson) != null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (supervisionOrderService.isSupervisor(context, ePerson, workflowItem.getItem())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} catch (SQLException | AuthorizeException | IOException e) {
|
} catch (SQLException | AuthorizeException | IOException e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,7 @@ import org.dspace.core.Context;
|
|||||||
import org.dspace.eperson.EPerson;
|
import org.dspace.eperson.EPerson;
|
||||||
import org.dspace.services.RequestService;
|
import org.dspace.services.RequestService;
|
||||||
import org.dspace.services.model.Request;
|
import org.dspace.services.model.Request;
|
||||||
|
import org.dspace.supervision.service.SupervisionOrderService;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -41,6 +42,9 @@ public class WorkspaceItemRestPermissionEvaluatorPlugin extends RestObjectPermis
|
|||||||
@Autowired
|
@Autowired
|
||||||
WorkspaceItemService wis;
|
WorkspaceItemService wis;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SupervisionOrderService supervisionOrderService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
|
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
|
||||||
DSpaceRestPermission permission) {
|
DSpaceRestPermission permission) {
|
||||||
@@ -82,6 +86,13 @@ public class WorkspaceItemRestPermissionEvaluatorPlugin extends RestObjectPermis
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (witem.getItem() != null) {
|
||||||
|
if (supervisionOrderService.isSupervisor(context, ePerson, witem.getItem())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
@@ -64,6 +64,7 @@ import org.dspace.app.rest.model.PropertyRest;
|
|||||||
import org.dspace.app.rest.model.ResourcePolicyRest;
|
import org.dspace.app.rest.model.ResourcePolicyRest;
|
||||||
import org.dspace.app.rest.model.RestAddressableModel;
|
import org.dspace.app.rest.model.RestAddressableModel;
|
||||||
import org.dspace.app.rest.model.RestModel;
|
import org.dspace.app.rest.model.RestModel;
|
||||||
|
import org.dspace.app.rest.model.SupervisionOrderRest;
|
||||||
import org.dspace.app.rest.model.VersionHistoryRest;
|
import org.dspace.app.rest.model.VersionHistoryRest;
|
||||||
import org.dspace.app.rest.model.VocabularyRest;
|
import org.dspace.app.rest.model.VocabularyRest;
|
||||||
import org.dspace.app.rest.model.hateoas.EmbeddedPage;
|
import org.dspace.app.rest.model.hateoas.EmbeddedPage;
|
||||||
@@ -296,6 +297,9 @@ public class Utils {
|
|||||||
if (StringUtils.equals(modelPlural, "orcidhistories")) {
|
if (StringUtils.equals(modelPlural, "orcidhistories")) {
|
||||||
return OrcidHistoryRest.NAME;
|
return OrcidHistoryRest.NAME;
|
||||||
}
|
}
|
||||||
|
if (StringUtils.equals(modelPlural, "supervisionorders")) {
|
||||||
|
return SupervisionOrderRest.NAME;
|
||||||
|
}
|
||||||
return modelPlural.replaceAll("s$", "");
|
return modelPlural.replaceAll("s$", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,11 +9,13 @@ package org.dspace.app.rest;
|
|||||||
|
|
||||||
import static com.google.common.net.UrlEscapers.urlPathSegmentEscaper;
|
import static com.google.common.net.UrlEscapers.urlPathSegmentEscaper;
|
||||||
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
||||||
|
import static org.dspace.app.rest.matcher.FacetValueMatcher.entrySupervisedBy;
|
||||||
import static org.hamcrest.Matchers.allOf;
|
import static org.hamcrest.Matchers.allOf;
|
||||||
import static org.hamcrest.Matchers.contains;
|
import static org.hamcrest.Matchers.contains;
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.emptyOrNullString;
|
import static org.hamcrest.Matchers.emptyOrNullString;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.hasItem;
|
import static org.hamcrest.Matchers.hasItem;
|
||||||
import static org.hamcrest.Matchers.hasSize;
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
@@ -48,6 +50,7 @@ import org.dspace.builder.EPersonBuilder;
|
|||||||
import org.dspace.builder.GroupBuilder;
|
import org.dspace.builder.GroupBuilder;
|
||||||
import org.dspace.builder.ItemBuilder;
|
import org.dspace.builder.ItemBuilder;
|
||||||
import org.dspace.builder.PoolTaskBuilder;
|
import org.dspace.builder.PoolTaskBuilder;
|
||||||
|
import org.dspace.builder.SupervisionOrderBuilder;
|
||||||
import org.dspace.builder.WorkflowItemBuilder;
|
import org.dspace.builder.WorkflowItemBuilder;
|
||||||
import org.dspace.builder.WorkspaceItemBuilder;
|
import org.dspace.builder.WorkspaceItemBuilder;
|
||||||
import org.dspace.content.Bitstream;
|
import org.dspace.content.Bitstream;
|
||||||
@@ -63,6 +66,7 @@ import org.dspace.eperson.EPerson;
|
|||||||
import org.dspace.eperson.Group;
|
import org.dspace.eperson.Group;
|
||||||
import org.dspace.services.ConfigurationService;
|
import org.dspace.services.ConfigurationService;
|
||||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
|
import org.dspace.supervision.SupervisionOrder;
|
||||||
import org.dspace.xmlworkflow.storedcomponents.ClaimedTask;
|
import org.dspace.xmlworkflow.storedcomponents.ClaimedTask;
|
||||||
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
|
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
@@ -5987,4 +5991,491 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest
|
|||||||
.andExpect(jsonPath("$._embedded.values").value(Matchers.hasSize(1)));
|
.andExpect(jsonPath("$._embedded.values").value(Matchers.hasSize(1)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void discoverFacetsSupervisedByTest() throws Exception {
|
||||||
|
//We turn off the authorization system in order to create the structure defined below
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
//** GIVEN **
|
||||||
|
//1. A community-collection structure with one parent community and one collection
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection collection =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//2. Two workspace items
|
||||||
|
WorkspaceItem wsItem1 =
|
||||||
|
WorkspaceItemBuilder.createWorkspaceItem(context, collection)
|
||||||
|
.withTitle("Workspace Item 1")
|
||||||
|
.withIssueDate("2010-07-23")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
WorkspaceItem wsItem2 =
|
||||||
|
WorkspaceItemBuilder.createWorkspaceItem(context, collection)
|
||||||
|
.withTitle("Workspace Item 2")
|
||||||
|
.withIssueDate("2010-11-03")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//3. Two groups
|
||||||
|
Group groupA =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group A")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group groupB =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group B")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//4. Four supervision orders
|
||||||
|
SupervisionOrder supervisionOrderOne =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, wsItem1.getItem(), groupA).build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrderTwo =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, wsItem1.getItem(), groupB).build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrderThree =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, wsItem2.getItem(), groupA).build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrderFour =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, wsItem2.getItem(), groupB).build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
//** WHEN **
|
||||||
|
//The Admin user browses this endpoint to find the supervisedBy results by the facet
|
||||||
|
getClient(getAuthToken(admin.getEmail(), password)).perform(get("/api/discover/facets/supervisedBy")
|
||||||
|
.param("configuration", "supervision"))
|
||||||
|
//** THEN **
|
||||||
|
//The status has to be 200 OK
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
//The type has to be 'discover'
|
||||||
|
.andExpect(jsonPath("$.type", is("discover")))
|
||||||
|
//The name has to be 'supervisedBy' as that's the facet that we've called
|
||||||
|
.andExpect(jsonPath("$.name", is("supervisedBy")))
|
||||||
|
//The facetType has to be `authority` because that's the default configuration for this facet
|
||||||
|
.andExpect(jsonPath("$.facetType", equalTo("authority")))
|
||||||
|
//There always needs to be a self link available
|
||||||
|
.andExpect(jsonPath("$._links.self.href",
|
||||||
|
containsString("api/discover/facets/supervisedBy?configuration=supervision")))
|
||||||
|
//This is how the page object must look like because it's the default with size 20
|
||||||
|
.andExpect(jsonPath("$.page",
|
||||||
|
is(PageMatcher.pageEntry(0, 20))))
|
||||||
|
//The supervisedBy values need to be as specified below
|
||||||
|
.andExpect(jsonPath("$._embedded.values", containsInAnyOrder(
|
||||||
|
entrySupervisedBy(groupA.getName(), groupA.getID().toString(), 2),
|
||||||
|
entrySupervisedBy(groupB.getName(), groupB.getID().toString(), 2)
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void discoverFacetsSupervisedByWithPrefixTest() throws Exception {
|
||||||
|
//We turn off the authorization system in order to create the structure defined below
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
//** GIVEN **
|
||||||
|
//1. A community-collection structure with one parent community and one collection
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection collection =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//2. Two workspace items
|
||||||
|
WorkspaceItem wsItem1 =
|
||||||
|
WorkspaceItemBuilder.createWorkspaceItem(context, collection)
|
||||||
|
.withTitle("Workspace Item 1")
|
||||||
|
.withIssueDate("2010-07-23")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
WorkspaceItem wsItem2 =
|
||||||
|
WorkspaceItemBuilder.createWorkspaceItem(context, collection)
|
||||||
|
.withTitle("Workspace Item 2")
|
||||||
|
.withIssueDate("2010-11-03")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group groupA =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group A")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group groupB =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group B")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrderOneA =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, wsItem1.getItem(), groupA).build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrderOneB =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, wsItem1.getItem(), groupB).build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrderTwoA =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, wsItem2.getItem(), groupA).build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrderTwoB =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, wsItem2.getItem(), groupB).build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
//** WHEN **
|
||||||
|
//The Admin user browses this endpoint to find the supervisedBy results by the facet
|
||||||
|
getClient(getAuthToken(admin.getEmail(), password)).perform(get("/api/discover/facets/supervisedBy")
|
||||||
|
.param("configuration", "supervision")
|
||||||
|
.param("prefix", "group B"))
|
||||||
|
//** THEN **
|
||||||
|
//The status has to be 200 OK
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
//The type has to be 'discover'
|
||||||
|
.andExpect(jsonPath("$.type", is("discover")))
|
||||||
|
//The name has to be 'supervisedBy' as that's the facet that we've called
|
||||||
|
.andExpect(jsonPath("$.name", is("supervisedBy")))
|
||||||
|
//The facetType has to be `authority` because that's the default configuration for this facet
|
||||||
|
.andExpect(jsonPath("$.facetType", equalTo("authority")))
|
||||||
|
//There always needs to be a self link available
|
||||||
|
.andExpect(jsonPath("$._links.self.href",
|
||||||
|
containsString("api/discover/facets/supervisedBy?prefix=group%2520B&configuration=supervision")))
|
||||||
|
//This is how the page object must look like because it's the default with size 20
|
||||||
|
.andExpect(jsonPath("$.page",
|
||||||
|
is(PageMatcher.pageEntry(0, 20))))
|
||||||
|
//The supervisedBy values need to be as specified below
|
||||||
|
.andExpect(jsonPath("$._embedded.values", containsInAnyOrder(
|
||||||
|
entrySupervisedBy(groupB.getName(), groupB.getID().toString(), 2)
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
/**
|
||||||
|
* This test is intent to verify that tasks are only visible to the admin users
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void discoverSearchObjectsSupervisionConfigurationTest() throws Exception {
|
||||||
|
|
||||||
|
//We turn off the authorization system in order to create the structure defined below
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
//** GIVEN **
|
||||||
|
// 1. Two reviewers and two users and two groups
|
||||||
|
EPerson reviewer1 =
|
||||||
|
EPersonBuilder.createEPerson(context)
|
||||||
|
.withEmail("reviewer1@example.com")
|
||||||
|
.withPassword(password)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
EPerson reviewer2 =
|
||||||
|
EPersonBuilder.createEPerson(context)
|
||||||
|
.withEmail("reviewer2@example.com")
|
||||||
|
.withPassword(password)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
EPerson userA =
|
||||||
|
EPersonBuilder.createEPerson(context)
|
||||||
|
.withCanLogin(true)
|
||||||
|
.withEmail("userA@test.com")
|
||||||
|
.withPassword(password)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
EPerson userB =
|
||||||
|
EPersonBuilder.createEPerson(context)
|
||||||
|
.withCanLogin(true)
|
||||||
|
.withEmail("userB@test.com")
|
||||||
|
.withPassword(password)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group groupA =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group A")
|
||||||
|
.addMember(userA)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group groupB =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group B")
|
||||||
|
.addMember(userB)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 2. A community-collection structure with one parent community with sub-community and two collections.
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
|
||||||
|
.withName("Sub Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 = CollectionBuilder.createCollection(context, child1)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the second collection has two workflow steps active
|
||||||
|
Collection col2 = CollectionBuilder.createCollection(context, child1)
|
||||||
|
.withName("Collection 2")
|
||||||
|
.withWorkflowGroup(1, admin, reviewer1)
|
||||||
|
.withWorkflowGroup(2, reviewer2)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 2. Three public items that are readable by Anonymous with different subjects
|
||||||
|
Item publicItem1 = ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("Test")
|
||||||
|
.withIssueDate("2010-10-17")
|
||||||
|
.withAuthor("Smith, Donald")
|
||||||
|
.withAuthor("Testing, Works")
|
||||||
|
.withSubject("ExtraEntry")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item publicItem2 = ItemBuilder.createItem(context, col2)
|
||||||
|
.withTitle("Test 2")
|
||||||
|
.withIssueDate("1990-02-13")
|
||||||
|
.withAuthor("Smith, Maria")
|
||||||
|
.withAuthor("Doe, Jane")
|
||||||
|
.withAuthor("Testing, Works")
|
||||||
|
.withSubject("TestingForMore")
|
||||||
|
.withSubject("ExtraEntry")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item publicItem3 = ItemBuilder.createItem(context, col2)
|
||||||
|
.withTitle("Public item 2")
|
||||||
|
.withIssueDate("2010-02-13")
|
||||||
|
.withAuthor("Smith, Maria")
|
||||||
|
.withAuthor("Doe, Jane")
|
||||||
|
.withAuthor("test,test")
|
||||||
|
.withAuthor("test2, test2")
|
||||||
|
.withAuthor("Maybe, Maybe")
|
||||||
|
.withSubject("AnotherTest")
|
||||||
|
.withSubject("TestingForMore")
|
||||||
|
.withSubject("ExtraEntry")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//3. three inprogress submission from a normal user (2 ws, 1 wf that will produce also a pooltask)
|
||||||
|
context.setCurrentUser(eperson);
|
||||||
|
WorkspaceItem wsItem1 = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
|
||||||
|
.withTitle("Workspace Item 1")
|
||||||
|
.withIssueDate("2010-07-23")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
WorkspaceItem wsItem2 = WorkspaceItemBuilder.createWorkspaceItem(context, col2)
|
||||||
|
.withTitle("Workspace Item 2")
|
||||||
|
.withIssueDate("2010-11-03")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
XmlWorkflowItem wfItem1 = WorkflowItemBuilder.createWorkflowItem(context, col2)
|
||||||
|
.withTitle("Workflow Item 1")
|
||||||
|
.withIssueDate("2010-11-03")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// create Four supervision orders for above items
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, wsItem1.getItem(), groupA).build();
|
||||||
|
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, wsItem2.getItem(), groupA).build();
|
||||||
|
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, wfItem1.getItem(), groupA).build();
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, wfItem1.getItem(), groupB).build();
|
||||||
|
|
||||||
|
// 4. a claimed task from the administrator
|
||||||
|
ClaimedTask cTask = ClaimedTaskBuilder.createClaimedTask(context, col2, admin).withTitle("Claimed Item")
|
||||||
|
.withIssueDate("2010-11-03")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 5. other inprogress submissions made by the administrator
|
||||||
|
context.setCurrentUser(admin);
|
||||||
|
WorkspaceItem wsItem1Admin = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
|
||||||
|
.withIssueDate("2010-07-23")
|
||||||
|
.withTitle("Admin Workspace Item 1").build();
|
||||||
|
|
||||||
|
WorkspaceItem wsItem2Admin = WorkspaceItemBuilder.createWorkspaceItem(context, col2)
|
||||||
|
.withIssueDate("2010-11-03")
|
||||||
|
.withTitle("Admin Workspace Item 2").build();
|
||||||
|
|
||||||
|
XmlWorkflowItem wfItem1Admin = WorkflowItemBuilder.createWorkflowItem(context, col2)
|
||||||
|
.withIssueDate("2010-11-03")
|
||||||
|
.withTitle("Admin Workflow Item 1").build();
|
||||||
|
|
||||||
|
// create Four supervision orders for above items
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, wsItem1Admin.getItem(), groupA).build();
|
||||||
|
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, wsItem2Admin.getItem(), groupA).build();
|
||||||
|
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, wfItem1Admin.getItem(), groupA).build();
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, wfItem1Admin.getItem(), groupB).build();
|
||||||
|
|
||||||
|
// 6. a pool taks in the second step of the workflow
|
||||||
|
ClaimedTask cTask2 = ClaimedTaskBuilder.createClaimedTask(context, col2, admin).withTitle("Pool Step2 Item")
|
||||||
|
.withIssueDate("2010-11-04")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
String epersonToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
String reviewer1Token = getAuthToken(reviewer1.getEmail(), password);
|
||||||
|
String reviewer2Token = getAuthToken(reviewer2.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(adminToken).perform(post("/api/workflow/claimedtasks/" + cTask2.getID())
|
||||||
|
.param("submit_approve", "true")
|
||||||
|
.contentType(MediaType.APPLICATION_FORM_URLENCODED))
|
||||||
|
.andExpect(status().isNoContent());
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
// summary of the structure, we have:
|
||||||
|
// a simple collection
|
||||||
|
// a second collection with 2 workflow steps that have 1 reviewer each (reviewer1 and reviewer2)
|
||||||
|
// 3 public items
|
||||||
|
// 2 workspace items submitted by a regular submitter
|
||||||
|
// 2 workspace items submitted by the admin
|
||||||
|
// 4 workflow items:
|
||||||
|
// 1 pool task in step 1, submitted by the same regular submitter
|
||||||
|
// 1 pool task in step 1, submitted by the admin
|
||||||
|
// 1 claimed task in the first workflow step from the repository admin
|
||||||
|
// 1 pool task task in step 2, from the repository admin
|
||||||
|
// (This one is created by creating a claimed task for step 1 and approving it)
|
||||||
|
|
||||||
|
//** WHEN **
|
||||||
|
// the submitter should not see anything in the workflow configuration
|
||||||
|
getClient(epersonToken)
|
||||||
|
.perform(get("/api/discover/search/objects").param("configuration", "supervision"))
|
||||||
|
//** THEN **
|
||||||
|
//The status has to be 200 OK
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
//The type has to be 'discover'
|
||||||
|
.andExpect(jsonPath("$.type", is("discover")))
|
||||||
|
//There needs to be a page object that shows the total pages and total elements as well as the
|
||||||
|
// size and the current page (number)
|
||||||
|
.andExpect(jsonPath("$._embedded.searchResult.page", is(
|
||||||
|
PageMatcher.pageEntryWithTotalPagesAndElements(0, 20, 0, 0)
|
||||||
|
)))
|
||||||
|
//There always needs to be a self link
|
||||||
|
.andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects")));
|
||||||
|
|
||||||
|
// reviewer1 should not see pool items, as it is not an administrator
|
||||||
|
getClient(reviewer1Token)
|
||||||
|
.perform(get("/api/discover/search/objects").param("configuration", "supervision"))
|
||||||
|
//** THEN **
|
||||||
|
//The status has to be 200 OK
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
//The type has to be 'discover'
|
||||||
|
.andExpect(jsonPath("$.type", is("discover")))
|
||||||
|
//There needs to be a page object that shows the total pages and total elements as well as the
|
||||||
|
// size and the current page (number)
|
||||||
|
.andExpect(jsonPath("$._embedded.searchResult.page", is(
|
||||||
|
PageMatcher.pageEntryWithTotalPagesAndElements(0, 20, 0, 0)
|
||||||
|
)))
|
||||||
|
//There always needs to be a self link
|
||||||
|
.andExpect(jsonPath("$._links.self.href",
|
||||||
|
containsString("/api/discover/search/objects")));
|
||||||
|
|
||||||
|
// admin should see seven pool items and a claimed task
|
||||||
|
// Three pool items from the submitter and Five from the admin
|
||||||
|
getClient(adminToken)
|
||||||
|
.perform(get("/api/discover/search/objects").param("configuration", "supervision"))
|
||||||
|
//** THEN **
|
||||||
|
//The status has to be 200 OK
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
//The type has to be 'discover'
|
||||||
|
.andExpect(jsonPath("$.type", is("discover")))
|
||||||
|
//There needs to be a page object that shows the total pages and total elements as well as the
|
||||||
|
// size and the current page (number)
|
||||||
|
.andExpect(jsonPath("$._embedded.searchResult.page", is(
|
||||||
|
PageMatcher.pageEntryWithTotalPagesAndElements(0, 20, 1, 8)
|
||||||
|
)))
|
||||||
|
// These search results have to be shown in the embedded.objects section:
|
||||||
|
// three workflow items and one claimed task.
|
||||||
|
// For step 1 one submitted by the user and one submitted by the admin and one for step 2.
|
||||||
|
//Seeing as everything fits onto one page, they have to all be present
|
||||||
|
.andExpect(jsonPath("$._embedded.searchResult._embedded.objects", Matchers.containsInAnyOrder(
|
||||||
|
Matchers.allOf(
|
||||||
|
SearchResultMatcher.match("workflow", "workflowitem", "workflowitems"),
|
||||||
|
JsonPathMatchers.hasJsonPath("$._embedded.indexableObject",
|
||||||
|
is(WorkflowItemMatcher.matchItemWithTitleAndDateIssued(
|
||||||
|
null, "Workflow Item 1", "2010-11-03")))
|
||||||
|
),
|
||||||
|
Matchers.allOf(
|
||||||
|
SearchResultMatcher.match("workflow", "workflowitem", "workflowitems"),
|
||||||
|
JsonPathMatchers.hasJsonPath("$._embedded.indexableObject",
|
||||||
|
is(WorkflowItemMatcher.matchItemWithTitleAndDateIssued(
|
||||||
|
null, "Admin Workflow Item 1", "2010-11-03")))
|
||||||
|
),
|
||||||
|
Matchers.allOf(
|
||||||
|
SearchResultMatcher.match("workflow", "workflowitem", "workflowitems"),
|
||||||
|
JsonPathMatchers.hasJsonPath("$._embedded.indexableObject",
|
||||||
|
is(WorkflowItemMatcher.matchItemWithTitleAndDateIssued(
|
||||||
|
null, "Pool Step2 Item", "2010-11-04")))
|
||||||
|
),
|
||||||
|
Matchers.allOf(
|
||||||
|
SearchResultMatcher.match("workflow", "workflowitem", "workflowitems"),
|
||||||
|
JsonPathMatchers.hasJsonPath("$._embedded.indexableObject",
|
||||||
|
is(WorkflowItemMatcher.matchItemWithTitleAndDateIssued(
|
||||||
|
null, "Claimed Item", "2010-11-03")))
|
||||||
|
),
|
||||||
|
Matchers.allOf(
|
||||||
|
SearchResultMatcher.match("submission", "workspaceitem", "workspaceitems"),
|
||||||
|
JsonPathMatchers.hasJsonPath("$._embedded.indexableObject",
|
||||||
|
is(WorkspaceItemMatcher.matchItemWithTitleAndDateIssued(wsItem1,
|
||||||
|
"Workspace Item 1", "2010-07-23")))
|
||||||
|
),
|
||||||
|
Matchers.allOf(
|
||||||
|
SearchResultMatcher.match("submission", "workspaceitem", "workspaceitems"),
|
||||||
|
JsonPathMatchers.hasJsonPath("$._embedded.indexableObject",
|
||||||
|
is(WorkspaceItemMatcher.matchItemWithTitleAndDateIssued(wsItem2,
|
||||||
|
"Workspace Item 2", "2010-11-03")))
|
||||||
|
),
|
||||||
|
Matchers.allOf(
|
||||||
|
SearchResultMatcher.match("submission", "workspaceitem", "workspaceitems"),
|
||||||
|
JsonPathMatchers.hasJsonPath("$._embedded.indexableObject",
|
||||||
|
is(WorkspaceItemMatcher.matchItemWithTitleAndDateIssued(wsItem1Admin,
|
||||||
|
"Admin Workspace Item 1", "2010-07-23")))
|
||||||
|
),
|
||||||
|
Matchers.allOf(
|
||||||
|
SearchResultMatcher.match("submission", "workspaceitem", "workspaceitems"),
|
||||||
|
JsonPathMatchers.hasJsonPath("$._embedded.indexableObject",
|
||||||
|
is(WorkspaceItemMatcher.matchItemWithTitleAndDateIssued(wsItem2Admin,
|
||||||
|
"Admin Workspace Item 2", "2010-11-03")))
|
||||||
|
)
|
||||||
|
)))
|
||||||
|
//These facets have to show up in the embedded.facets section as well with the given hasMore
|
||||||
|
//property because we don't exceed their default limit for a hasMore true (the default is 10)
|
||||||
|
.andExpect(jsonPath("$._embedded.facets", Matchers.containsInAnyOrder(
|
||||||
|
FacetEntryMatcher.resourceTypeFacet(false),
|
||||||
|
FacetEntryMatcher.typeFacet(false),
|
||||||
|
FacetEntryMatcher.dateIssuedFacet(false),
|
||||||
|
FacetEntryMatcher.submitterFacet(false),
|
||||||
|
FacetEntryMatcher.supervisedByFacet(false)
|
||||||
|
)))
|
||||||
|
//check supervisedBy Facet values
|
||||||
|
.andExpect(jsonPath("$._embedded.facets[4]._embedded.values",
|
||||||
|
contains(
|
||||||
|
entrySupervisedBy(groupA.getName(), groupA.getID().toString(), 6),
|
||||||
|
entrySupervisedBy(groupB.getName(), groupB.getID().toString(), 2)
|
||||||
|
)))
|
||||||
|
//There always needs to be a self link
|
||||||
|
.andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects")));
|
||||||
|
|
||||||
|
// reviewer2 should not see pool items, as it is not an administrator
|
||||||
|
getClient(reviewer2Token)
|
||||||
|
.perform(get("/api/discover/search/objects").param("configuration", "supervision"))
|
||||||
|
//** THEN **
|
||||||
|
//The status has to be 200 OK
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
//The type has to be 'discover'
|
||||||
|
.andExpect(jsonPath("$.type", is("discover")))
|
||||||
|
//There needs to be a page object that shows the total pages and total elements as well as the
|
||||||
|
// size and the current page (number)
|
||||||
|
.andExpect(jsonPath("$._embedded.searchResult.page", is(
|
||||||
|
PageMatcher.pageEntryWithTotalPagesAndElements(0, 20, 0, 0)
|
||||||
|
)))
|
||||||
|
//There always needs to be a self link
|
||||||
|
.andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects")));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,932 @@
|
|||||||
|
/**
|
||||||
|
* 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.app.rest;
|
||||||
|
import static com.jayway.jsonpath.JsonPath.read;
|
||||||
|
import static org.dspace.app.rest.matcher.ItemMatcher.matchItemWithTitleAndDateIssued;
|
||||||
|
import static org.dspace.app.rest.matcher.SupervisionOrderMatcher.matchSuperVisionOrder;
|
||||||
|
import static org.hamcrest.Matchers.contains;
|
||||||
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
||||||
|
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.post;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.model.patch.AddOperation;
|
||||||
|
import org.dspace.app.rest.model.patch.ReplaceOperation;
|
||||||
|
import org.dspace.app.rest.repository.SupervisionOrderRestRepository;
|
||||||
|
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
|
||||||
|
import org.dspace.builder.CollectionBuilder;
|
||||||
|
import org.dspace.builder.CommunityBuilder;
|
||||||
|
import org.dspace.builder.EPersonBuilder;
|
||||||
|
import org.dspace.builder.GroupBuilder;
|
||||||
|
import org.dspace.builder.ItemBuilder;
|
||||||
|
import org.dspace.builder.SupervisionOrderBuilder;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.eperson.EPerson;
|
||||||
|
import org.dspace.eperson.Group;
|
||||||
|
import org.dspace.supervision.SupervisionOrder;
|
||||||
|
import org.dspace.supervision.service.SupervisionOrderService;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration test against class {@link SupervisionOrderRestRepository}.
|
||||||
|
*
|
||||||
|
* @author Mohamed Eskander (mohamed.eskander at 4science.it)
|
||||||
|
*/
|
||||||
|
public class SupervisionOrderRestRepositoryIT extends AbstractControllerIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SupervisionOrderService supervisionOrderService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findAllByAnonymousUserTest() throws Exception {
|
||||||
|
getClient().perform(get("/api/core/supervisionorders/"))
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findAllByNotAdminUserTest() throws Exception {
|
||||||
|
|
||||||
|
String authToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(authToken).perform(get("/api/core/supervisionorders/"))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findAllByAdminTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item item =
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item title")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group groupA = GroupBuilder.createGroup(context)
|
||||||
|
.withName("group A")
|
||||||
|
.addMember(admin)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group groupB = GroupBuilder.createGroup(context)
|
||||||
|
.withName("group B")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrderOne =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, item, groupA)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrderTwo =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, item, groupB)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(adminToken).perform(get("/api/core/supervisionorders/"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.page.totalElements", is(2)))
|
||||||
|
.andExpect(jsonPath("$._embedded.supervisionorders",
|
||||||
|
containsInAnyOrder(
|
||||||
|
matchSuperVisionOrder(supervisionOrderOne),
|
||||||
|
matchSuperVisionOrder(supervisionOrderTwo)
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href", containsString("/api/core/supervisionorders")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findOneByAnonymousUserTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item item =
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item title")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group group =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrder =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, item, group)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
getClient().perform(get("/api/core/supervisionorders/" + supervisionOrder.getID()))
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findOneByNotAdminUserTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item item =
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item title")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group group =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrder =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, item, group)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String authToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(authToken).perform(get("/api/core/supervisionorders/" + supervisionOrder.getID()))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findOneByAdminTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item item =
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item title")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group group =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrder =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, item, group)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(adminToken).perform(get("/api/core/supervisionorders/" + supervisionOrder.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$", matchSuperVisionOrder(supervisionOrder)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findOneByAdminAndItemIsWithdrawnTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item item =
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item title")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group group =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrder =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, item, group)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String patchBody = getPatchContent(List.of(new ReplaceOperation("/withdrawn", true)));
|
||||||
|
|
||||||
|
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
// withdraw item
|
||||||
|
getClient(adminToken).perform(patch("/api/core/items/" + item.getID())
|
||||||
|
.content(patchBody)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.uuid", Matchers.is(item.getID().toString())))
|
||||||
|
.andExpect(jsonPath("$.withdrawn", Matchers.is(true)))
|
||||||
|
.andExpect(jsonPath("$.inArchive", Matchers.is(false)));
|
||||||
|
|
||||||
|
getClient(adminToken).perform(get("/api/core/supervisionorders/" + supervisionOrder.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$", matchSuperVisionOrder(context.reloadEntity(supervisionOrder))));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findOneByAdminButNotFoundTest() throws Exception {
|
||||||
|
int fakeId = 12354326;
|
||||||
|
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
getClient(adminToken).perform(get("/api/core/supervisionorders/" + fakeId))
|
||||||
|
.andExpect(status().isNotFound());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findByItemByAnonymousUserTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item item =
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item title")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group group =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, item, group).build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
getClient().perform(get("/api/core/supervisionorders/search/byItem")
|
||||||
|
.param("uuid", item.getID().toString()))
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findByItemByNotAdminUserTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item item =
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item title")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group group =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, item, group).build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String authToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(authToken).perform(get("/api/core/supervisionorders/search/byItem")
|
||||||
|
.param("uuid", item.getID().toString()))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findByItemByAdminButNotFoundItemTest() throws Exception {
|
||||||
|
String fakeItemId = "d9dcf4c3-093d-413e-a538-93d8589d3ea6";
|
||||||
|
|
||||||
|
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
getClient(adminToken).perform(get("/api/core/supervisionorders/search/byItem")
|
||||||
|
.param("uuid", fakeItemId))
|
||||||
|
.andExpect(status().isNotFound());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findByItemByAdminTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity =
|
||||||
|
CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item itemOne =
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item title")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group groupA =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group A")
|
||||||
|
.addMember(admin)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group groupB =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group B")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrderOne =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, itemOne, groupA)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrderTwo =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, itemOne, groupB)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item itemTwo =
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item two title")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrderItemTwo =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, itemTwo, groupA)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(adminToken).perform(get("/api/core/supervisionorders/search/byItem")
|
||||||
|
.param("uuid", itemOne.getID().toString()))
|
||||||
|
.andExpect(jsonPath("$.page.totalElements", is(2)))
|
||||||
|
.andExpect(jsonPath("$._embedded.supervisionorders", containsInAnyOrder(
|
||||||
|
matchSuperVisionOrder(supervisionOrderOne),
|
||||||
|
matchSuperVisionOrder(supervisionOrderTwo)
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href", containsString(
|
||||||
|
"/api/core/supervisionorders/search/byItem?uuid=" + itemOne.getID()))
|
||||||
|
);
|
||||||
|
|
||||||
|
getClient(adminToken).perform(get("/api/core/supervisionorders/search/byItem")
|
||||||
|
.param("uuid", itemTwo.getID().toString()))
|
||||||
|
.andExpect(jsonPath("$.page.totalElements", is(1)))
|
||||||
|
.andExpect(jsonPath("$._embedded.supervisionorders", contains(
|
||||||
|
matchSuperVisionOrder(supervisionOrderItemTwo)
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href", containsString(
|
||||||
|
"/api/core/supervisionorders/search/byItem?uuid=" + itemTwo.getID()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createByAnonymousUserTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity =
|
||||||
|
CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item item =
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item title")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group group =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
getClient().perform(post("/api/core/supervisionorders/")
|
||||||
|
.param("uuid", item.getID().toString())
|
||||||
|
.param("group", group.getID().toString())
|
||||||
|
.param("type", "EDITOR")
|
||||||
|
.contentType(contentType))
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createByNotAdminUserTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity =
|
||||||
|
CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item item =
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item title")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group group =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String authToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
getClient(authToken).perform(post("/api/core/supervisionorders/")
|
||||||
|
.param("uuid", item.getID().toString())
|
||||||
|
.param("group", group.getID().toString())
|
||||||
|
.param("type", "EDITOR")
|
||||||
|
.contentType(contentType))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createByAdminButMissingParametersTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity =
|
||||||
|
CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item itemOne =
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item title")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group groupA =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group A")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(adminToken).perform(post("/api/core/supervisionorders/")
|
||||||
|
.param("group", groupA.getID().toString())
|
||||||
|
.param("type", "EDITOR")
|
||||||
|
.contentType(contentType))
|
||||||
|
.andExpect(status().isBadRequest());
|
||||||
|
|
||||||
|
getClient(adminToken).perform(post("/api/core/supervisionorders/")
|
||||||
|
.param("uuid", itemOne.getID().toString())
|
||||||
|
.param("type", "EDITOR")
|
||||||
|
.contentType(contentType))
|
||||||
|
.andExpect(status().isBadRequest());
|
||||||
|
|
||||||
|
getClient(adminToken).perform(post("/api/core/supervisionorders/")
|
||||||
|
.param("uuid", itemOne.getID().toString())
|
||||||
|
.param("group", groupA.getID().toString())
|
||||||
|
.contentType(contentType))
|
||||||
|
.andExpect(status().isBadRequest());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createByAdminButIncorrectTypeParameterTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item item =
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item title")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group group =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
getClient(adminToken).perform(post("/api/core/supervisionorders/")
|
||||||
|
.param("uuid", item.getID().toString())
|
||||||
|
.param("group", group.getID().toString())
|
||||||
|
.param("type", "WRONG")
|
||||||
|
.contentType(contentType))
|
||||||
|
.andExpect(status().isBadRequest());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createByAdminButNotFoundItemOrGroupTest() throws Exception {
|
||||||
|
|
||||||
|
String fakeItemId = "d9dcf4c3-093d-413e-a538-93d8589d3ea6";
|
||||||
|
String fakeGroupId = "d9dcf4c3-093d-413e-a538-93d8589d3ea6";
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item itemOne =
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item title")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group groupA = GroupBuilder.createGroup(context)
|
||||||
|
.withName("group A")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(adminToken).perform(post("/api/core/supervisionorders/")
|
||||||
|
.param("uuid", fakeItemId)
|
||||||
|
.param("group", groupA.getID().toString())
|
||||||
|
.param("type", "EDITOR")
|
||||||
|
.contentType(contentType))
|
||||||
|
.andExpect(status().isUnprocessableEntity());
|
||||||
|
|
||||||
|
getClient(adminToken).perform(post("/api/core/supervisionorders/")
|
||||||
|
.param("uuid", itemOne.getID().toString())
|
||||||
|
.param("group", fakeGroupId)
|
||||||
|
.param("type", "EDITOR")
|
||||||
|
.contentType(contentType))
|
||||||
|
.andExpect(status().isUnprocessableEntity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createTheSameSupervisionOrderTwiceTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity =
|
||||||
|
CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item itemOne =
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item title")
|
||||||
|
.withIssueDate("2017-10-17")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group groupA =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group A")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(adminToken).perform(post("/api/core/supervisionorders/")
|
||||||
|
.param("uuid", itemOne.getID().toString())
|
||||||
|
.param("group", groupA.getID().toString())
|
||||||
|
.param("type", "EDITOR")
|
||||||
|
.contentType(contentType))
|
||||||
|
.andExpect(status().isCreated());
|
||||||
|
|
||||||
|
getClient(adminToken).perform(post("/api/core/supervisionorders/")
|
||||||
|
.param("uuid", itemOne.getID().toString())
|
||||||
|
.param("group", groupA.getID().toString())
|
||||||
|
.param("type", "OBSERVER")
|
||||||
|
.contentType(contentType))
|
||||||
|
.andExpect(status().isConflict());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createByAdminTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
EPerson userA =
|
||||||
|
EPersonBuilder.createEPerson(context)
|
||||||
|
.withCanLogin(true)
|
||||||
|
.withEmail("test1@email.com")
|
||||||
|
.withPassword(password)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
EPerson userB =
|
||||||
|
EPersonBuilder.createEPerson(context)
|
||||||
|
.withCanLogin(true)
|
||||||
|
.withEmail("test2@email.com")
|
||||||
|
.withPassword(password)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
parentCommunity =
|
||||||
|
CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item itemOne =
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item title")
|
||||||
|
.withIssueDate("2017-10-17")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group groupA =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group A")
|
||||||
|
.addMember(userA)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group groupB =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group B")
|
||||||
|
.addMember(userB)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
AtomicInteger supervisionOrderIdOne = new AtomicInteger();
|
||||||
|
AtomicInteger supervisionOrderIdTwo = new AtomicInteger();
|
||||||
|
|
||||||
|
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(adminToken).perform(post("/api/core/supervisionorders/")
|
||||||
|
.param("uuid", itemOne.getID().toString())
|
||||||
|
.param("group", groupA.getID().toString())
|
||||||
|
.param("type", "EDITOR")
|
||||||
|
.contentType(contentType))
|
||||||
|
.andExpect(status().isCreated())
|
||||||
|
.andDo(result -> supervisionOrderIdOne
|
||||||
|
.set(read(result.getResponse().getContentAsString(), "$.id")));
|
||||||
|
|
||||||
|
getClient(adminToken).perform(post("/api/core/supervisionorders/")
|
||||||
|
.param("uuid", itemOne.getID().toString())
|
||||||
|
.param("group", groupB.getID().toString())
|
||||||
|
.param("type", "OBSERVER")
|
||||||
|
.contentType(contentType))
|
||||||
|
.andExpect(status().isCreated())
|
||||||
|
.andDo(result -> supervisionOrderIdTwo
|
||||||
|
.set(read(result.getResponse().getContentAsString(), "$.id")));
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrderOne =
|
||||||
|
supervisionOrderService.find(context, supervisionOrderIdOne.get());
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrderTwo =
|
||||||
|
supervisionOrderService.find(context, supervisionOrderIdTwo.get());
|
||||||
|
|
||||||
|
getClient(adminToken).perform(get("/api/core/supervisionorders/" + supervisionOrderOne.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
matchSuperVisionOrder(context.reloadEntity(supervisionOrderOne))));
|
||||||
|
|
||||||
|
getClient(adminToken).perform(get("/api/core/supervisionorders/" + supervisionOrderTwo.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
matchSuperVisionOrder(context.reloadEntity(supervisionOrderTwo))));
|
||||||
|
|
||||||
|
String authTokenA = getAuthToken(userA.getEmail(), password);
|
||||||
|
String authTokenB = getAuthToken(userB.getEmail(), password);
|
||||||
|
|
||||||
|
String patchBody = getPatchContent(List.of(
|
||||||
|
new AddOperation("/metadata/dc.title", List.of(Map.of("value", "new title")))
|
||||||
|
));
|
||||||
|
|
||||||
|
// update title of itemOne by userA is Ok
|
||||||
|
getClient(authTokenA).perform(patch("/api/core/items/" + itemOne.getID())
|
||||||
|
.content(patchBody)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$", is(
|
||||||
|
matchItemWithTitleAndDateIssued(context.reloadEntity(itemOne),
|
||||||
|
"new title", "2017-10-17")
|
||||||
|
)));
|
||||||
|
|
||||||
|
// update title of itemOne by userB is Forbidden
|
||||||
|
getClient(authTokenB).perform(patch("/api/core/items/" + itemOne.getID())
|
||||||
|
.content(patchBody)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deleteByAnonymousUserTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item item =
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item title")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group group =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrder =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, item, group)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
getClient().perform(delete("/api/core/supervisionorders/" + supervisionOrder.getID()))
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deleteByNotAdminUserTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item item =
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item title")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group group =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrder =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, item, group)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String authToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(authToken).perform(delete("/api/core/supervisionorders/" + supervisionOrder.getID()))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deleteByAdminButNotFoundTest() throws Exception {
|
||||||
|
int fakeId = 12354326;
|
||||||
|
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
getClient(adminToken).perform(delete("/api/core/supervisionorders/" + fakeId))
|
||||||
|
.andExpect(status().isNotFound());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deleteByAdminTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item item =
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item title")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group group =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrder =
|
||||||
|
SupervisionOrderBuilder.createSupervisionOrder(context, item, group)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(adminToken).perform(get("/api/core/supervisionorders/" + supervisionOrder.getID()))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
|
getClient(adminToken).perform(delete("/api/core/supervisionorders/" + supervisionOrder.getID()))
|
||||||
|
.andExpect(status().isNoContent());
|
||||||
|
|
||||||
|
getClient(adminToken).perform(get("/api/core/supervisionorders/" + supervisionOrder.getID()))
|
||||||
|
.andExpect(status().isNotFound());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -46,6 +46,7 @@ import org.dspace.builder.ClaimedTaskBuilder;
|
|||||||
import org.dspace.builder.CollectionBuilder;
|
import org.dspace.builder.CollectionBuilder;
|
||||||
import org.dspace.builder.CommunityBuilder;
|
import org.dspace.builder.CommunityBuilder;
|
||||||
import org.dspace.builder.EPersonBuilder;
|
import org.dspace.builder.EPersonBuilder;
|
||||||
|
import org.dspace.builder.GroupBuilder;
|
||||||
import org.dspace.builder.ItemBuilder;
|
import org.dspace.builder.ItemBuilder;
|
||||||
import org.dspace.builder.WorkflowItemBuilder;
|
import org.dspace.builder.WorkflowItemBuilder;
|
||||||
import org.dspace.builder.WorkspaceItemBuilder;
|
import org.dspace.builder.WorkspaceItemBuilder;
|
||||||
@@ -55,6 +56,7 @@ import org.dspace.content.Community;
|
|||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.WorkspaceItem;
|
import org.dspace.content.WorkspaceItem;
|
||||||
import org.dspace.eperson.EPerson;
|
import org.dspace.eperson.EPerson;
|
||||||
|
import org.dspace.eperson.Group;
|
||||||
import org.dspace.services.ConfigurationService;
|
import org.dspace.services.ConfigurationService;
|
||||||
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
|
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
|
||||||
import org.dspace.xmlworkflow.state.Step;
|
import org.dspace.xmlworkflow.state.Step;
|
||||||
@@ -2123,4 +2125,71 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSupervisorFindOne() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
EPerson user =
|
||||||
|
EPersonBuilder.createEPerson(context)
|
||||||
|
.withCanLogin(true)
|
||||||
|
.withEmail("user@test.com")
|
||||||
|
.withPassword(password)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
EPerson anotherUser =
|
||||||
|
EPersonBuilder.createEPerson(context)
|
||||||
|
.withCanLogin(true)
|
||||||
|
.withEmail("anotheruser@test.com")
|
||||||
|
.withPassword(password)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
parentCommunity =
|
||||||
|
CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Community child1 =
|
||||||
|
CommunityBuilder.createSubCommunity(context, parentCommunity)
|
||||||
|
.withName("Sub Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection collection =
|
||||||
|
CollectionBuilder.createCollection(context, child1)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.withWorkflowGroup(1, admin)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group group =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group A")
|
||||||
|
.addMember(user)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
XmlWorkflowItem workflowItem =
|
||||||
|
WorkflowItemBuilder.createWorkflowItem(context, collection)
|
||||||
|
.withSubmitter(admin)
|
||||||
|
.withTitle("Workflow Item")
|
||||||
|
.withIssueDate("2017-10-17")
|
||||||
|
.withAuthor("Author one")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
getClient(getAuthToken(admin.getEmail(), password))
|
||||||
|
.perform(post("/api/core/supervisionorders/")
|
||||||
|
.param("uuid", workflowItem.getItem().getID().toString())
|
||||||
|
.param("group", group.getID().toString())
|
||||||
|
.param("type", "EDITOR")
|
||||||
|
.contentType(contentType))
|
||||||
|
.andExpect(status().isCreated());
|
||||||
|
|
||||||
|
getClient(getAuthToken(anotherUser.getEmail(), password))
|
||||||
|
.perform(get("/api/workflow/workflowitems/" + workflowItem.getID()))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
|
||||||
|
getClient(getAuthToken(user.getEmail(), password))
|
||||||
|
.perform(get("/api/workflow/workflowitems/" + workflowItem.getID()))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -11,9 +11,12 @@ import static com.jayway.jsonpath.JsonPath.read;
|
|||||||
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
||||||
import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadata;
|
import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadata;
|
||||||
import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadataDoesNotExist;
|
import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadataDoesNotExist;
|
||||||
|
import static org.dspace.app.rest.matcher.SupervisionOrderMatcher.matchSuperVisionOrder;
|
||||||
import static org.dspace.authorize.ResourcePolicy.TYPE_CUSTOM;
|
import static org.dspace.authorize.ResourcePolicy.TYPE_CUSTOM;
|
||||||
import static org.hamcrest.Matchers.allOf;
|
import static org.hamcrest.Matchers.allOf;
|
||||||
import static org.hamcrest.Matchers.contains;
|
import static org.hamcrest.Matchers.contains;
|
||||||
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.empty;
|
import static org.hamcrest.Matchers.empty;
|
||||||
import static org.hamcrest.Matchers.hasSize;
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
@@ -70,6 +73,7 @@ import org.dspace.builder.ItemBuilder;
|
|||||||
import org.dspace.builder.RelationshipBuilder;
|
import org.dspace.builder.RelationshipBuilder;
|
||||||
import org.dspace.builder.RelationshipTypeBuilder;
|
import org.dspace.builder.RelationshipTypeBuilder;
|
||||||
import org.dspace.builder.ResourcePolicyBuilder;
|
import org.dspace.builder.ResourcePolicyBuilder;
|
||||||
|
import org.dspace.builder.SupervisionOrderBuilder;
|
||||||
import org.dspace.builder.WorkspaceItemBuilder;
|
import org.dspace.builder.WorkspaceItemBuilder;
|
||||||
import org.dspace.content.Bitstream;
|
import org.dspace.content.Bitstream;
|
||||||
import org.dspace.content.Bundle;
|
import org.dspace.content.Bundle;
|
||||||
@@ -89,6 +93,7 @@ import org.dspace.eperson.Group;
|
|||||||
import org.dspace.eperson.factory.EPersonServiceFactory;
|
import org.dspace.eperson.factory.EPersonServiceFactory;
|
||||||
import org.dspace.eperson.service.GroupService;
|
import org.dspace.eperson.service.GroupService;
|
||||||
import org.dspace.services.ConfigurationService;
|
import org.dspace.services.ConfigurationService;
|
||||||
|
import org.dspace.supervision.SupervisionOrder;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -8291,4 +8296,274 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
|
|||||||
assertTrue(date.equals(date2));
|
assertTrue(date.equals(date2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void supervisionOrdersLinksTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity =
|
||||||
|
CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
WorkspaceItem witem =
|
||||||
|
WorkspaceItemBuilder.createWorkspaceItem(context, col1)
|
||||||
|
.withTitle("Workspace Item 1")
|
||||||
|
.withIssueDate("2022-12-12")
|
||||||
|
.withAuthor("Eskander, Mohamed")
|
||||||
|
.withSubject("ExtraEntry")
|
||||||
|
.grantLicense()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group group =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group A")
|
||||||
|
.addMember(admin)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrderOne = SupervisionOrderBuilder
|
||||||
|
.createSupervisionOrder(context, witem.getItem(), group)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//disable file upload mandatory
|
||||||
|
configurationService.setProperty("webui.submit.upload.required", false);
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(adminToken)
|
||||||
|
.perform(get("/api/submission/workspaceitems/" + witem.getID())).andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
Matchers.is(WorkspaceItemMatcher.matchItemWithTitleAndDateIssuedAndSubject(witem,
|
||||||
|
"Workspace Item 1", "2022-12-12", "ExtraEntry"))))
|
||||||
|
.andExpect(jsonPath("$._links.supervisionOrders.href", containsString(
|
||||||
|
"/api/submission/workspaceitems/" + witem.getID() + "/supervisionOrders")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void supervisionOrdersEndpointTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity =
|
||||||
|
CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
WorkspaceItem witemOne =
|
||||||
|
WorkspaceItemBuilder.createWorkspaceItem(context, col1)
|
||||||
|
.withTitle("Test item -- supervision orders")
|
||||||
|
.withIssueDate("2022-12-12")
|
||||||
|
.withAuthor("Eskander, Mohamed")
|
||||||
|
.grantLicense()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
WorkspaceItem witemTwo =
|
||||||
|
WorkspaceItemBuilder.createWorkspaceItem(context, col1)
|
||||||
|
.withTitle("Test item -- no supervision orders")
|
||||||
|
.withIssueDate("2022-12-12")
|
||||||
|
.withAuthor("Eskander")
|
||||||
|
.grantLicense()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group groupA =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group A")
|
||||||
|
.addMember(admin)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group groupB =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group B")
|
||||||
|
.addMember(eperson)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrderOne = SupervisionOrderBuilder
|
||||||
|
.createSupervisionOrder(context, witemOne.getItem(), groupA)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SupervisionOrder supervisionOrderTwo = SupervisionOrderBuilder
|
||||||
|
.createSupervisionOrder(context, witemOne.getItem(), groupB)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//disable file upload mandatory
|
||||||
|
configurationService.setProperty("webui.submit.upload.required", false);
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
String authToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
|
||||||
|
// Item's supervision orders endpoint of itemOne by not admin
|
||||||
|
getClient(authToken)
|
||||||
|
.perform(get("/api/submission/workspaceitems/" + witemOne.getID() + "/supervisionOrders"))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
|
||||||
|
// Item's supervision orders endpoint of itemOne by admin
|
||||||
|
getClient(adminToken)
|
||||||
|
.perform(get("/api/submission/workspaceitems/" + witemOne.getID() + "/supervisionOrders"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.page.totalElements", is(2)))
|
||||||
|
.andExpect(jsonPath("$._embedded.supervisionOrders", containsInAnyOrder(
|
||||||
|
matchSuperVisionOrder(supervisionOrderOne),
|
||||||
|
matchSuperVisionOrder(supervisionOrderTwo)
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href", containsString(
|
||||||
|
"/api/submission/workspaceitems/" + witemOne.getID() + "/supervisionOrders")
|
||||||
|
));
|
||||||
|
|
||||||
|
// Item's supervision orders endpoint of itemTwo by admin
|
||||||
|
getClient(adminToken)
|
||||||
|
.perform(get("/api/submission/workspaceitems/" + witemTwo.getID() + "/supervisionOrders"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.page.totalElements", is(0)))
|
||||||
|
.andExpect(jsonPath("$._embedded.supervisionOrders", empty()))
|
||||||
|
.andExpect(jsonPath("$._links.self.href", containsString(
|
||||||
|
"/api/submission/workspaceitems/" + witemTwo.getID() + "/supervisionOrders")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void patchBySupervisorTest() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
EPerson userA =
|
||||||
|
EPersonBuilder.createEPerson(context)
|
||||||
|
.withCanLogin(true)
|
||||||
|
.withEmail("userA@test.com")
|
||||||
|
.withPassword(password)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
EPerson userB =
|
||||||
|
EPersonBuilder.createEPerson(context)
|
||||||
|
.withCanLogin(true)
|
||||||
|
.withEmail("userB@test.com")
|
||||||
|
.withPassword(password)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
EPerson userC =
|
||||||
|
EPersonBuilder.createEPerson(context)
|
||||||
|
.withCanLogin(true)
|
||||||
|
.withEmail("userC@test.com")
|
||||||
|
.withPassword(password)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
parentCommunity =
|
||||||
|
CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection publications =
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Publications")
|
||||||
|
.withEntityType("Publication")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group groupA =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group A")
|
||||||
|
.addMember(userA)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group groupB =
|
||||||
|
GroupBuilder.createGroup(context)
|
||||||
|
.withName("group B")
|
||||||
|
.addMember(userB)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
WorkspaceItem witem =
|
||||||
|
WorkspaceItemBuilder.createWorkspaceItem(context, publications)
|
||||||
|
.withTitle("Workspace Item 1")
|
||||||
|
.withIssueDate("2017-10-17")
|
||||||
|
.withSubject("ExtraEntry")
|
||||||
|
.grantLicense()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//disable file upload mandatory
|
||||||
|
configurationService.setProperty("webui.submit.upload.required", false);
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
getClient(getAuthToken(admin.getEmail(), password))
|
||||||
|
.perform(post("/api/core/supervisionorders/")
|
||||||
|
.param("uuid", witem.getItem().getID().toString())
|
||||||
|
.param("group", groupA.getID().toString())
|
||||||
|
.param("type", "EDITOR")
|
||||||
|
.contentType(contentType))
|
||||||
|
.andExpect(status().isCreated());
|
||||||
|
|
||||||
|
getClient(getAuthToken(admin.getEmail(), password))
|
||||||
|
.perform(post("/api/core/supervisionorders/")
|
||||||
|
.param("uuid", witem.getItem().getID().toString())
|
||||||
|
.param("group", groupB.getID().toString())
|
||||||
|
.param("type", "OBSERVER")
|
||||||
|
.contentType(contentType))
|
||||||
|
.andExpect(status().isCreated());
|
||||||
|
|
||||||
|
String authTokenA = getAuthToken(userA.getEmail(), password);
|
||||||
|
String authTokenB = getAuthToken(userB.getEmail(), password);
|
||||||
|
String authTokenC = getAuthToken(userC.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(authTokenC).perform(get("/api/submission/workspaceitems/" + witem.getID()))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
|
||||||
|
// a simple patch to update an existent metadata
|
||||||
|
List<Operation> updateTitle = new ArrayList<>();
|
||||||
|
Map<String, String> value = new HashMap<>();
|
||||||
|
value.put("value", "New Title");
|
||||||
|
updateTitle.add(new ReplaceOperation("/sections/traditionalpageone/dc.title/0", value));
|
||||||
|
String patchBody = getPatchContent(updateTitle);
|
||||||
|
|
||||||
|
getClient(authTokenB).perform(patch("/api/submission/workspaceitems/" + witem.getID())
|
||||||
|
.content(patchBody)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
|
||||||
|
getClient(authTokenA).perform(patch("/api/submission/workspaceitems/" + witem.getID())
|
||||||
|
.content(patchBody)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
// check the new title and untouched values
|
||||||
|
Matchers.is(WorkspaceItemMatcher
|
||||||
|
.matchItemWithTitleAndDateIssuedAndSubject(
|
||||||
|
witem,
|
||||||
|
"New Title", "2017-10-17",
|
||||||
|
"ExtraEntry"))));
|
||||||
|
|
||||||
|
getClient(authTokenA).perform(get("/api/submission/workspaceitems/" + witem.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
Matchers.is(
|
||||||
|
WorkspaceItemMatcher
|
||||||
|
.matchItemWithTitleAndDateIssuedAndSubject(
|
||||||
|
witem,
|
||||||
|
"New Title", "2017-10-17",
|
||||||
|
"ExtraEntry")
|
||||||
|
)));
|
||||||
|
|
||||||
|
getClient(authTokenB).perform(get("/api/submission/workspaceitems/" + witem.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
Matchers.is(
|
||||||
|
WorkspaceItemMatcher
|
||||||
|
.matchItemWithTitleAndDateIssuedAndSubject(
|
||||||
|
witem,
|
||||||
|
"New Title", "2017-10-17",
|
||||||
|
"ExtraEntry")
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -67,6 +67,17 @@ public class FacetEntryMatcher {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Matcher<? super Object> supervisedByFacet(boolean hasNext) {
|
||||||
|
return allOf(
|
||||||
|
hasJsonPath("$.name", is("supervisedBy")),
|
||||||
|
hasJsonPath("$.facetType", is("authority")),
|
||||||
|
hasJsonPath("$.facetLimit", any(Integer.class)),
|
||||||
|
hasJsonPath("$._links.self.href", containsString("api/discover/facets/supervisedBy")),
|
||||||
|
hasJsonPath("$._links", matchNextLink(hasNext, "api/discover/facets/supervisedBy"))
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static Matcher<? super Object> dateIssuedFacet(boolean hasNext) {
|
public static Matcher<? super Object> dateIssuedFacet(boolean hasNext) {
|
||||||
return allOf(
|
return allOf(
|
||||||
hasJsonPath("$.name", is("dateIssued")),
|
hasJsonPath("$.name", is("dateIssued")),
|
||||||
|
@@ -97,4 +97,16 @@ public class FacetValueMatcher {
|
|||||||
hasJsonPath("$._links.search.href", containsString(",equals"))
|
hasJsonPath("$._links.search.href", containsString(",equals"))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Matcher<? super Object> entrySupervisedBy(String label, String authority, int count) {
|
||||||
|
return allOf(
|
||||||
|
hasJsonPath("$.authorityKey", is(authority)),
|
||||||
|
hasJsonPath("$.count", is(count)),
|
||||||
|
hasJsonPath("$.label", is(label)),
|
||||||
|
hasJsonPath("$.type", is("discover")),
|
||||||
|
hasJsonPath("$._links.search.href", containsString("api/discover/search/objects")),
|
||||||
|
hasJsonPath("$._links.search.href", containsString("f.supervisedBy=" + authority + ",authority"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* 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.app.rest.matcher;
|
||||||
|
|
||||||
|
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
||||||
|
import static org.dspace.app.rest.matcher.GroupMatcher.matchGroupEntry;
|
||||||
|
import static org.dspace.app.rest.matcher.ItemMatcher.matchItemProperties;
|
||||||
|
import static org.hamcrest.Matchers.allOf;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
import org.dspace.eperson.Group;
|
||||||
|
import org.dspace.supervision.SupervisionOrder;
|
||||||
|
import org.hamcrest.Matcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class to construct a Matcher for an SupervisionOrder object
|
||||||
|
*
|
||||||
|
* @author Mohamed Eskander (mohamed.eskander at 4science dot it)
|
||||||
|
*/
|
||||||
|
public class SupervisionOrderMatcher {
|
||||||
|
|
||||||
|
private SupervisionOrderMatcher() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Matcher<? super Object> matchSuperVisionOrder(SupervisionOrder supervisionOrder) {
|
||||||
|
Group group = supervisionOrder.getGroup();
|
||||||
|
return allOf(
|
||||||
|
hasJsonPath("$.id", is(supervisionOrder.getID())),
|
||||||
|
hasJsonPath("$._embedded.item", matchItemProperties(supervisionOrder.getItem())),
|
||||||
|
hasJsonPath("$._embedded.group", matchGroupEntry(group.getID(), group.getName()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -93,5 +93,7 @@
|
|||||||
<mapping class="org.dspace.orcid.OrcidHistory" />
|
<mapping class="org.dspace.orcid.OrcidHistory" />
|
||||||
<mapping class="org.dspace.orcid.OrcidToken"/>
|
<mapping class="org.dspace.orcid.OrcidToken"/>
|
||||||
|
|
||||||
|
<mapping class="org.dspace.supervision.SupervisionOrder"/>
|
||||||
|
|
||||||
</session-factory>
|
</session-factory>
|
||||||
</hibernate-configuration>
|
</hibernate-configuration>
|
||||||
|
@@ -64,5 +64,7 @@
|
|||||||
<bean class="org.dspace.orcid.dao.impl.OrcidQueueDAOImpl" />
|
<bean class="org.dspace.orcid.dao.impl.OrcidQueueDAOImpl" />
|
||||||
<bean class="org.dspace.orcid.dao.impl.OrcidHistoryDAOImpl" />
|
<bean class="org.dspace.orcid.dao.impl.OrcidHistoryDAOImpl" />
|
||||||
|
|
||||||
|
<bean class="org.dspace.supervision.dao.impl.SupervisionOrderDaoImpl"/>
|
||||||
|
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
@@ -55,4 +55,6 @@
|
|||||||
|
|
||||||
<bean id="orcidServiceFactory" class="org.dspace.orcid.factory.OrcidServiceFactoryImpl"/>
|
<bean id="orcidServiceFactory" class="org.dspace.orcid.factory.OrcidServiceFactoryImpl"/>
|
||||||
|
|
||||||
|
<bean id="supervisionOrderServiceFactory" class="org.dspace.supervision.factory.SupervisionOrderServiceFactoryImpl"/>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
@@ -148,5 +148,7 @@
|
|||||||
<bean class="org.dspace.authorize.ValidatePasswordServiceImpl"/>
|
<bean class="org.dspace.authorize.ValidatePasswordServiceImpl"/>
|
||||||
<bean class="org.dspace.authorize.RegexPasswordValidator" />
|
<bean class="org.dspace.authorize.RegexPasswordValidator" />
|
||||||
|
|
||||||
|
<bean class="org.dspace.supervision.SupervisionOrderServiceImpl"/>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
|
||||||
|
@@ -40,6 +40,9 @@
|
|||||||
<!-- Additional indexing plugin enables searching by filenames and by file descriptions for files in ORIGINAL bundle -->
|
<!-- Additional indexing plugin enables searching by filenames and by file descriptions for files in ORIGINAL bundle -->
|
||||||
<bean id="solrServiceFileInfoPlugin" class="org.dspace.discovery.SolrServiceFileInfoPlugin"/>
|
<bean id="solrServiceFileInfoPlugin" class="org.dspace.discovery.SolrServiceFileInfoPlugin"/>
|
||||||
|
|
||||||
|
<!-- Additional indexing plugin enables searching by supervised (true,false) -->
|
||||||
|
<bean id="solrServiceSupervisionOrderIndexingPlugin" class="org.dspace.discovery.SolrServiceSupervisionOrderIndexingPlugin"/>
|
||||||
|
|
||||||
<!--Bean that is used for mapping communities/collections to certain discovery configurations.-->
|
<!--Bean that is used for mapping communities/collections to certain discovery configurations.-->
|
||||||
<bean id="org.dspace.discovery.configuration.DiscoveryConfigurationService" class="org.dspace.discovery.configuration.DiscoveryConfigurationService">
|
<bean id="org.dspace.discovery.configuration.DiscoveryConfigurationService" class="org.dspace.discovery.configuration.DiscoveryConfigurationService">
|
||||||
<property name="map">
|
<property name="map">
|
||||||
@@ -61,10 +64,14 @@
|
|||||||
<!-- Do not change the id of special entries or else they won't work -->
|
<!-- Do not change the id of special entries or else they won't work -->
|
||||||
<!-- "workspace" is a special entry to search for your own workspace items -->
|
<!-- "workspace" is a special entry to search for your own workspace items -->
|
||||||
<entry key="workspace" value-ref="workspaceConfiguration" />
|
<entry key="workspace" value-ref="workspaceConfiguration" />
|
||||||
|
<entry key="otherworkspace" value-ref="otherWorkspaceConfiguration" />
|
||||||
<!-- "workflow" is a special entry to search for your own workflow tasks -->
|
<!-- "workflow" is a special entry to search for your own workflow tasks -->
|
||||||
<entry key="workflow" value-ref="workflowConfiguration" />
|
<entry key="workflow" value-ref="workflowConfiguration" />
|
||||||
<!-- "workflowAdmin" is a special entry to search for all workflow items if you are an administrator -->
|
<!-- "workflowAdmin" is a special entry to search for all workflow items if you are an administrator -->
|
||||||
<entry key="workflowAdmin" value-ref="workflowAdminConfiguration" />
|
<entry key="workflowAdmin" value-ref="workflowAdminConfiguration" />
|
||||||
|
<!-- "supervision" is a special entry to search for all workspace and workflow items if you are an administrator -->
|
||||||
|
<entry key="supervision" value-ref="supervisionConfiguration" />
|
||||||
|
|
||||||
<entry key="undiscoverable" value-ref="unDiscoverableItems" />
|
<entry key="undiscoverable" value-ref="unDiscoverableItems" />
|
||||||
<entry key="administrativeView" value-ref="administrativeView" />
|
<entry key="administrativeView" value-ref="administrativeView" />
|
||||||
|
|
||||||
@@ -894,6 +901,81 @@
|
|||||||
<property name="spellCheckEnabled" value="true"/>
|
<property name="spellCheckEnabled" value="true"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<!--The other workspace configuration settings for discovery -->
|
||||||
|
<bean id="otherWorkspaceConfiguration"
|
||||||
|
class="org.dspace.discovery.configuration.DiscoveryConfiguration"
|
||||||
|
scope="prototype">
|
||||||
|
<property name="id" value="otherworkspace" />
|
||||||
|
<!--Which sidebar facets are to be displayed -->
|
||||||
|
<property name="sidebarFacets">
|
||||||
|
<list>
|
||||||
|
<ref bean="searchFilterObjectNamedType" />
|
||||||
|
<ref bean="searchFilterType" />
|
||||||
|
<ref bean="searchFilterIssued" />
|
||||||
|
<ref bean="searchFilterSupervision" />
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
<!--The search filters which can be used on the discovery search page -->
|
||||||
|
<property name="searchFilters">
|
||||||
|
<list>
|
||||||
|
<ref bean="searchFilterObjectNamedType" />
|
||||||
|
<ref bean="searchFilterType" />
|
||||||
|
<ref bean="searchFilterIssued" />
|
||||||
|
<ref bean="searchFilterSupervision" />
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
<!--The sort filters for the discovery search-->
|
||||||
|
<property name="searchSortConfiguration">
|
||||||
|
<bean class="org.dspace.discovery.configuration.DiscoverySortConfiguration">
|
||||||
|
<property name="sortFields">
|
||||||
|
<list>
|
||||||
|
<ref bean="sortLastModified" />
|
||||||
|
<ref bean="sortTitleAsc" />
|
||||||
|
<ref bean="sortDateIssuedDesc" />
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
</property>
|
||||||
|
<!--Any default filter queries, these filter queries will be used for all
|
||||||
|
queries done by discovery for this configuration -->
|
||||||
|
<property name="defaultFilterQueries">
|
||||||
|
<list>
|
||||||
|
<!--Only find items, workspace and accepted for workflow -->
|
||||||
|
<value>search.resourcetype:WorkspaceItem</value>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
<!--Default result per page -->
|
||||||
|
<property name="defaultRpp" value="10" />
|
||||||
|
<property name="hitHighlightingConfiguration">
|
||||||
|
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightingConfiguration">
|
||||||
|
<property name="metadataFields">
|
||||||
|
<list>
|
||||||
|
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
|
||||||
|
<property name="field" value="dc.title"/>
|
||||||
|
<property name="snippets" value="5"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
|
||||||
|
<property name="field" value="dc.contributor.author"/>
|
||||||
|
<property name="snippets" value="5"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
|
||||||
|
<property name="field" value="dc.description.abstract"/>
|
||||||
|
<property name="maxSize" value="250"/>
|
||||||
|
<property name="snippets" value="2"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
|
||||||
|
<property name="field" value="fulltext"/>
|
||||||
|
<property name="maxSize" value="250"/>
|
||||||
|
<property name="snippets" value="2"/>
|
||||||
|
</bean>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
</property>
|
||||||
|
<!-- When true a "did you mean" example will be displayed, value can be true or false -->
|
||||||
|
<property name="spellCheckEnabled" value="true"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<!--The workflow configuration settings for discovery -->
|
<!--The workflow configuration settings for discovery -->
|
||||||
<bean id="workflowConfiguration"
|
<bean id="workflowConfiguration"
|
||||||
class="org.dspace.discovery.configuration.DiscoveryConfiguration"
|
class="org.dspace.discovery.configuration.DiscoveryConfiguration"
|
||||||
@@ -1043,6 +1125,81 @@
|
|||||||
<property name="spellCheckEnabled" value="true"/>
|
<property name="spellCheckEnabled" value="true"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="supervisionConfiguration"
|
||||||
|
class="org.dspace.discovery.configuration.DiscoveryConfiguration"
|
||||||
|
scope="prototype">
|
||||||
|
<property name="id" value="supervision" />
|
||||||
|
<!--Which sidebar facets are to be displayed -->
|
||||||
|
<property name="sidebarFacets">
|
||||||
|
<list>
|
||||||
|
<ref bean="searchFilterObjectNamedType" />
|
||||||
|
<ref bean="searchFilterType" />
|
||||||
|
<ref bean="searchFilterIssued" />
|
||||||
|
<ref bean="searchFilterSubmitter" />
|
||||||
|
<ref bean="searchFilterSupervision" />
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
<!--The search filters which can be used on the discovery search page -->
|
||||||
|
<property name="searchFilters">
|
||||||
|
<list>
|
||||||
|
<ref bean="searchFilterObjectNamedType" />
|
||||||
|
<ref bean="searchFilterType" />
|
||||||
|
<ref bean="searchFilterIssued" />
|
||||||
|
<ref bean="searchFilterSubmitter" />
|
||||||
|
<ref bean="searchFilterSupervision" />
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
<!--The sort filters for the discovery search-->
|
||||||
|
<property name="searchSortConfiguration">
|
||||||
|
<bean class="org.dspace.discovery.configuration.DiscoverySortConfiguration">
|
||||||
|
<property name="sortFields">
|
||||||
|
<list>
|
||||||
|
<ref bean="sortScore" />
|
||||||
|
<ref bean="sortTitle" />
|
||||||
|
<ref bean="sortDateIssued" />
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
</property>
|
||||||
|
<!--Any default filter queries, these filter queries will be used for all
|
||||||
|
queries done by discovery for this configuration -->
|
||||||
|
<property name="defaultFilterQueries">
|
||||||
|
<list>
|
||||||
|
<value>search.resourcetype:WorkspaceItem OR search.resourcetype:XmlWorkflowItem</value>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
<!--Default result per page -->
|
||||||
|
<property name="defaultRpp" value="10" />
|
||||||
|
<property name="hitHighlightingConfiguration">
|
||||||
|
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightingConfiguration">
|
||||||
|
<property name="metadataFields">
|
||||||
|
<list>
|
||||||
|
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
|
||||||
|
<property name="field" value="dc.title"/>
|
||||||
|
<property name="snippets" value="5"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
|
||||||
|
<property name="field" value="dc.contributor.author"/>
|
||||||
|
<property name="snippets" value="5"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
|
||||||
|
<property name="field" value="dc.description.abstract"/>
|
||||||
|
<property name="maxSize" value="250"/>
|
||||||
|
<property name="snippets" value="2"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
|
||||||
|
<property name="field" value="fulltext"/>
|
||||||
|
<property name="maxSize" value="250"/>
|
||||||
|
<property name="snippets" value="2"/>
|
||||||
|
</bean>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
</property>
|
||||||
|
<!-- When true a "did you mean" example will be displayed, value can be true or false -->
|
||||||
|
<property name="spellCheckEnabled" value="true"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="publication" class="org.dspace.discovery.configuration.DiscoveryConfiguration" scope="prototype">
|
<bean id="publication" class="org.dspace.discovery.configuration.DiscoveryConfiguration" scope="prototype">
|
||||||
<property name="id" value="publication"/>
|
<property name="id" value="publication"/>
|
||||||
<property name="indexAlways" value="true"/>
|
<property name="indexAlways" value="true"/>
|
||||||
@@ -2792,6 +2949,18 @@
|
|||||||
<property name="pageSize" value="10"/>
|
<property name="pageSize" value="10"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<!-- Used only to READ "supervisedBy" facets -->
|
||||||
|
<bean id="searchFilterSupervision"
|
||||||
|
class="org.dspace.discovery.configuration.DiscoverySearchFilterFacet">
|
||||||
|
<property name="indexFieldName" value="supervisedBy" />
|
||||||
|
<property name="type" value="authority" />
|
||||||
|
<property name="metadataFields">
|
||||||
|
<list>
|
||||||
|
<value>placeholder.placeholder.placeholder</value>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<!--Sort properties-->
|
<!--Sort properties-->
|
||||||
<bean id="sortScore" class="org.dspace.discovery.configuration.DiscoverySortFieldConfiguration">
|
<bean id="sortScore" class="org.dspace.discovery.configuration.DiscoverySortFieldConfiguration">
|
||||||
<property name="defaultSortOrder" value="desc"/>
|
<property name="defaultSortOrder" value="desc"/>
|
||||||
@@ -2866,4 +3035,21 @@
|
|||||||
<property name="defaultSortOrder" value="desc"/>
|
<property name="defaultSortOrder" value="desc"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="sortLastModified" class="org.dspace.discovery.configuration.DiscoverySortFieldConfiguration">
|
||||||
|
<property name="metadataField" value="lastModified" />
|
||||||
|
<property name="type" value="date" />
|
||||||
|
<property name="defaultSortOrder" value="desc"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="sortTitleAsc" class="org.dspace.discovery.configuration.DiscoverySortFieldConfiguration">
|
||||||
|
<property name="metadataField" value="dc.title"/>
|
||||||
|
<property name="defaultSortOrder" value="asc"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="sortDateIssuedDesc" class="org.dspace.discovery.configuration.DiscoverySortFieldConfiguration">
|
||||||
|
<property name="metadataField" value="dc.date.issued"/>
|
||||||
|
<property name="type" value="date"/>
|
||||||
|
<property name="defaultSortOrder" value="desc"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
Reference in New Issue
Block a user