[CST-7754] removed old code of supervision orders

added a new migration script sql
tested that supervisors can edit only workspace items
This commit is contained in:
Mohamed Saber Eskander
2023-02-01 18:13:26 +02:00
committed by eskander
parent 7a08fe50fe
commit da2815752c
31 changed files with 888 additions and 707 deletions

View File

@@ -1,39 +0,0 @@
/**
* 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;
}
}

View File

@@ -22,6 +22,8 @@ import org.dspace.embargo.service.EmbargoService;
import org.dspace.event.Event; import org.dspace.event.Event;
import org.dspace.identifier.IdentifierException; import org.dspace.identifier.IdentifierException;
import org.dspace.identifier.service.IdentifierService; import org.dspace.identifier.service.IdentifierService;
import org.dspace.supervision.SupervisionOrder;
import org.dspace.supervision.service.SupervisionOrderService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
/** /**
@@ -42,6 +44,8 @@ public class InstallItemServiceImpl implements InstallItemService {
protected IdentifierService identifierService; protected IdentifierService identifierService;
@Autowired(required = true) @Autowired(required = true)
protected ItemService itemService; protected ItemService itemService;
@Autowired(required = true)
protected SupervisionOrderService supervisionOrderService;
protected InstallItemServiceImpl() { protected InstallItemServiceImpl() {
@@ -222,9 +226,19 @@ public class InstallItemServiceImpl implements InstallItemService {
// set embargo lift date and take away read access if indicated. // set embargo lift date and take away read access if indicated.
embargoService.setEmbargo(c, item); embargoService.setEmbargo(c, item);
// delete all related supervision orders
deleteSupervisionOrders(c, item);
return item; return item;
} }
private void deleteSupervisionOrders(Context c, Item item) throws SQLException, AuthorizeException {
List<SupervisionOrder> supervisionOrders = supervisionOrderService.findByItem(c, item);
for (SupervisionOrder supervisionOrder : supervisionOrders) {
supervisionOrderService.delete(c, supervisionOrder);
}
}
@Override @Override
public String getBitstreamProvenanceMessage(Context context, Item myitem) public String getBitstreamProvenanceMessage(Context context, Item myitem)
throws SQLException { throws SQLException {

View File

@@ -1,40 +0,0 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.content;
import java.sql.SQLException;
import java.util.List;
import org.dspace.content.service.SupervisedItemService;
import org.dspace.content.service.WorkspaceItemService;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.springframework.beans.factory.annotation.Autowired;
public class SupervisedItemServiceImpl implements SupervisedItemService {
@Autowired(required = true)
protected WorkspaceItemService workspaceItemService;
protected SupervisedItemServiceImpl() {
}
@Override
public List<WorkspaceItem> getAll(Context context)
throws SQLException {
return workspaceItemService.findAllSupervisedItems(context);
}
@Override
public List<WorkspaceItem> findbyEPerson(Context context, EPerson ep)
throws SQLException {
return workspaceItemService.findSupervisedItemsByEPerson(context, ep);
}
}

View File

@@ -8,8 +8,6 @@
package org.dspace.content; package org.dspace.content;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.FetchType; import javax.persistence.FetchType;
@@ -17,8 +15,6 @@ import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType; import javax.persistence.GenerationType;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import javax.persistence.OneToOne; import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator; import javax.persistence.SequenceGenerator;
@@ -27,7 +23,6 @@ import javax.persistence.Table;
import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.eperson.EPerson; import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
import org.dspace.workflow.WorkflowItem; import org.dspace.workflow.WorkflowItem;
import org.hibernate.proxy.HibernateProxyHelper; import org.hibernate.proxy.HibernateProxyHelper;
@@ -78,14 +73,6 @@ public class WorkspaceItem
@Column(name = "page_reached") @Column(name = "page_reached")
private Integer pageReached = -1; private Integer pageReached = -1;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "epersongroup2workspaceitem",
joinColumns = {@JoinColumn(name = "workspace_item_id")},
inverseJoinColumns = {@JoinColumn(name = "eperson_group_id")}
)
private final List<Group> supervisorGroups = new ArrayList<>();
/** /**
* Protected constructor, create object using: * Protected constructor, create object using:
* {@link org.dspace.content.service.WorkspaceItemService#create(Context, Collection, boolean)} * {@link org.dspace.content.service.WorkspaceItemService#create(Context, Collection, boolean)}
@@ -226,15 +213,4 @@ public class WorkspaceItem
publishedBefore = b; publishedBefore = b;
} }
public List<Group> getSupervisorGroups() {
return supervisorGroups;
}
void removeSupervisorGroup(Group group) {
supervisorGroups.remove(group);
}
void addSupervisorGroup(Group group) {
supervisorGroups.add(group);
}
} }

View File

@@ -212,16 +212,6 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService {
return workspaceItemDAO.findByItem(context, item); return workspaceItemDAO.findByItem(context, item);
} }
@Override
public List<WorkspaceItem> findAllSupervisedItems(Context context) throws SQLException {
return workspaceItemDAO.findWithSupervisedGroup(context);
}
@Override
public List<WorkspaceItem> findSupervisedItemsByEPerson(Context context, EPerson ePerson) throws SQLException {
return workspaceItemDAO.findBySupervisedGroupMember(context, ePerson);
}
@Override @Override
public List<WorkspaceItem> findAll(Context context) throws SQLException { public List<WorkspaceItem> findAll(Context context) throws SQLException {
return workspaceItemDAO.findAll(context); return workspaceItemDAO.findAll(context);
@@ -268,10 +258,6 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService {
"workspace_item_id=" + workspaceItem.getID() + "item_id=" + item.getID() "workspace_item_id=" + workspaceItem.getID() + "item_id=" + item.getID()
+ "collection_id=" + workspaceItem.getCollection().getID())); + "collection_id=" + workspaceItem.getCollection().getID()));
// Need to delete the epersongroup2workspaceitem row first since it refers
// to workspaceitem ID
workspaceItem.getSupervisorGroups().clear();
// Need to delete the workspaceitem row first since it refers // Need to delete the workspaceitem row first since it refers
// to item ID // to item ID
workspaceItemDAO.delete(context, workspaceItem); workspaceItemDAO.delete(context, workspaceItem);
@@ -307,14 +293,6 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService {
// deleteSubmitPermissions(); // deleteSubmitPermissions();
// Need to delete the workspaceitem row first since it refers
// to item ID
try {
workspaceItem.getSupervisorGroups().clear();
} catch (Exception e) {
log.error("failed to clear supervisor group", e);
}
workspaceItemDAO.delete(context, workspaceItem); workspaceItemDAO.delete(context, workspaceItem);
} }

View File

@@ -41,10 +41,6 @@ public interface WorkspaceItemDAO extends GenericDAO<WorkspaceItem> {
public List<WorkspaceItem> findAll(Context context, Integer limit, Integer offset) throws SQLException; public List<WorkspaceItem> findAll(Context context, Integer limit, Integer offset) throws SQLException;
public List<WorkspaceItem> findWithSupervisedGroup(Context context) throws SQLException;
public List<WorkspaceItem> findBySupervisedGroupMember(Context context, EPerson ePerson) throws SQLException;
int countRows(Context context) throws SQLException; int countRows(Context context) throws SQLException;
List<Map.Entry<Integer, Long>> getStageReachedCounts(Context context) throws SQLException; List<Map.Entry<Integer, Long>> getStageReachedCounts(Context context) throws SQLException;

View File

@@ -15,7 +15,6 @@ import java.util.Map;
import javax.persistence.Query; import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Root; import javax.persistence.criteria.Root;
import org.dspace.content.Collection; import org.dspace.content.Collection;
@@ -26,8 +25,6 @@ import org.dspace.content.dao.WorkspaceItemDAO;
import org.dspace.core.AbstractHibernateDAO; import org.dspace.core.AbstractHibernateDAO;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.eperson.EPerson; import org.dspace.eperson.EPerson;
import org.dspace.eperson.EPerson_;
import org.dspace.eperson.Group;
/** /**
* Hibernate implementation of the Database Access Object interface class for the WorkspaceItem object. * Hibernate implementation of the Database Access Object interface class for the WorkspaceItem object.
@@ -114,33 +111,6 @@ public class WorkspaceItemDAOImpl extends AbstractHibernateDAO<WorkspaceItem> im
return list(context, criteriaQuery, false, WorkspaceItem.class, limit, offset); return list(context, criteriaQuery, false, WorkspaceItem.class, limit, offset);
} }
@Override
public List<WorkspaceItem> findWithSupervisedGroup(Context context) throws SQLException {
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, WorkspaceItem.class);
Root<WorkspaceItem> workspaceItemRoot = criteriaQuery.from(WorkspaceItem.class);
criteriaQuery.select(workspaceItemRoot);
criteriaQuery.where(criteriaBuilder.isNotEmpty(workspaceItemRoot.get(WorkspaceItem_.supervisorGroups)));
List<javax.persistence.criteria.Order> orderList = new LinkedList<>();
orderList.add(criteriaBuilder.asc(workspaceItemRoot.get(WorkspaceItem_.workspaceItemId)));
criteriaQuery.orderBy(orderList);
return list(context, criteriaQuery, false, WorkspaceItem.class, -1, -1);
}
@Override
public List<WorkspaceItem> findBySupervisedGroupMember(Context context, EPerson ePerson) throws SQLException {
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, WorkspaceItem.class);
Root<WorkspaceItem> workspaceItemRoot = criteriaQuery.from(WorkspaceItem.class);
Join<WorkspaceItem, Group> join = workspaceItemRoot.join("supervisorGroups");
Join<Group, EPerson> secondJoin = join.join("epeople");
criteriaQuery.select(workspaceItemRoot);
criteriaQuery.where(criteriaBuilder.equal(secondJoin.get(EPerson_.id), ePerson.getID()));
criteriaQuery.orderBy(criteriaBuilder.asc(workspaceItemRoot.get(WorkspaceItem_.workspaceItemId)));
return list(context, criteriaQuery, false, WorkspaceItem.class, -1, -1);
}
@Override @Override
public int countRows(Context context) throws SQLException { public int countRows(Context context) throws SQLException {
return count(createQuery(context, "SELECT count(*) from WorkspaceItem")); return count(createQuery(context, "SELECT count(*) from WorkspaceItem"));

View File

@@ -31,7 +31,6 @@ import org.dspace.content.service.MetadataValueService;
import org.dspace.content.service.RelationshipService; import org.dspace.content.service.RelationshipService;
import org.dspace.content.service.RelationshipTypeService; import org.dspace.content.service.RelationshipTypeService;
import org.dspace.content.service.SiteService; import org.dspace.content.service.SiteService;
import org.dspace.content.service.SupervisedItemService;
import org.dspace.content.service.WorkspaceItemService; import org.dspace.content.service.WorkspaceItemService;
import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.services.factory.DSpaceServicesFactory;
import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.workflow.factory.WorkflowServiceFactory;
@@ -71,8 +70,6 @@ public abstract class ContentServiceFactory {
public abstract InstallItemService getInstallItemService(); public abstract InstallItemService getInstallItemService();
public abstract SupervisedItemService getSupervisedItemService();
public abstract SiteService getSiteService(); public abstract SiteService getSiteService();
/** /**

View File

@@ -28,7 +28,6 @@ import org.dspace.content.service.MetadataValueService;
import org.dspace.content.service.RelationshipService; import org.dspace.content.service.RelationshipService;
import org.dspace.content.service.RelationshipTypeService; import org.dspace.content.service.RelationshipTypeService;
import org.dspace.content.service.SiteService; import org.dspace.content.service.SiteService;
import org.dspace.content.service.SupervisedItemService;
import org.dspace.content.service.WorkspaceItemService; import org.dspace.content.service.WorkspaceItemService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -68,8 +67,6 @@ public class ContentServiceFactoryImpl extends ContentServiceFactory {
@Autowired(required = true) @Autowired(required = true)
private InstallItemService installItemService; private InstallItemService installItemService;
@Autowired(required = true) @Autowired(required = true)
private SupervisedItemService supervisedItemService;
@Autowired(required = true)
private SiteService siteService; private SiteService siteService;
@Autowired(required = true) @Autowired(required = true)
@@ -148,11 +145,6 @@ public class ContentServiceFactoryImpl extends ContentServiceFactory {
return installItemService; return installItemService;
} }
@Override
public SupervisedItemService getSupervisedItemService() {
return supervisedItemService;
}
@Override @Override
public SiteService getSiteService() { public SiteService getSiteService() {
return siteService; return siteService;

View File

@@ -1,44 +0,0 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.content.service;
import java.sql.SQLException;
import java.util.List;
import org.dspace.content.WorkspaceItem;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
/**
* Class to handle WorkspaceItems which are being supervised.
*
* @author Richard Jones
* @version $Revision$
*/
public interface SupervisedItemService {
/**
* Get all workspace items which are being supervised
*
* @param context the context this object exists in
* @return array of SupervisedItems
* @throws SQLException if database error
*/
public List<WorkspaceItem> getAll(Context context) throws SQLException;
/**
* Get items being supervised by given EPerson
*
* @param ep the eperson who's items to supervise we want
* @param context the dspace context
* @return the items eperson is supervising in an array
* @throws SQLException if database error
*/
public List<WorkspaceItem> findbyEPerson(Context context, EPerson ep)
throws SQLException;
}

View File

@@ -127,10 +127,6 @@ public interface WorkspaceItemService extends InProgressSubmissionService<Worksp
public WorkspaceItem findByItem(Context context, Item item) public WorkspaceItem findByItem(Context context, Item item)
throws SQLException; throws SQLException;
public List<WorkspaceItem> findAllSupervisedItems(Context context) throws SQLException;
public List<WorkspaceItem> findSupervisedItemsByEPerson(Context context, EPerson ePerson) throws SQLException;
/** /**
* Get all workspace items in the whole system * Get all workspace items in the whole system
* *

View File

@@ -23,8 +23,12 @@ import org.dspace.supervision.service.SupervisionOrderService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
/** /**
* A Solr Indexing plugin responsible for
* When item being indexed is a workspace or workflow item,
* and at least one supervision order is defined
* a 'supervised' field with value 'true' will be added to the solr document,
* if not a 'supervised' will be 'false'
* *
*
* @author Mohamed Eskander (mohamed.eskander at 4science dot it) * @author Mohamed Eskander (mohamed.eskander at 4science dot it)
*/ */
public class SolrServiceSupervisionOrderIndexingPlugin implements SolrServiceIndexPlugin { public class SolrServiceSupervisionOrderIndexingPlugin implements SolrServiceIndexPlugin {

View File

@@ -23,7 +23,6 @@ import javax.persistence.Transient;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.content.DSpaceObjectLegacySupport; import org.dspace.content.DSpaceObjectLegacySupport;
import org.dspace.content.WorkspaceItem;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.hibernate.annotations.CacheConcurrencyStrategy; import org.hibernate.annotations.CacheConcurrencyStrategy;
@@ -83,9 +82,6 @@ public class Group extends DSpaceObject implements DSpaceObjectLegacySupport {
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "groups") @ManyToMany(fetch = FetchType.LAZY, mappedBy = "groups")
private final List<Group> parentGroups = new ArrayList<>(); private final List<Group> parentGroups = new ArrayList<>();
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "supervisorGroups")
private final List<WorkspaceItem> supervisedItems = new ArrayList<>();
@Transient @Transient
private boolean groupsChanged; private boolean groupsChanged;
@@ -218,10 +214,6 @@ public class Group extends DSpaceObject implements DSpaceObjectLegacySupport {
return legacyId; return legacyId;
} }
public List<WorkspaceItem> getSupervisedItems() {
return supervisedItems;
}
/** /**
* May this Group be renamed or deleted? (The content of any group may be * May this Group be renamed or deleted? (The content of any group may be
* changed.) * changed.)

View File

@@ -480,9 +480,6 @@ public class GroupServiceImpl extends DSpaceObjectServiceImpl<Group> implements
context.addEvent(new Event(Event.DELETE, Constants.GROUP, group.getID(), context.addEvent(new Event(Event.DELETE, Constants.GROUP, group.getID(),
group.getName(), getIdentifiers(context, group))); group.getName(), getIdentifiers(context, group)));
//Remove the supervised group from any workspace items linked to us.
group.getSupervisedItems().clear();
// Remove any ResourcePolicies that reference this group // Remove any ResourcePolicies that reference this group
authorizeService.removeGroupPolicies(context, group); authorizeService.removeGroupPolicies(context, group);

View File

@@ -1,93 +0,0 @@
/**
* 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.eperson;
import java.sql.SQLException;
import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.authorize.service.ResourcePolicyService;
import org.dspace.content.Item;
import org.dspace.content.WorkspaceItem;
import org.dspace.content.service.ItemService;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.eperson.service.SupervisorService;
import org.springframework.beans.factory.annotation.Autowired;
public class SupervisorServiceImpl implements SupervisorService {
@Autowired(required = true)
protected ItemService itemService;
@Autowired(required = true)
protected ResourcePolicyService resourcePolicyService;
protected SupervisorServiceImpl() {
}
@Override
public boolean isOrder(Context context, WorkspaceItem workspaceItem, Group group)
throws SQLException {
return workspaceItem.getSupervisorGroups().contains(group);
}
@Override
public void remove(Context context, WorkspaceItem workspaceItem, Group group)
throws SQLException, AuthorizeException {
// get the workspace item and the group from the request values
workspaceItem.getSupervisorGroups().remove(group);
// get the item and have it remove the policies for the group
Item item = workspaceItem.getItem();
itemService.removeGroupPolicies(context, item, group);
}
@Override
public void add(Context context, Group group, WorkspaceItem workspaceItem, int policy)
throws SQLException, AuthorizeException {
// make a table row in the database table, and update with the relevant
// details
workspaceItem.getSupervisorGroups().add(group);
group.getSupervisedItems().add(workspaceItem);
// If a default policy type has been requested, apply the policies using
// the DSpace API for doing so
if (policy != POLICY_NONE) {
Item item = workspaceItem.getItem();
// "Editor" implies READ, WRITE, ADD permissions
// "Observer" implies READ permissions
if (policy == POLICY_EDITOR) {
ResourcePolicy r = resourcePolicyService.create(context);
r.setdSpaceObject(item);
r.setGroup(group);
r.setAction(Constants.READ);
resourcePolicyService.update(context, r);
r = resourcePolicyService.create(context);
r.setdSpaceObject(item);
r.setGroup(group);
r.setAction(Constants.WRITE);
resourcePolicyService.update(context, r);
r = resourcePolicyService.create(context);
r.setdSpaceObject(item);
r.setGroup(group);
r.setAction(Constants.ADD);
resourcePolicyService.update(context, r);
} else if (policy == POLICY_OBSERVER) {
ResourcePolicy r = resourcePolicyService.create(context);
r.setdSpaceObject(item);
r.setGroup(group);
r.setAction(Constants.READ);
resourcePolicyService.update(context, r);
}
}
}
}

View File

@@ -12,7 +12,6 @@ import org.dspace.eperson.service.EPersonService;
import org.dspace.eperson.service.GroupService; import org.dspace.eperson.service.GroupService;
import org.dspace.eperson.service.RegistrationDataService; import org.dspace.eperson.service.RegistrationDataService;
import org.dspace.eperson.service.SubscribeService; import org.dspace.eperson.service.SubscribeService;
import org.dspace.eperson.service.SupervisorService;
import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.services.factory.DSpaceServicesFactory;
/** /**
@@ -33,8 +32,6 @@ public abstract class EPersonServiceFactory {
public abstract SubscribeService getSubscribeService(); public abstract SubscribeService getSubscribeService();
public abstract SupervisorService getSupervisorService();
public static EPersonServiceFactory getInstance() { public static EPersonServiceFactory getInstance() {
return DSpaceServicesFactory.getInstance().getServiceManager() return DSpaceServicesFactory.getInstance().getServiceManager()
.getServiceByName("ePersonServiceFactory", EPersonServiceFactory.class); .getServiceByName("ePersonServiceFactory", EPersonServiceFactory.class);

View File

@@ -12,7 +12,6 @@ import org.dspace.eperson.service.EPersonService;
import org.dspace.eperson.service.GroupService; import org.dspace.eperson.service.GroupService;
import org.dspace.eperson.service.RegistrationDataService; import org.dspace.eperson.service.RegistrationDataService;
import org.dspace.eperson.service.SubscribeService; import org.dspace.eperson.service.SubscribeService;
import org.dspace.eperson.service.SupervisorService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
/** /**
@@ -33,8 +32,6 @@ public class EPersonServiceFactoryImpl extends EPersonServiceFactory {
private AccountService accountService; private AccountService accountService;
@Autowired(required = true) @Autowired(required = true)
private SubscribeService subscribeService; private SubscribeService subscribeService;
@Autowired(required = true)
private SupervisorService supervisorService;
@Override @Override
public EPersonService getEPersonService() { public EPersonService getEPersonService() {
@@ -61,8 +58,4 @@ public class EPersonServiceFactoryImpl extends EPersonServiceFactory {
return subscribeService; return subscribeService;
} }
@Override
public SupervisorService getSupervisorService() {
return supervisorService;
}
} }

View File

@@ -1,83 +0,0 @@
/**
* 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.eperson.service;
import java.sql.SQLException;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.WorkspaceItem;
import org.dspace.core.Context;
import org.dspace.eperson.Group;
/**
* Class to represent the supervisor, primarily for use in applying supervisor
* activities to the database, such as setting and unsetting supervision
* orders and so forth.
*
* @author Richard Jones
* @version $Revision$
*/
public interface SupervisorService {
/**
* value to use for no policy set
*/
public static final int POLICY_NONE = 0;
/**
* value to use for editor policies
*/
public static final int POLICY_EDITOR = 1;
/**
* value to use for observer policies
*/
public static final int POLICY_OBSERVER = 2;
/**
* finds out if there is a supervision order that matches this set
* of values
*
* @param context the context this object exists in
* @param workspaceItem the workspace item to be supervised
* @param group the group to be doing the supervising
* @return boolean true if there is an order that matches, false if not
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
public boolean isOrder(Context context, WorkspaceItem workspaceItem, Group group)
throws SQLException;
/**
* removes the requested group from the requested workspace item in terms
* of supervision. This also removes all the policies that group has
* associated with the item
*
* @param context the context this object exists in
* @param workspaceItem the ID of the workspace item
* @param group the ID of the group to be removed from the item
* @throws SQLException An exception that provides information on a database access error or other errors.
* @throws AuthorizeException Exception indicating the current user of the context does not have permission
* to perform a particular action.
*/
public void remove(Context context, WorkspaceItem workspaceItem, Group group)
throws SQLException, AuthorizeException;
/**
* adds a supervision order to the database
*
* @param context the context this object exists in
* @param group the ID of the group which will supervise
* @param workspaceItem the ID of the workspace item to be supervised
* @param policy String containing the policy type to be used
* @throws SQLException An exception that provides information on a database access error or other errors.
* @throws AuthorizeException Exception indicating the current user of the context does not have permission
* to perform a particular action.
*/
public void add(Context context, Group group, WorkspaceItem workspaceItem, int policy)
throws SQLException, AuthorizeException;
}

View File

@@ -26,7 +26,25 @@ import org.dspace.supervision.SupervisionOrder;
*/ */
public interface SupervisionOrderDao extends GenericDAO<SupervisionOrder> { public interface SupervisionOrderDao extends GenericDAO<SupervisionOrder> {
/**
* find all Supervision Orders related to the item
*
* @param context The DSpace context
* @param item the item
* @return the Supervision Orders related to the item
* @throws SQLException If something goes wrong in the database
*/
List<SupervisionOrder> findByItem(Context context, Item item) throws SQLException; List<SupervisionOrder> findByItem(Context context, Item item) throws SQLException;
/**
* find the Supervision Order related to the item and group
*
* @param context The DSpace context
* @param item the item
* @param group the group
* @return the Supervision Order related to the item and group
* @throws SQLException If something goes wrong in the database
*/
SupervisionOrder findByItemAndGroup(Context context, Item item, Group group) throws SQLException; SupervisionOrder findByItemAndGroup(Context context, Item item, Group group) throws SQLException;
} }

View File

@@ -9,6 +9,12 @@ package org.dspace.supervision.enumeration;
/** /**
* This Enum holds a representation of all the possible supervision order types
* <p>
* OBSERVER: grant READ permission to the item
* EDITOR: grant READ and WRITE permissions to the item
* NONE: no grants
* </p>
* *
* @author Mohamed Eskander (mohamed.eskander at 4science dot it) * @author Mohamed Eskander (mohamed.eskander at 4science dot it)
*/ */

View File

@@ -24,9 +24,45 @@ import org.dspace.supervision.SupervisionOrder;
*/ */
public interface SupervisionOrderService extends DSpaceCRUDService<SupervisionOrder> { public interface SupervisionOrderService extends DSpaceCRUDService<SupervisionOrder> {
/**
* @param context The DSpace context
* @param item the item
* @param group the group
* @return the created Supervision Order on item and group
* @throws SQLException If something goes wrong in the database
*/
SupervisionOrder create(Context context, Item item, Group group) throws SQLException; SupervisionOrder create(Context context, Item item, Group group) throws SQLException;
/**
* @param context The DSpace context
* @return all Supervision Orders
* @throws SQLException If something goes wrong in the database
*/
List<SupervisionOrder> findAll(Context context) throws SQLException; List<SupervisionOrder> findAll(Context context) throws SQLException;
/**
* @param context The DSpace context
* @param item the item
* @return all Supervision Orders related to the item
* @throws SQLException If something goes wrong in the database
*/
List<SupervisionOrder> findByItem(Context context, Item item) throws SQLException; List<SupervisionOrder> findByItem(Context context, Item item) throws SQLException;
/**
* @param context The DSpace context
* @param item the item
* @param group the group
* @return the Supervision Order of the item and group
* @throws SQLException If something goes wrong in the database
*/
SupervisionOrder findByItemAndGroup(Context context, Item item, Group group) throws SQLException; SupervisionOrder findByItemAndGroup(Context context, Item item, Group group) throws SQLException;
/**
* @param context The DSpace context
* @param ePerson the ePerson to be checked
* @param item the item
* @return true if the ePerson is a supervisor of the item
* @throws SQLException If something goes wrong in the database
*/
boolean isSupervisor(Context context, EPerson ePerson, Item item) throws SQLException; boolean isSupervisor(Context context, EPerson ePerson, Item item) throws SQLException;
} }

View File

@@ -18,3 +18,61 @@ CREATE TABLE supervision_orders
); );
CREATE SEQUENCE supervision_orders_seq; CREATE SEQUENCE supervision_orders_seq;
INSERT INTO supervision_orders (id, item_id, eperson_group_id)
SELECT supervision_orders_seq.nextval AS id, w.item_id, e.uuid
FROM epersongroup2workspaceitem ew INNER JOIN workspaceitem w
ON ew.workspace_item_id = w.workspace_item_id
INNER JOIN epersongroup e
ON ew.eperson_group_id = e.uuid;
-- UPDATE policies for supervision orders
-- items, bundles and bitstreams
DECLARE
BEGIN
FOR rec IN
(
SELECT so.item_id as dspace_object, so.eperson_group_id, rp.resource_type_id
FROM supervision_orders so
INNER JOIN RESOURCEPOLICY rp on so.item_id = rp.dspace_object
AND so.eperson_group_id = rp.epersongroup_id
WHERE rp.rptype IS NULL
UNION
SELECT ib.bundle_id as dspace_object, so.eperson_group_id, rp.resource_type_id
FROM supervision_orders so
INNER JOIN item2bundle ib ON so.item_id = ib.item_id
INNER JOIN RESOURCEPOLICY rp on ib.bundle_id = rp.dspace_object
AND so.eperson_group_id = rp.epersongroup_id
WHERE rp.rptype IS NULL
UNION
SELECT bs.bitstream_id as dspace_object, so.eperson_group_id, rp.resource_type_id
FROM supervision_orders so
INNER JOIN item2bundle ib ON so.item_id = ib.item_id
INNER JOIN bundle2bitstream bs ON ib.bundle_id = bs.bundle_id
INNER JOIN RESOURCEPOLICY rp on bs.bitstream_id = rp.dspace_object
AND so.eperson_group_id = rp.epersongroup_id
WHERE rp.rptype IS NULL
)
LOOP
UPDATE RESOURCEPOLICY SET rptype = 'TYPE_SUBMISSION'
where dspace_object = rec.dspace_object
AND epersongroup_id = rec.eperson_group_id
AND rptype IS NULL;
END LOOP;
END;
-------------------------------------------------------------------------------
-- drop epersongroup2workspaceitem table
-------------------------------------------------------------------------------
DROP TABLE epersongroup2workspaceitem;

View File

@@ -18,3 +18,68 @@ CREATE TABLE supervision_orders
); );
CREATE SEQUENCE supervision_orders_seq; CREATE SEQUENCE supervision_orders_seq;
-------------------------------------------------------------------------------
-- migrate data from epersongroup2workspaceitem table
-------------------------------------------------------------------------------
INSERT INTO supervision_orders (id, item_id, eperson_group_id)
SELECT getnextid('supervision_orders') AS id, w.item_id, e.uuid
FROM epersongroup2workspaceitem ew INNER JOIN workspaceitem w
ON ew.workspace_item_id = w.workspace_item_id
INNER JOIN epersongroup e
ON ew.eperson_group_id = e.uuid;
-- UPDATE policies for supervision orders
-- items, bundles and bitstreams
do
$$
DECLARE
rec record;
BEGIN
FOR rec IN
SELECT so.item_id as dspace_object, so.eperson_group_id, rp.resource_type_id
FROM supervision_orders so
INNER JOIN RESOURCEPOLICY rp on so.item_id = rp.dspace_object
AND so.eperson_group_id = rp.epersongroup_id
WHERE rp.rptype IS NULL
UNION
SELECT ib.bundle_id as dspace_object, so.eperson_group_id, rp.resource_type_id
FROM supervision_orders so
INNER JOIN item2bundle ib ON so.item_id = ib.item_id
INNER JOIN RESOURCEPOLICY rp on ib.bundle_id = rp.dspace_object
AND so.eperson_group_id = rp.epersongroup_id
WHERE rp.rptype IS NULL
UNION
SELECT bs.bitstream_id as dspace_object, so.eperson_group_id, rp.resource_type_id
FROM supervision_orders so
INNER JOIN item2bundle ib ON so.item_id = ib.item_id
INNER JOIN bundle2bitstream bs ON ib.bundle_id = bs.bundle_id
INNER JOIN RESOURCEPOLICY rp on bs.bitstream_id = rp.dspace_object
AND so.eperson_group_id = rp.epersongroup_id
WHERE rp.rptype IS NULL
LOOP
UPDATE RESOURCEPOLICY SET rptype = 'TYPE_SUBMISSION'
where dspace_object = rec.dspace_object
AND epersongroup_id = rec.eperson_group_id
AND rptype IS NULL;
END LOOP;
END;
$$;
-------------------------------------------------------------------------------
-- drop epersongroup2workspaceitem table
-------------------------------------------------------------------------------
DROP TABLE epersongroup2workspaceitem;

View File

@@ -1,200 +0,0 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.content;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.UUID;
import org.apache.logging.log4j.Logger;
import org.dspace.AbstractUnitTest;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.CollectionService;
import org.dspace.content.service.CommunityService;
import org.dspace.content.service.SupervisedItemService;
import org.dspace.content.service.WorkspaceItemService;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
import org.dspace.eperson.factory.EPersonServiceFactory;
import org.dspace.eperson.service.EPersonService;
import org.dspace.eperson.service.GroupService;
import org.dspace.eperson.service.SupervisorService;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* @author pvillega
*/
public class SupervisedItemTest extends AbstractUnitTest {
/**
* log4j category
*/
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(SupervisedItemTest.class);
protected CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
protected CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
protected EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService();
protected GroupService groupService = EPersonServiceFactory.getInstance().getGroupService();
protected SupervisedItemService supervisedItemService = ContentServiceFactory.getInstance()
.getSupervisedItemService();
protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService();
protected SupervisorService supervisorService = EPersonServiceFactory.getInstance().getSupervisorService();
protected UUID communityId;
protected UUID groupId;
protected int workspaceItemId;
/**
* This method will be run before every test as per @Before. It will
* initialize resources required for the tests.
*
* Other methods can be annotated with @Before here or in subclasses
* but no execution order is guaranteed
*/
@Before
@Override
public void init() {
super.init();
try {
//we have to create a new community in the database
context.turnOffAuthorisationSystem();
Community owningCommunity = communityService.create(null, context);
Collection collection = collectionService.create(context, owningCommunity);
WorkspaceItem si = workspaceItemService.create(context, collection, false);
Group gr = groupService.create(context);
EPerson currentUser = context.getCurrentUser();
groupService.addMember(context, gr, currentUser);
groupService.update(context, gr);
//set a supervisor as editor
supervisorService.add(context, gr, si, 1);
communityId = owningCommunity.getID();
workspaceItemId = si.getID();
groupId = gr.getID();
//we need to commit the changes so we don't block the table for testing
context.restoreAuthSystemState();
context.complete();
context = new Context();
context.setCurrentUser(currentUser);
} catch (AuthorizeException ex) {
log.error("Authorization Error in init", ex);
fail("Authorization Error in init: " + ex.getMessage());
} catch (SQLException ex) {
log.error("SQL Error in init", ex);
fail("SQL Error in init");
}
}
/**
* This method will be run after every test as per @After. It will
* clean resources initialized by the @Before methods.
*
* Other methods can be annotated with @After here or in subclasses
* but no execution order is guaranteed
*/
@After
@Override
public void destroy() {
try {
context.turnOffAuthorisationSystem();
communityService.delete(context, communityService.find(context, communityId));
context.restoreAuthSystemState();
} catch (SQLException | AuthorizeException | IOException ex) {
log.error("SQL Error in destroy", ex);
fail("SQL Error in destroy: " + ex.getMessage());
}
super.destroy();
}
/**
* Test of getAll method, of class SupervisedItem.
*/
@Test
public void testGetAll() throws Exception {
List<WorkspaceItem> found = supervisedItemService.getAll(context);
assertThat("testGetAll 0", found, notNullValue());
assertTrue("testGetAll 1", found.size() >= 1);
boolean added = false;
for (WorkspaceItem sia : found) {
if (sia.getID() == workspaceItemId) {
added = true;
}
}
assertTrue("testGetAll 2", added);
}
/**
* Test of getSupervisorGroups method, of class SupervisedItem.
*/
@Test
public void testGetSupervisorGroups_Context_int() throws Exception {
List<Group> found = workspaceItemService.find(context, workspaceItemId).getSupervisorGroups();
assertThat("testGetSupervisorGroups_Context_int 0", found, notNullValue());
assertTrue("testGetSupervisorGroups_Context_int 1", found.size() == 1);
assertThat("testGetSupervisorGroups_Context_int 2", found.get(0).getID(), equalTo(groupId));
}
/**
* Test of getSupervisorGroups method, of class SupervisedItem.
*/
@Test
public void testGetSupervisorGroups_0args() throws Exception {
List<Group> found = workspaceItemService.find(context, workspaceItemId).getSupervisorGroups();
assertThat("testGetSupervisorGroups_0args 0", found, notNullValue());
assertTrue("testGetSupervisorGroups_0args 1", found.size() == 1);
boolean added = false;
for (Group g : found) {
if (g.getID().equals(groupId)) {
added = true;
}
}
assertTrue("testGetSupervisorGroups_0args 2", added);
}
/**
* Test of findbyEPerson method, of class SupervisedItem.
*/
@Test
public void testFindbyEPerson() throws Exception {
context.turnOffAuthorisationSystem();
List<WorkspaceItem> found = supervisedItemService.findbyEPerson(context, ePersonService.create(context));
assertThat("testFindbyEPerson 0", found, notNullValue());
assertTrue("testFindbyEPerson 1", found.size() == 0);
found = supervisedItemService.findbyEPerson(context, context.getCurrentUser());
assertThat("testFindbyEPerson 2", found, notNullValue());
assertTrue("testFindbyEPerson 3", found.size() >= 1);
boolean added = false;
for (WorkspaceItem sia : found) {
if (sia.getID() == workspaceItemId) {
added = true;
}
}
assertTrue("testFindbyEPerson 4", added);
context.restoreAuthSystemState();
}
}

View File

@@ -0,0 +1,385 @@
/**
* 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 static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import org.dspace.AbstractIntegrationTestWithDatabase;
import org.dspace.builder.CollectionBuilder;
import org.dspace.builder.CommunityBuilder;
import org.dspace.builder.EPersonBuilder;
import org.dspace.builder.GroupBuilder;
import org.dspace.builder.WorkspaceItemBuilder;
import org.dspace.content.Collection;
import org.dspace.content.Item;
import org.dspace.content.WorkspaceItem;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
import org.dspace.supervision.factory.SupervisionOrderServiceFactory;
import org.dspace.supervision.service.SupervisionOrderService;
import org.junit.Test;
/**
* Unit tests for the {@link SupervisionOrderService}
*
* @author Mohamed Eskander (mohamed.eskander at 4science dot it)
*/
public class SupervisionOrderServiceIT extends AbstractIntegrationTestWithDatabase {
protected SupervisionOrderService supervisionOrderService =
SupervisionOrderServiceFactory.getInstance().getSupervisionOrderService();
@Test
public void createSupervisionOrderTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity =
CommunityBuilder.createCommunity(context)
.withName("parent community")
.build();
Collection collection =
CollectionBuilder.createCollection(context, parentCommunity)
.withName("collection")
.withEntityType("Publication")
.build();
WorkspaceItem workspaceItem =
WorkspaceItemBuilder.createWorkspaceItem(context, collection)
.withTitle("workspace item")
.withIssueDate("2023-01-24")
.grantLicense()
.build();
Item item = workspaceItem.getItem();
EPerson userA =
EPersonBuilder.createEPerson(context)
.withCanLogin(true)
.withEmail("userA@example.org")
.build();
EPerson userB =
EPersonBuilder.createEPerson(context)
.withCanLogin(true)
.withEmail("userB@example.org")
.build();
Group groupA = GroupBuilder.createGroup(context)
.withName("group A")
.addMember(userA)
.build();
Group groupB = GroupBuilder.createGroup(context)
.withName("group B")
.addMember(userB)
.build();
SupervisionOrder supervisionOrderOne =
supervisionOrderService.create(context, item, groupA);
SupervisionOrder supervisionOrderTwo =
supervisionOrderService.create(context, item, groupB);
context.restoreAuthSystemState();
assertThat(supervisionOrderOne, notNullValue());
assertThat(supervisionOrderOne.getItem().getID(), is(item.getID()));
assertThat(supervisionOrderOne.getGroup().getID(), is(groupA.getID()));
assertThat(supervisionOrderTwo, notNullValue());
assertThat(supervisionOrderTwo.getItem().getID(), is(item.getID()));
assertThat(supervisionOrderTwo.getGroup().getID(), is(groupB.getID()));
}
@Test
public void findSupervisionOrderTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity =
CommunityBuilder.createCommunity(context)
.withName("parent community")
.build();
Collection collection =
CollectionBuilder.createCollection(context, parentCommunity)
.withName("collection")
.withEntityType("Publication")
.build();
WorkspaceItem workspaceItem =
WorkspaceItemBuilder.createWorkspaceItem(context, collection)
.withTitle("workspace item")
.withIssueDate("2023-01-24")
.grantLicense()
.build();
EPerson userA =
EPersonBuilder.createEPerson(context)
.withCanLogin(true)
.withEmail("userA@example.org")
.build();
Group groupA = GroupBuilder.createGroup(context)
.withName("group A")
.addMember(userA)
.build();
SupervisionOrder supervisionOrderOne =
supervisionOrderService.create(context, workspaceItem.getItem(), groupA);
context.restoreAuthSystemState();
SupervisionOrder supervisionOrder =
supervisionOrderService.find(context, supervisionOrderOne.getID());
assertThat(supervisionOrder, notNullValue());
assertThat(supervisionOrder.getID(), is(supervisionOrderOne.getID()));
assertThat(supervisionOrder.getGroup().getID(),
is(supervisionOrderOne.getGroup().getID()));
assertThat(supervisionOrder.getItem().getID(),
is(supervisionOrderOne.getItem().getID()));
}
@Test
public void findAllSupervisionOrdersTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity =
CommunityBuilder.createCommunity(context)
.withName("parent community")
.build();
Collection collection =
CollectionBuilder.createCollection(context, parentCommunity)
.withName("collection")
.withEntityType("Publication")
.build();
WorkspaceItem workspaceItem =
WorkspaceItemBuilder.createWorkspaceItem(context, collection)
.withTitle("workspace item")
.withIssueDate("2023-01-24")
.grantLicense()
.build();
WorkspaceItem workspaceItemTwo =
WorkspaceItemBuilder.createWorkspaceItem(context, collection)
.withTitle("workspace item two")
.withIssueDate("2023-01-25")
.grantLicense()
.build();
EPerson userA =
EPersonBuilder.createEPerson(context)
.withCanLogin(true)
.withEmail("userA@example.org")
.build();
EPerson userB =
EPersonBuilder.createEPerson(context)
.withCanLogin(true)
.withEmail("userB@example.org")
.build();
Group groupA = GroupBuilder.createGroup(context)
.withName("group A")
.addMember(userA)
.build();
Group groupB = GroupBuilder.createGroup(context)
.withName("group B")
.addMember(userB)
.build();
supervisionOrderService.create(context, workspaceItem.getItem(), groupA);
supervisionOrderService.create(context, workspaceItem.getItem(), groupB);
supervisionOrderService.create(context, workspaceItemTwo.getItem(), groupA);
context.restoreAuthSystemState();
assertThat(supervisionOrderService.findAll(context), hasSize(3));
}
@Test
public void findSupervisionOrderByItemTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity =
CommunityBuilder.createCommunity(context)
.withName("parent community")
.build();
Collection collection =
CollectionBuilder.createCollection(context, parentCommunity)
.withName("collection")
.withEntityType("Publication")
.build();
WorkspaceItem workspaceItem =
WorkspaceItemBuilder.createWorkspaceItem(context, collection)
.withTitle("workspace item")
.withIssueDate("2023-01-24")
.grantLicense()
.build();
WorkspaceItem workspaceItemTwo =
WorkspaceItemBuilder.createWorkspaceItem(context, collection)
.withTitle("workspace item two")
.withIssueDate("2023-01-25")
.grantLicense()
.build();
EPerson userA =
EPersonBuilder.createEPerson(context)
.withCanLogin(true)
.withEmail("userA@example.org")
.build();
Group groupA = GroupBuilder.createGroup(context)
.withName("group A")
.addMember(userA)
.build();
Group groupB = GroupBuilder.createGroup(context)
.withName("group B")
.addMember(eperson)
.build();
supervisionOrderService.create(context, workspaceItem.getItem(), groupA);
supervisionOrderService.create(context, workspaceItem.getItem(), groupB);
supervisionOrderService.create(context, workspaceItemTwo.getItem(), groupA);
context.restoreAuthSystemState();
assertThat(supervisionOrderService.findByItem(context, workspaceItem.getItem()), hasSize(2));
assertThat(supervisionOrderService.findByItem(context, workspaceItemTwo.getItem()), hasSize(1));
}
@Test
public void findSupervisionOrderByItemAndGroupTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity =
CommunityBuilder.createCommunity(context)
.withName("parent community")
.build();
Collection collection =
CollectionBuilder.createCollection(context, parentCommunity)
.withName("collection")
.withEntityType("Publication")
.build();
WorkspaceItem workspaceItem =
WorkspaceItemBuilder.createWorkspaceItem(context, collection)
.withTitle("workspace item")
.withIssueDate("2023-01-24")
.grantLicense()
.build();
Item item = workspaceItem.getItem();
EPerson userA =
EPersonBuilder.createEPerson(context)
.withCanLogin(true)
.withEmail("userA@example.org")
.build();
Group groupA = GroupBuilder.createGroup(context)
.withName("group A")
.addMember(userA)
.build();
Group groupB = GroupBuilder.createGroup(context)
.withName("group B")
.addMember(eperson)
.build();
supervisionOrderService.create(context, item, groupA);
context.restoreAuthSystemState();
SupervisionOrder supervisionOrderA =
supervisionOrderService.findByItemAndGroup(context, item, groupA);
assertThat(supervisionOrderA, notNullValue());
assertThat(supervisionOrderA.getItem().getID(), is(item.getID()));
assertThat(supervisionOrderA.getGroup().getID(), is(groupA.getID()));
// no supervision order on item and groupB
assertThat(supervisionOrderService.findByItemAndGroup(context, item, groupB), nullValue());
}
@Test
public void isSupervisorTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity =
CommunityBuilder.createCommunity(context)
.withName("parent community")
.build();
Collection collection =
CollectionBuilder.createCollection(context, parentCommunity)
.withName("collection")
.withEntityType("Publication")
.build();
WorkspaceItem workspaceItem =
WorkspaceItemBuilder.createWorkspaceItem(context, collection)
.withTitle("workspace item")
.withIssueDate("2023-01-24")
.grantLicense()
.build();
EPerson userA =
EPersonBuilder.createEPerson(context)
.withCanLogin(true)
.withEmail("userA@example.org")
.build();
EPerson userB =
EPersonBuilder.createEPerson(context)
.withCanLogin(true)
.withEmail("userB@example.org")
.build();
Group groupA = GroupBuilder.createGroup(context)
.withName("group A")
.addMember(userA)
.build();
GroupBuilder.createGroup(context)
.withName("group B")
.addMember(userB)
.build();
supervisionOrderService.create(context, workspaceItem.getItem(), groupA);
context.restoreAuthSystemState();
assertThat(supervisionOrderService.isSupervisor(
context, userA, workspaceItem.getItem()), is(true));
// userB is not a supervisor on workspace Item
assertThat(supervisionOrderService.isSupervisor(
context, userB, workspaceItem.getItem()), is(false));
}
}

View File

@@ -22,19 +22,13 @@ 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;
@@ -66,13 +60,6 @@ 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.
*/ */
@@ -248,12 +235,6 @@ 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

View File

@@ -19,7 +19,7 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.dspace.app.exception.ResourceConflictException; import org.dspace.app.exception.ResourceAlreadyExistsException;
import org.dspace.app.rest.Parameter; import org.dspace.app.rest.Parameter;
import org.dspace.app.rest.SearchRestMethod; import org.dspace.app.rest.SearchRestMethod;
import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.converter.ConverterService;
@@ -116,6 +116,10 @@ public class SupervisionOrderRestRepository extends DSpaceRestRepository<Supervi
throw new UnprocessableEntityException("Item with uuid: " + itemId + " not found"); throw new UnprocessableEntityException("Item with uuid: " + itemId + " not found");
} }
if (item.isArchived()) {
throw new UnprocessableEntityException("An archived Item with uuid: " + itemId + " can't be supervised");
}
Group group = groupService.find(context, UUID.fromString(groupId)); Group group = groupService.find(context, UUID.fromString(groupId));
if (group == null) { if (group == null) {
throw new UnprocessableEntityException("Group with uuid: " + groupId + " not found"); throw new UnprocessableEntityException("Group with uuid: " + groupId + " not found");
@@ -123,10 +127,8 @@ public class SupervisionOrderRestRepository extends DSpaceRestRepository<Supervi
supervisionOrder = supervisionOrderService.findByItemAndGroup(context, item, group); supervisionOrder = supervisionOrderService.findByItemAndGroup(context, item, group);
if (Objects.nonNull(supervisionOrder)) { if (Objects.nonNull(supervisionOrder)) {
throw new ResourceConflictException( throw new ResourceAlreadyExistsException(
"There is a conflict supervision order with itemId <" + itemId + "> and groupId <" + groupId + ">", "A supervision order already exists with itemId <" + itemId + "> and groupId <" + groupId + ">");
supervisionOrder
);
} }
supervisionOrder = supervisionOrderService.create(context, item, group); supervisionOrder = supervisionOrderService.create(context, item, group);
addGroupPoliciesToItem(context, item, group, type); addGroupPoliciesToItem(context, item, group, type);

View File

@@ -7,7 +7,6 @@
*/ */
package org.dspace.app.rest; package org.dspace.app.rest;
import static com.jayway.jsonpath.JsonPath.read; 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.dspace.app.rest.matcher.SupervisionOrderMatcher.matchSuperVisionOrder;
import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsInAnyOrder;
@@ -20,13 +19,14 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.io.InputStream;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.dspace.app.rest.model.patch.AddOperation; import org.dspace.app.rest.matcher.WorkspaceItemMatcher;
import org.dspace.app.rest.model.patch.ReplaceOperation; import org.dspace.app.rest.model.patch.ReplaceOperation;
import org.dspace.app.rest.repository.SupervisionOrderRestRepository; import org.dspace.app.rest.repository.SupervisionOrderRestRepository;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
@@ -40,6 +40,7 @@ import org.dspace.builder.WorkspaceItemBuilder;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.content.WorkspaceItem; import org.dspace.content.WorkspaceItem;
import org.dspace.content.service.InstallItemService;
import org.dspace.eperson.EPerson; import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group; import org.dspace.eperson.Group;
import org.dspace.supervision.SupervisionOrder; import org.dspace.supervision.SupervisionOrder;
@@ -59,6 +60,9 @@ public class SupervisionOrderRestRepositoryIT extends AbstractControllerIntegrat
@Autowired @Autowired
private SupervisionOrderService supervisionOrderService; private SupervisionOrderService supervisionOrderService;
@Autowired
private InstallItemService installItemService;
@Test @Test
public void findAllByAnonymousUserTest() throws Exception { public void findAllByAnonymousUserTest() throws Exception {
getClient().perform(get("/api/core/supervisionorders/")) getClient().perform(get("/api/core/supervisionorders/"))
@@ -667,11 +671,15 @@ public class SupervisionOrderRestRepositoryIT extends AbstractControllerIntegrat
.withName("Collection 1") .withName("Collection 1")
.build(); .build();
Item itemOne = WorkspaceItem workspaceItem =
ItemBuilder.createItem(context, col1) WorkspaceItemBuilder.createWorkspaceItem(context, col1)
.withTitle("item title") .withTitle("Workspace Item 1")
.withIssueDate("2017-10-17") .withIssueDate("2017-10-17")
.build(); .withSubject("ExtraEntry")
.grantLicense()
.build();
Item itemOne = workspaceItem.getItem();
Group groupA = Group groupA =
GroupBuilder.createGroup(context) GroupBuilder.createGroup(context)
@@ -695,7 +703,47 @@ public class SupervisionOrderRestRepositoryIT extends AbstractControllerIntegrat
.param("group", groupA.getID().toString()) .param("group", groupA.getID().toString())
.param("type", "OBSERVER") .param("type", "OBSERVER")
.contentType(contentType)) .contentType(contentType))
.andExpect(status().isConflict()); .andExpect(status().isUnprocessableEntity());
}
@Test
public void createSupervisionOrderOnArchivedItemTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity =
CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Collection col1 =
CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1")
.build();
// create archived item
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", "OBSERVER")
.contentType(contentType))
.andExpect(status().isUnprocessableEntity());
} }
@Test @Test
@@ -722,16 +770,24 @@ public class SupervisionOrderRestRepositoryIT extends AbstractControllerIntegrat
.withName("Parent Community") .withName("Parent Community")
.build(); .build();
Collection col1 = Collection publications =
CollectionBuilder.createCollection(context, parentCommunity) CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1") .withName("Publications")
.withEntityType("Publication")
.build(); .build();
Item itemOne = InputStream pdf = getClass().getResourceAsStream("simple-article.pdf");
ItemBuilder.createItem(context, col1)
.withTitle("item title") WorkspaceItem witem =
.withIssueDate("2017-10-17") WorkspaceItemBuilder.createWorkspaceItem(context, publications)
.build(); .withTitle("Workspace Item 1")
.withIssueDate("2017-10-17")
.withSubject("ExtraEntry")
.withFulltext("simple-article.pdf", "/local/path/simple-article.pdf", pdf)
.grantLicense()
.build();
Item itemOne = witem.getItem();
Group groupA = Group groupA =
GroupBuilder.createGroup(context) GroupBuilder.createGroup(context)
@@ -790,21 +846,38 @@ public class SupervisionOrderRestRepositoryIT extends AbstractControllerIntegrat
String authTokenB = getAuthToken(userB.getEmail(), password); String authTokenB = getAuthToken(userB.getEmail(), password);
String patchBody = getPatchContent(List.of( String patchBody = getPatchContent(List.of(
new AddOperation("/metadata/dc.title", List.of(Map.of("value", "new title"))) new ReplaceOperation("/sections/traditionalpageone/dc.title/0", Map.of("value", "New Title"))
)); ));
// update title of itemOne by userA is Ok // update title of workspace item by userA is Ok
getClient(authTokenA).perform(patch("/api/core/items/" + itemOne.getID()) getClient(authTokenA).perform(patch("/api/submission/workspaceitems/" + witem.getID())
.content(patchBody) .content(patchBody)
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$", is( .andExpect(jsonPath("$.errors").doesNotExist())
matchItemWithTitleAndDateIssued(context.reloadEntity(itemOne), .andExpect(jsonPath("$",
"new title", "2017-10-17") // check the new title and untouched values
))); Matchers.is(WorkspaceItemMatcher
.matchItemWithTitleAndDateIssuedAndSubject(
witem,
"New Title", "2017-10-17",
"ExtraEntry"))));
// update title of itemOne by userB is Forbidden getClient(authTokenA).perform(get("/api/submission/workspaceitems/" + witem.getID()))
getClient(authTokenB).perform(patch("/api/core/items/" + itemOne.getID()) .andExpect(status().isOk())
.andExpect(jsonPath("$.errors").doesNotExist())
.andExpect(jsonPath("$",
Matchers.is(
WorkspaceItemMatcher
.matchItemWithTitleAndDateIssuedAndSubject(
witem,
"New Title", "2017-10-17",
"ExtraEntry")
)));
// update title of workspace item by userB is Forbidden
getClient(authTokenB).perform(patch("/api/submission/workspaceitems/" + witem.getID())
.content(patchBody) .content(patchBody)
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isForbidden()); .andExpect(status().isForbidden());
@@ -1085,4 +1158,89 @@ public class SupervisionOrderRestRepositoryIT extends AbstractControllerIntegrat
} }
@Test
public void installWorkspaceItemThenSupervisionOrderBeDeletedTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity =
CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Collection publications =
CollectionBuilder.createCollection(context, parentCommunity)
.withName("Publications")
.withEntityType("Publication")
.build();
EPerson userA =
EPersonBuilder.createEPerson(context)
.withCanLogin(true)
.withEmail("test1@email.com")
.withPassword(password)
.build();
Group groupA =
GroupBuilder.createGroup(context)
.withName("group A")
.addMember(userA)
.build();
Group groupB =
GroupBuilder.createGroup(context)
.withName("group B")
.addMember(eperson)
.build();
WorkspaceItem witem =
WorkspaceItemBuilder.createWorkspaceItem(context, publications)
.withTitle("Workspace Item 1")
.withIssueDate("2017-10-17")
.withSubject("ExtraEntry")
.grantLicense()
.build();
context.restoreAuthSystemState();
AtomicReference<Integer> idRefOne = new AtomicReference<>();
AtomicReference<Integer> idRefTwo = new AtomicReference<>();
String adminToken = getAuthToken(admin.getEmail(), password);
getClient(adminToken).perform(post("/api/core/supervisionorders/")
.param("uuid", witem.getItem().getID().toString())
.param("group", groupA.getID().toString())
.param("type", "EDITOR")
.contentType(contentType))
.andExpect(status().isCreated())
.andDo(result -> idRefOne
.set(read(result.getResponse().getContentAsString(), "$.id")));
getClient(adminToken).perform(post("/api/core/supervisionorders/")
.param("uuid", witem.getItem().getID().toString())
.param("group", groupB.getID().toString())
.param("type", "EDITOR")
.contentType(contentType))
.andExpect(status().isCreated())
.andDo(result -> idRefTwo
.set(read(result.getResponse().getContentAsString(), "$.id")));
getClient(adminToken).perform(get("/api/core/supervisionorders/" + idRefOne.get()))
.andExpect(status().isOk());
getClient(adminToken).perform(get("/api/core/supervisionorders/" + idRefTwo.get()))
.andExpect(status().isOk());
// install item then supervision orders will be deleted
context.turnOffAuthorisationSystem();
installItemService.installItem(context, context.reloadEntity(witem));
context.restoreAuthSystemState();
getClient(adminToken).perform(get("/api/core/supervisionorders/" + idRefOne.get()))
.andExpect(status().isNotFound());
getClient(adminToken).perform(get("/api/core/supervisionorders/" + idRefTwo.get()))
.andExpect(status().isNotFound());
}
} }

View File

@@ -2126,70 +2126,141 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT
} }
@Test @Test
public void testSupervisorFindOne() throws Exception { public void createSupervisionOnWorkspaceThenSubmitToBeWorkflowTest() throws Exception {
context.turnOffAuthorisationSystem(); 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 = parentCommunity =
CommunityBuilder.createCommunity(context) CommunityBuilder.createCommunity(context)
.withName("Parent Community") .withName("Parent Community")
.build(); .build();
Community child1 = EPerson reviewer =
CommunityBuilder.createSubCommunity(context, parentCommunity) EPersonBuilder.createEPerson(context)
.withName("Sub Community") .withEmail("reviewer1@example.com")
.build(); .withPassword(password)
.build();
Collection collection = Collection collection =
CollectionBuilder.createCollection(context, child1) CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1") .withName("Collection 1")
.withWorkflowGroup(1, admin) .withWorkflowGroup("reviewer", reviewer)
.build(); .build();
Group group = EPerson userA =
EPersonBuilder.createEPerson(context)
.withCanLogin(true)
.withEmail("userA@test.com")
.withPassword(password)
.build();
Group groupA =
GroupBuilder.createGroup(context) GroupBuilder.createGroup(context)
.withName("group A") .withName("group A")
.addMember(user) .addMember(userA)
.build(); .build();
XmlWorkflowItem workflowItem = InputStream pdf = getClass().getResourceAsStream("simple-article.pdf");
WorkflowItemBuilder.createWorkflowItem(context, collection)
.withSubmitter(admin) WorkspaceItem witem =
.withTitle("Workflow Item") WorkspaceItemBuilder.createWorkspaceItem(context, collection)
.withIssueDate("2017-10-17") .withTitle("Workspace Item 1")
.withAuthor("Author one") .withIssueDate("2017-10-17")
.build(); .withSubject("ExtraEntry")
.withFulltext("simple-article.pdf", "/local/path/simple-article.pdf", pdf)
.grantLicense()
.build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
// create a supervision order on workspaceItem to groupA
getClient(getAuthToken(admin.getEmail(), password)) getClient(getAuthToken(admin.getEmail(), password))
.perform(post("/api/core/supervisionorders/") .perform(post("/api/core/supervisionorders/")
.param("uuid", workflowItem.getItem().getID().toString()) .param("uuid", witem.getItem().getID().toString())
.param("group", group.getID().toString()) .param("group", groupA.getID().toString())
.param("type", "EDITOR") .param("type", "EDITOR")
.contentType(contentType)) .contentType(contentType))
.andExpect(status().isCreated()); .andExpect(status().isCreated());
getClient(getAuthToken(anotherUser.getEmail(), password)) String authTokenA = getAuthToken(userA.getEmail(), password);
.perform(get("/api/workflow/workflowitems/" + workflowItem.getID()))
.andExpect(status().isForbidden());
getClient(getAuthToken(user.getEmail(), password)) // a simple patch to update an existent metadata
.perform(get("/api/workflow/workflowitems/" + workflowItem.getID())) String patchBody =
.andExpect(status().isOk()); getPatchContent(List.of(
new ReplaceOperation("/sections/traditionalpageone/dc.title/0", Map.of("value", "New Title"))
));
// supervisor update the title of the workspaceItem
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"
))));
// supervisor check that title has been updated
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"
))));
AtomicReference<Integer> idRef = new AtomicReference<Integer>();
try {
String adminToken = getAuthToken(admin.getEmail(), password);
String reviewerToken = getAuthToken(reviewer.getEmail(), password);
// submit the workspaceitem to start the workflow
getClient(adminToken).perform(post(BASE_REST_SERVER_URL + "/api/workflow/workflowitems")
.content("/api/submission/workspaceitems/" + witem.getID())
.contentType(textUriContentType))
.andExpect(status().isCreated())
.andDo(result ->
idRef.set(read(result.getResponse().getContentAsString(), "$.id")));
// supervisor can read the workflowitem
getClient(authTokenA)
.perform(get("/api/workflow/workflowitems/" + idRef.get()))
.andExpect(status().isOk())
.andExpect(jsonPath("$",Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssued(
null, "New Title", "2017-10-17"))))
.andExpect(jsonPath("$.sections.defaultAC.discoverable", is(true)));
// reviewer can read the workflowitem
getClient(reviewerToken)
.perform(get("/api/workflow/workflowitems/" + idRef.get()))
.andExpect(status().isOk())
.andExpect(jsonPath("$",Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssued(
null, "New Title", "2017-10-17"))))
.andExpect(jsonPath("$.sections.defaultAC.discoverable", is(true)));
// a simple patch to update an existent metadata
String patchBodyTwo =
getPatchContent(List.of(new ReplaceOperation("/metadata/dc.title", Map.of("value", "edited title"))));
// supervisor can't edit item in workflow
getClient(authTokenA).perform(patch("/api/core/items/" + witem.getItem().getID())
.content(patchBodyTwo)
.contentType(contentType))
.andExpect(status().isForbidden());
// supervisor can't edit the workflow item
getClient(authTokenA).perform(patch("/api/workflow/workflowitems/" + idRef.get())
.content(patchBody)
.contentType(contentType))
.andExpect(status().isUnprocessableEntity());
} finally {
if (idRef.get() != null) {
WorkflowItemBuilder.deleteWorkflowItem(idRef.get());
}
}
} }
} }

View File

@@ -48,7 +48,6 @@
<bean class="org.dspace.content.MetadataSchemaServiceImpl"/> <bean class="org.dspace.content.MetadataSchemaServiceImpl"/>
<bean class="org.dspace.content.MetadataValueServiceImpl"/> <bean class="org.dspace.content.MetadataValueServiceImpl"/>
<bean class="org.dspace.content.SiteServiceImpl"/> <bean class="org.dspace.content.SiteServiceImpl"/>
<bean class="org.dspace.content.SupervisedItemServiceImpl"/>
<bean class="org.dspace.content.WorkspaceItemServiceImpl"/> <bean class="org.dspace.content.WorkspaceItemServiceImpl"/>
<bean class="org.dspace.content.RelationshipServiceImpl"/> <bean class="org.dspace.content.RelationshipServiceImpl"/>
<bean class="org.dspace.content.EntityTypeServiceImpl"/> <bean class="org.dspace.content.EntityTypeServiceImpl"/>
@@ -101,7 +100,6 @@
<bean class="org.dspace.eperson.GroupServiceImpl"/> <bean class="org.dspace.eperson.GroupServiceImpl"/>
<bean class="org.dspace.eperson.RegistrationDataServiceImpl"/> <bean class="org.dspace.eperson.RegistrationDataServiceImpl"/>
<bean class="org.dspace.eperson.SubscribeServiceImpl"/> <bean class="org.dspace.eperson.SubscribeServiceImpl"/>
<bean class="org.dspace.eperson.SupervisorServiceImpl"/>
<bean class="org.dspace.eperson.CaptchaServiceImpl"/> <bean class="org.dspace.eperson.CaptchaServiceImpl"/>
<bean class="org.dspace.event.EventServiceImpl"/> <bean class="org.dspace.event.EventServiceImpl"/>

View File

@@ -64,7 +64,7 @@
<!-- 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" /> <entry key="supervisedWorkspace" value-ref="supervisedWorkspaceConfiguration" />
<!-- "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 -->
@@ -902,10 +902,10 @@
</bean> </bean>
<!--The other workspace configuration settings for discovery --> <!--The other workspace configuration settings for discovery -->
<bean id="otherWorkspaceConfiguration" <bean id="supervisedWorkspaceConfiguration"
class="org.dspace.discovery.configuration.DiscoveryConfiguration" class="org.dspace.discovery.configuration.DiscoveryConfiguration"
scope="prototype"> scope="prototype">
<property name="id" value="otherworkspace" /> <property name="id" value="supervisedWorkspace" />
<!--Which sidebar facets are to be displayed --> <!--Which sidebar facets are to be displayed -->
<property name="sidebarFacets"> <property name="sidebarFacets">
<list> <list>