mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 18:14:26 +00:00
Merge pull request #3046 from 4Science/CSTPER-221
Metadata identifier for Communities and Collections
This commit is contained in:
@@ -55,6 +55,8 @@ import org.dspace.eperson.service.SubscribeService;
|
|||||||
import org.dspace.event.Event;
|
import org.dspace.event.Event;
|
||||||
import org.dspace.harvest.HarvestedCollection;
|
import org.dspace.harvest.HarvestedCollection;
|
||||||
import org.dspace.harvest.service.HarvestedCollectionService;
|
import org.dspace.harvest.service.HarvestedCollectionService;
|
||||||
|
import org.dspace.identifier.IdentifierException;
|
||||||
|
import org.dspace.identifier.service.IdentifierService;
|
||||||
import org.dspace.workflow.factory.WorkflowServiceFactory;
|
import org.dspace.workflow.factory.WorkflowServiceFactory;
|
||||||
import org.dspace.xmlworkflow.WorkflowConfigurationException;
|
import org.dspace.xmlworkflow.WorkflowConfigurationException;
|
||||||
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
|
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
|
||||||
@@ -92,6 +94,8 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
|||||||
protected CommunityService communityService;
|
protected CommunityService communityService;
|
||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
protected GroupService groupService;
|
protected GroupService groupService;
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected IdentifierService identifierService;
|
||||||
|
|
||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
protected LicenseService licenseService;
|
protected LicenseService licenseService;
|
||||||
@@ -131,13 +135,6 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
|||||||
//Add our newly created collection to our community, authorization checks occur in THIS method
|
//Add our newly created collection to our community, authorization checks occur in THIS method
|
||||||
communityService.addCollection(context, community, newCollection);
|
communityService.addCollection(context, community, newCollection);
|
||||||
|
|
||||||
//Update our community so we have a collection identifier
|
|
||||||
if (handle == null) {
|
|
||||||
handleService.createHandle(context, newCollection);
|
|
||||||
} else {
|
|
||||||
handleService.createHandle(context, newCollection, handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the default authorization policy for collections
|
// create the default authorization policy for collections
|
||||||
// of 'anonymous' READ
|
// of 'anonymous' READ
|
||||||
Group anonymousGroup = groupService.findByName(context, Group.ANONYMOUS);
|
Group anonymousGroup = groupService.findByName(context, Group.ANONYMOUS);
|
||||||
@@ -150,6 +147,18 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
|||||||
authorizeService
|
authorizeService
|
||||||
.createResourcePolicy(context, newCollection, anonymousGroup, null, Constants.DEFAULT_BITSTREAM_READ, null);
|
.createResourcePolicy(context, newCollection, anonymousGroup, null, Constants.DEFAULT_BITSTREAM_READ, null);
|
||||||
|
|
||||||
|
collectionDAO.save(context, newCollection);
|
||||||
|
|
||||||
|
//Update our collection so we have a collection identifier
|
||||||
|
try {
|
||||||
|
if (handle == null) {
|
||||||
|
identifierService.register(context, newCollection);
|
||||||
|
} else {
|
||||||
|
identifierService.register(context, newCollection, handle);
|
||||||
|
}
|
||||||
|
} catch (IllegalStateException | IdentifierException ex) {
|
||||||
|
throw new IllegalStateException(ex);
|
||||||
|
}
|
||||||
|
|
||||||
context.addEvent(new Event(Event.CREATE, Constants.COLLECTION,
|
context.addEvent(new Event(Event.CREATE, Constants.COLLECTION,
|
||||||
newCollection.getID(), newCollection.getHandle(),
|
newCollection.getID(), newCollection.getHandle(),
|
||||||
@@ -159,7 +168,6 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
|||||||
"collection_id=" + newCollection.getID())
|
"collection_id=" + newCollection.getID())
|
||||||
+ ",handle=" + newCollection.getHandle());
|
+ ",handle=" + newCollection.getHandle());
|
||||||
|
|
||||||
collectionDAO.save(context, newCollection);
|
|
||||||
return newCollection;
|
return newCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -37,6 +37,8 @@ import org.dspace.core.LogManager;
|
|||||||
import org.dspace.eperson.Group;
|
import org.dspace.eperson.Group;
|
||||||
import org.dspace.eperson.service.GroupService;
|
import org.dspace.eperson.service.GroupService;
|
||||||
import org.dspace.event.Event;
|
import org.dspace.event.Event;
|
||||||
|
import org.dspace.identifier.IdentifierException;
|
||||||
|
import org.dspace.identifier.service.IdentifierService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,6 +71,8 @@ public class CommunityServiceImpl extends DSpaceObjectServiceImpl<Community> imp
|
|||||||
protected BitstreamService bitstreamService;
|
protected BitstreamService bitstreamService;
|
||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
protected SiteService siteService;
|
protected SiteService siteService;
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected IdentifierService identifierService;
|
||||||
|
|
||||||
protected CommunityServiceImpl() {
|
protected CommunityServiceImpl() {
|
||||||
super();
|
super();
|
||||||
@@ -90,17 +94,6 @@ public class CommunityServiceImpl extends DSpaceObjectServiceImpl<Community> imp
|
|||||||
|
|
||||||
Community newCommunity = communityDAO.create(context, new Community());
|
Community newCommunity = communityDAO.create(context, new Community());
|
||||||
|
|
||||||
try {
|
|
||||||
if (handle == null) {
|
|
||||||
handleService.createHandle(context, newCommunity);
|
|
||||||
} else {
|
|
||||||
handleService.createHandle(context, newCommunity, handle);
|
|
||||||
}
|
|
||||||
} catch (IllegalStateException ie) {
|
|
||||||
//If an IllegalStateException is thrown, then an existing object is already using this handle
|
|
||||||
throw ie;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
parent.addSubCommunity(newCommunity);
|
parent.addSubCommunity(newCommunity);
|
||||||
newCommunity.addParentCommunity(parent);
|
newCommunity.addParentCommunity(parent);
|
||||||
@@ -115,14 +108,24 @@ public class CommunityServiceImpl extends DSpaceObjectServiceImpl<Community> imp
|
|||||||
|
|
||||||
communityDAO.save(context, newCommunity);
|
communityDAO.save(context, newCommunity);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (handle == null) {
|
||||||
|
identifierService.register(context, newCommunity);
|
||||||
|
} else {
|
||||||
|
identifierService.register(context, newCommunity, handle);
|
||||||
|
}
|
||||||
|
} catch (IllegalStateException | IdentifierException ex) {
|
||||||
|
throw new IllegalStateException(ex);
|
||||||
|
}
|
||||||
|
|
||||||
context.addEvent(new Event(Event.CREATE, Constants.COMMUNITY, newCommunity.getID(), newCommunity.getHandle(),
|
context.addEvent(new Event(Event.CREATE, Constants.COMMUNITY, newCommunity.getID(), newCommunity.getHandle(),
|
||||||
getIdentifiers(context, newCommunity)));
|
getIdentifiers(context, newCommunity)));
|
||||||
|
|
||||||
// if creating a top-level Community, simulate an ADD event at the Site.
|
// if creating a top-level Community, simulate an ADD event at the Site.
|
||||||
if (parent == null) {
|
if (parent == null) {
|
||||||
context.addEvent(new Event(Event.ADD, Constants.SITE, siteService.findSite(context).getID(),
|
context.addEvent(new Event(Event.ADD, Constants.SITE, siteService.findSite(context).getID(),
|
||||||
Constants.COMMUNITY, newCommunity.getID(), newCommunity.getHandle(),
|
Constants.COMMUNITY, newCommunity.getID(), newCommunity.getHandle(),
|
||||||
getIdentifiers(context, newCommunity)));
|
getIdentifiers(context, newCommunity)));
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info(LogManager.getHeader(context, "create_community",
|
log.info(LogManager.getHeader(context, "create_community",
|
||||||
|
@@ -169,6 +169,10 @@ public class DOIIdentifierProvider
|
|||||||
@Override
|
@Override
|
||||||
public String register(Context context, DSpaceObject dso)
|
public String register(Context context, DSpaceObject dso)
|
||||||
throws IdentifierException {
|
throws IdentifierException {
|
||||||
|
if (!(dso instanceof Item)) {
|
||||||
|
// DOI are currently assigned only to Item
|
||||||
|
return null;
|
||||||
|
}
|
||||||
String doi = mint(context, dso);
|
String doi = mint(context, dso);
|
||||||
// register tries to reserve doi if it's not already.
|
// register tries to reserve doi if it's not already.
|
||||||
// So we don't have to reserve it here.
|
// So we don't have to reserve it here.
|
||||||
@@ -179,6 +183,10 @@ public class DOIIdentifierProvider
|
|||||||
@Override
|
@Override
|
||||||
public void register(Context context, DSpaceObject dso, String identifier)
|
public void register(Context context, DSpaceObject dso, String identifier)
|
||||||
throws IdentifierException {
|
throws IdentifierException {
|
||||||
|
if (!(dso instanceof Item)) {
|
||||||
|
// DOI are currently assigned only to Item
|
||||||
|
return;
|
||||||
|
}
|
||||||
String doi = doiService.formatIdentifier(identifier);
|
String doi = doiService.formatIdentifier(identifier);
|
||||||
DOI doiRow = null;
|
DOI doiRow = null;
|
||||||
|
|
||||||
|
@@ -148,6 +148,10 @@ public class EZIDIdentifierProvider
|
|||||||
throws IdentifierException {
|
throws IdentifierException {
|
||||||
log.debug("register {}", dso);
|
log.debug("register {}", dso);
|
||||||
|
|
||||||
|
if (!(dso instanceof Item)) {
|
||||||
|
// DOI are currently assigned only to Item
|
||||||
|
return null;
|
||||||
|
}
|
||||||
DSpaceObjectService<DSpaceObject> dsoService = contentServiceFactory.getDSpaceObjectService(dso);
|
DSpaceObjectService<DSpaceObject> dsoService = contentServiceFactory.getDSpaceObjectService(dso);
|
||||||
List<MetadataValue> identifiers = dsoService.getMetadata(dso, MD_SCHEMA, DOI_ELEMENT, DOI_QUALIFIER, null);
|
List<MetadataValue> identifiers = dsoService.getMetadata(dso, MD_SCHEMA, DOI_ELEMENT, DOI_QUALIFIER, null);
|
||||||
for (MetadataValue identifier : identifiers) {
|
for (MetadataValue identifier : identifiers) {
|
||||||
@@ -171,6 +175,10 @@ public class EZIDIdentifierProvider
|
|||||||
public void register(Context context, DSpaceObject object, String identifier) {
|
public void register(Context context, DSpaceObject object, String identifier) {
|
||||||
log.debug("register {} as {}", object, identifier);
|
log.debug("register {} as {}", object, identifier);
|
||||||
|
|
||||||
|
if (!(object instanceof Item)) {
|
||||||
|
// DOI are currently assigned only to Item
|
||||||
|
return;
|
||||||
|
}
|
||||||
EZIDResponse response;
|
EZIDResponse response;
|
||||||
try {
|
try {
|
||||||
EZIDRequest request = requestFactory.getInstance(loadAuthority(),
|
EZIDRequest request = requestFactory.getInstance(loadAuthority(),
|
||||||
|
@@ -13,11 +13,14 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.content.Community;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.MetadataSchemaEnum;
|
import org.dspace.content.MetadataSchemaEnum;
|
||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
|
import org.dspace.content.service.DSpaceObjectService;
|
||||||
import org.dspace.core.ConfigurationManager;
|
import org.dspace.core.ConfigurationManager;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.core.LogManager;
|
import org.dspace.core.LogManager;
|
||||||
@@ -48,7 +51,7 @@ public class HandleIdentifierProvider extends IdentifierProvider {
|
|||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
protected HandleService handleService;
|
protected HandleService handleService;
|
||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
protected ItemService itemService;
|
protected ContentServiceFactory contentServiceFactory;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supports(Class<? extends Identifier> identifier) {
|
public boolean supports(Class<? extends Identifier> identifier) {
|
||||||
@@ -91,7 +94,7 @@ public class HandleIdentifierProvider extends IdentifierProvider {
|
|||||||
String id = mint(context, dso);
|
String id = mint(context, dso);
|
||||||
|
|
||||||
// move canonical to point the latest version
|
// move canonical to point the latest version
|
||||||
if (dso instanceof Item) {
|
if (dso instanceof Item || dso instanceof Collection || dso instanceof Community) {
|
||||||
Item item = (Item) dso;
|
Item item = (Item) dso;
|
||||||
populateHandleMetadata(context, item, id);
|
populateHandleMetadata(context, item, id);
|
||||||
}
|
}
|
||||||
@@ -108,7 +111,7 @@ public class HandleIdentifierProvider extends IdentifierProvider {
|
|||||||
public void register(Context context, DSpaceObject dso, String identifier) {
|
public void register(Context context, DSpaceObject dso, String identifier) {
|
||||||
try {
|
try {
|
||||||
handleService.createHandle(context, dso, identifier);
|
handleService.createHandle(context, dso, identifier);
|
||||||
if (dso instanceof Item) {
|
if (dso instanceof Item || dso instanceof Collection || dso instanceof Community) {
|
||||||
Item item = (Item) dso;
|
Item item = (Item) dso;
|
||||||
populateHandleMetadata(context, item, identifier);
|
populateHandleMetadata(context, item, identifier);
|
||||||
}
|
}
|
||||||
@@ -220,23 +223,25 @@ public class HandleIdentifierProvider extends IdentifierProvider {
|
|||||||
return prefix;
|
return prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void populateHandleMetadata(Context context, Item item, String handle)
|
protected void populateHandleMetadata(Context context, DSpaceObject dso, String handle)
|
||||||
throws SQLException, IOException, AuthorizeException {
|
throws SQLException, IOException, AuthorizeException {
|
||||||
String handleref = handleService.getCanonicalForm(handle);
|
String handleref = handleService.getCanonicalForm(handle);
|
||||||
|
|
||||||
|
DSpaceObjectService<DSpaceObject> dsoService = contentServiceFactory.getDSpaceObjectService(dso);
|
||||||
|
|
||||||
// Add handle as identifier.uri DC value.
|
// Add handle as identifier.uri DC value.
|
||||||
// First check that identifier doesn't already exist.
|
// First check that identifier doesn't already exist.
|
||||||
boolean identifierExists = false;
|
boolean identifierExists = false;
|
||||||
List<MetadataValue> identifiers = itemService
|
List<MetadataValue> identifiers = dsoService
|
||||||
.getMetadata(item, MetadataSchemaEnum.DC.getName(), "identifier", "uri", Item.ANY);
|
.getMetadata(dso, MetadataSchemaEnum.DC.getName(), "identifier", "uri", Item.ANY);
|
||||||
for (MetadataValue identifier : identifiers) {
|
for (MetadataValue identifier : identifiers) {
|
||||||
if (handleref.equals(identifier.getValue())) {
|
if (handleref.equals(identifier.getValue())) {
|
||||||
identifierExists = true;
|
identifierExists = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!identifierExists) {
|
if (!identifierExists) {
|
||||||
itemService.addMetadata(context, item, MetadataSchemaEnum.DC.getName(),
|
dsoService.addMetadata(context, dso, MetadataSchemaEnum.DC.getName(),
|
||||||
"identifier", "uri", null, handleref);
|
"identifier", "uri", null, handleref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -97,7 +97,7 @@ public class IdentifierServiceImpl implements IdentifierService {
|
|||||||
for (IdentifierProvider service : providers) {
|
for (IdentifierProvider service : providers) {
|
||||||
service.register(context, dso);
|
service.register(context, dso);
|
||||||
}
|
}
|
||||||
//Update our item
|
//Update our item / collection / community
|
||||||
contentServiceFactory.getDSpaceObjectService(dso).update(context, dso);
|
contentServiceFactory.getDSpaceObjectService(dso).update(context, dso);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ public class IdentifierServiceImpl implements IdentifierService {
|
|||||||
throw new IdentifierException("Cannot register identifier: Didn't "
|
throw new IdentifierException("Cannot register identifier: Didn't "
|
||||||
+ "find a provider that supports this identifier.");
|
+ "find a provider that supports this identifier.");
|
||||||
}
|
}
|
||||||
//Update our item
|
//Update our item / collection / community
|
||||||
contentServiceFactory.getDSpaceObjectService(object).update(context, object);
|
contentServiceFactory.getDSpaceObjectService(object).update(context, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,11 +17,14 @@ import java.util.regex.Pattern;
|
|||||||
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.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.content.Community;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.MetadataSchemaEnum;
|
import org.dspace.content.MetadataSchemaEnum;
|
||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
|
import org.dspace.content.service.DSpaceObjectService;
|
||||||
import org.dspace.core.ConfigurationManager;
|
import org.dspace.core.ConfigurationManager;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
@@ -65,7 +68,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
|
|||||||
private HandleService handleService;
|
private HandleService handleService;
|
||||||
|
|
||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
private ItemService itemService;
|
protected ContentServiceFactory contentServiceFactory;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supports(Class<? extends Identifier> identifier) {
|
public boolean supports(Class<? extends Identifier> identifier) {
|
||||||
@@ -107,8 +110,8 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
|
|||||||
public String register(Context context, DSpaceObject dso) {
|
public String register(Context context, DSpaceObject dso) {
|
||||||
String id = mint(context, dso);
|
String id = mint(context, dso);
|
||||||
try {
|
try {
|
||||||
if (dso instanceof Item) {
|
if (dso instanceof Item || dso instanceof Collection || dso instanceof Community) {
|
||||||
populateHandleMetadata(context, (Item) dso, id);
|
populateHandleMetadata(context, dso, id);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(LogManager.getHeader(context, "Error while attempting to create handle",
|
log.error(LogManager.getHeader(context, "Error while attempting to create handle",
|
||||||
@@ -410,16 +413,17 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
|
|||||||
return identifier;
|
return identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void populateHandleMetadata(Context context, Item item, String handle)
|
protected void populateHandleMetadata(Context context, DSpaceObject dso, String handle)
|
||||||
throws SQLException, IOException, AuthorizeException {
|
throws SQLException, IOException, AuthorizeException {
|
||||||
String handleref = handleService.getCanonicalForm(handle);
|
String handleref = handleService.getCanonicalForm(handle);
|
||||||
// we want to remove the old handle and insert the new. To do so, we
|
// we want to remove the old handle and insert the new. To do so, we
|
||||||
// load all identifiers, clear the metadata field, re add all
|
// load all identifiers, clear the metadata field, re add all
|
||||||
// identifiers which are not from type handle and add the new handle.
|
// identifiers which are not from type handle and add the new handle.
|
||||||
List<MetadataValue> identifiers = itemService.getMetadata(item,
|
DSpaceObjectService<DSpaceObject> dsoService = contentServiceFactory.getDSpaceObjectService(dso);
|
||||||
|
List<MetadataValue> identifiers = dsoService.getMetadata(dso,
|
||||||
MetadataSchemaEnum.DC.getName(), "identifier", "uri",
|
MetadataSchemaEnum.DC.getName(), "identifier", "uri",
|
||||||
Item.ANY);
|
Item.ANY);
|
||||||
itemService.clearMetadata(context, item, MetadataSchemaEnum.DC.getName(),
|
dsoService.clearMetadata(context, dso, MetadataSchemaEnum.DC.getName(),
|
||||||
"identifier", "uri", Item.ANY);
|
"identifier", "uri", Item.ANY);
|
||||||
for (MetadataValue identifier : identifiers) {
|
for (MetadataValue identifier : identifiers) {
|
||||||
if (this.supports(identifier.getValue())) {
|
if (this.supports(identifier.getValue())) {
|
||||||
@@ -428,8 +432,8 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
log.debug("Preserving identifier " + identifier.getValue());
|
log.debug("Preserving identifier " + identifier.getValue());
|
||||||
itemService.addMetadata(context,
|
dsoService.addMetadata(context,
|
||||||
item,
|
dso,
|
||||||
identifier.getMetadataField(),
|
identifier.getMetadataField(),
|
||||||
identifier.getLanguage(),
|
identifier.getLanguage(),
|
||||||
identifier.getValue(),
|
identifier.getValue(),
|
||||||
@@ -439,9 +443,9 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
|
|||||||
|
|
||||||
// Add handle as identifier.uri DC value.
|
// Add handle as identifier.uri DC value.
|
||||||
if (StringUtils.isNotBlank(handleref)) {
|
if (StringUtils.isNotBlank(handleref)) {
|
||||||
itemService.addMetadata(context, item, MetadataSchemaEnum.DC.getName(),
|
dsoService.addMetadata(context, dso, MetadataSchemaEnum.DC.getName(),
|
||||||
"identifier", "uri", null, handleref);
|
"identifier", "uri", null, handleref);
|
||||||
}
|
}
|
||||||
itemService.update(context, item);
|
dsoService.update(context, dso);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* 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.storage.rdbms.migration;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.text.StringSubstitutor;
|
||||||
|
import org.dspace.handle.service.HandleService;
|
||||||
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
|
import org.dspace.storage.rdbms.DatabaseUtils;
|
||||||
|
import org.flywaydb.core.api.migration.BaseJavaMigration;
|
||||||
|
import org.flywaydb.core.api.migration.Context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a 'dc.idendifier.uri' metadata record for each Community and Collection in the database.
|
||||||
|
* The value is calculated concatenating the canonicalPrefix extracted from the configuration
|
||||||
|
* (default is "http://hdl.handle.net/) and the object's handle suffix stored inside the handle table.
|
||||||
|
*
|
||||||
|
* @author Alessandro Martelli (alessandro.martelli at 4science.it)
|
||||||
|
*/
|
||||||
|
public class V7_0_2020_10_31__CollectionCommunity_Metadata_Handle extends BaseJavaMigration {
|
||||||
|
// Size of migration script run
|
||||||
|
protected Integer migration_file_size = -1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void migrate(Context context) throws Exception {
|
||||||
|
|
||||||
|
HandleService handleService = DSpaceServicesFactory
|
||||||
|
.getInstance().getServiceManager().getServicesByType(HandleService.class).get(0);
|
||||||
|
|
||||||
|
String dbtype = DatabaseUtils.getDbType(context.getConnection());
|
||||||
|
String sqlMigrationPath = "org/dspace/storage/rdbms/sqlmigration/metadata/" + dbtype + "/";
|
||||||
|
String dataMigrateSQL = MigrationUtils.getResourceAsString(
|
||||||
|
sqlMigrationPath + "V7.0_2020.10.31__CollectionCommunity_Metadata_Handle.sql");
|
||||||
|
|
||||||
|
// Replace ${handle.canonical.prefix} variable in SQL script with value from Configuration
|
||||||
|
Map<String, String> valuesMap = new HashMap<String, String>();
|
||||||
|
valuesMap.put("handle.canonical.prefix", handleService.getCanonicalPrefix());
|
||||||
|
StringSubstitutor sub = new StringSubstitutor(valuesMap);
|
||||||
|
dataMigrateSQL = sub.replace(dataMigrateSQL);
|
||||||
|
|
||||||
|
DatabaseUtils.executeSql(context.getConnection(), dataMigrateSQL);
|
||||||
|
|
||||||
|
migration_file_size = dataMigrateSQL.length();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getChecksum() {
|
||||||
|
return migration_file_size;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,90 @@
|
|||||||
|
--
|
||||||
|
-- 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/
|
||||||
|
--
|
||||||
|
|
||||||
|
-- ===============================================================
|
||||||
|
-- WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
|
||||||
|
--
|
||||||
|
-- DO NOT MANUALLY RUN THIS DATABASE MIGRATION. IT WILL BE EXECUTED
|
||||||
|
-- AUTOMATICALLY (IF NEEDED) BY "FLYWAY" WHEN YOU STARTUP DSPACE.
|
||||||
|
-- http://flywaydb.org/
|
||||||
|
-- ===============================================================
|
||||||
|
|
||||||
|
-------------------------------------------------------------
|
||||||
|
-- This will create COMMUNITY handle metadata
|
||||||
|
-------------------------------------------------------------
|
||||||
|
|
||||||
|
insert into metadatavalue (metadata_field_id, text_value, text_lang, place, authority, confidence, dspace_object_id)
|
||||||
|
select distinct
|
||||||
|
T1.metadata_field_id as metadata_field_id,
|
||||||
|
concat('${handle.canonical.prefix}', h.handle) as text_value,
|
||||||
|
null as text_lang, 0 as place,
|
||||||
|
null as authority,
|
||||||
|
-1 as confidence,
|
||||||
|
c.uuid as dspace_object_id
|
||||||
|
|
||||||
|
from community c
|
||||||
|
left outer join handle h on h.resource_id = c.uuid
|
||||||
|
left outer join metadatavalue mv on mv.dspace_object_id = c.uuid
|
||||||
|
left outer join metadatafieldregistry mfr on mv.metadata_field_id = mfr.metadata_field_id
|
||||||
|
left outer join metadataschemaregistry msr on mfr.metadata_schema_id = msr.metadata_schema_id
|
||||||
|
|
||||||
|
cross join (select mfr.metadata_field_id as metadata_field_id from metadatafieldregistry mfr
|
||||||
|
left outer join metadataschemaregistry msr on mfr.metadata_schema_id = msr.metadata_schema_id
|
||||||
|
where msr.short_id = 'dc'
|
||||||
|
and mfr.element = 'identifier'
|
||||||
|
and mfr.qualifier = 'uri') T1
|
||||||
|
|
||||||
|
where uuid not in (
|
||||||
|
select c.uuid as uuid from community c
|
||||||
|
left outer join handle h on h.resource_id = c.uuid
|
||||||
|
left outer join metadatavalue mv on mv.dspace_object_id = c.uuid
|
||||||
|
left outer join metadatafieldregistry mfr on mv.metadata_field_id = mfr.metadata_field_id
|
||||||
|
left outer join metadataschemaregistry msr on mfr.metadata_schema_id = msr.metadata_schema_id
|
||||||
|
where msr.short_id = 'dc'
|
||||||
|
and mfr.element = 'identifier'
|
||||||
|
and mfr.qualifier = 'uri'
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
-------------------------------------------------------------
|
||||||
|
-- This will create COLLECTION handle metadata
|
||||||
|
-------------------------------------------------------------
|
||||||
|
|
||||||
|
insert into metadatavalue (metadata_field_id, text_value, text_lang, place, authority, confidence, dspace_object_id)
|
||||||
|
select distinct
|
||||||
|
T1.metadata_field_id as metadata_field_id,
|
||||||
|
concat('${handle.canonical.prefix}', h.handle) as text_value,
|
||||||
|
null as text_lang, 0 as place,
|
||||||
|
null as authority,
|
||||||
|
-1 as confidence,
|
||||||
|
c.uuid as dspace_object_id
|
||||||
|
|
||||||
|
from collection c
|
||||||
|
left outer join handle h on h.resource_id = c.uuid
|
||||||
|
left outer join metadatavalue mv on mv.dspace_object_id = c.uuid
|
||||||
|
left outer join metadatafieldregistry mfr on mv.metadata_field_id = mfr.metadata_field_id
|
||||||
|
left outer join metadataschemaregistry msr on mfr.metadata_schema_id = msr.metadata_schema_id
|
||||||
|
|
||||||
|
cross join (select mfr.metadata_field_id as metadata_field_id from metadatafieldregistry mfr
|
||||||
|
left outer join metadataschemaregistry msr on mfr.metadata_schema_id = msr.metadata_schema_id
|
||||||
|
where msr.short_id = 'dc'
|
||||||
|
and mfr.element = 'identifier'
|
||||||
|
and mfr.qualifier = 'uri') T1
|
||||||
|
|
||||||
|
where uuid not in (
|
||||||
|
select c.uuid as uuid from collection c
|
||||||
|
left outer join handle h on h.resource_id = c.uuid
|
||||||
|
left outer join metadatavalue mv on mv.dspace_object_id = c.uuid
|
||||||
|
left outer join metadatafieldregistry mfr on mv.metadata_field_id = mfr.metadata_field_id
|
||||||
|
left outer join metadataschemaregistry msr on mfr.metadata_schema_id = msr.metadata_schema_id
|
||||||
|
where msr.short_id = 'dc'
|
||||||
|
and mfr.element = 'identifier'
|
||||||
|
and mfr.qualifier = 'uri'
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
@@ -0,0 +1,90 @@
|
|||||||
|
--
|
||||||
|
-- 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/
|
||||||
|
--
|
||||||
|
|
||||||
|
-- ===============================================================
|
||||||
|
-- WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
|
||||||
|
--
|
||||||
|
-- DO NOT MANUALLY RUN THIS DATABASE MIGRATION. IT WILL BE EXECUTED
|
||||||
|
-- AUTOMATICALLY (IF NEEDED) BY "FLYWAY" WHEN YOU STARTUP DSPACE.
|
||||||
|
-- http://flywaydb.org/
|
||||||
|
-- ===============================================================
|
||||||
|
|
||||||
|
-------------------------------------------------------------
|
||||||
|
-- This will create COMMUNITY handle metadata
|
||||||
|
-------------------------------------------------------------
|
||||||
|
|
||||||
|
insert into metadatavalue (metadata_field_id, text_value, text_lang, place, authority, confidence, dspace_object_id)
|
||||||
|
select distinct
|
||||||
|
T1.metadata_field_id as metadata_field_id,
|
||||||
|
concat('${handle.canonical.prefix}', h.handle) as text_value,
|
||||||
|
null as text_lang, 0 as place,
|
||||||
|
null as authority,
|
||||||
|
-1 as confidence,
|
||||||
|
c.uuid as dspace_object_id
|
||||||
|
|
||||||
|
from community c
|
||||||
|
left outer join handle h on h.resource_id = c.uuid
|
||||||
|
left outer join metadatavalue mv on mv.dspace_object_id = c.uuid
|
||||||
|
left outer join metadatafieldregistry mfr on mv.metadata_field_id = mfr.metadata_field_id
|
||||||
|
left outer join metadataschemaregistry msr on mfr.metadata_schema_id = msr.metadata_schema_id
|
||||||
|
|
||||||
|
cross join (select mfr.metadata_field_id as metadata_field_id from metadatafieldregistry mfr
|
||||||
|
left outer join metadataschemaregistry msr on mfr.metadata_schema_id = msr.metadata_schema_id
|
||||||
|
where msr.short_id = 'dc'
|
||||||
|
and mfr.element = 'identifier'
|
||||||
|
and mfr.qualifier = 'uri') T1
|
||||||
|
|
||||||
|
where uuid not in (
|
||||||
|
select c.uuid as uuid from community c
|
||||||
|
left outer join handle h on h.resource_id = c.uuid
|
||||||
|
left outer join metadatavalue mv on mv.dspace_object_id = c.uuid
|
||||||
|
left outer join metadatafieldregistry mfr on mv.metadata_field_id = mfr.metadata_field_id
|
||||||
|
left outer join metadataschemaregistry msr on mfr.metadata_schema_id = msr.metadata_schema_id
|
||||||
|
where msr.short_id = 'dc'
|
||||||
|
and mfr.element = 'identifier'
|
||||||
|
and mfr.qualifier = 'uri'
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
-------------------------------------------------------------
|
||||||
|
-- This will create COLLECTION handle metadata
|
||||||
|
-------------------------------------------------------------
|
||||||
|
|
||||||
|
insert into metadatavalue (metadata_field_id, text_value, text_lang, place, authority, confidence, dspace_object_id)
|
||||||
|
select distinct
|
||||||
|
T1.metadata_field_id as metadata_field_id,
|
||||||
|
concat('${handle.canonical.prefix}', h.handle) as text_value,
|
||||||
|
null as text_lang, 0 as place,
|
||||||
|
null as authority,
|
||||||
|
-1 as confidence,
|
||||||
|
c.uuid as dspace_object_id
|
||||||
|
|
||||||
|
from collection c
|
||||||
|
left outer join handle h on h.resource_id = c.uuid
|
||||||
|
left outer join metadatavalue mv on mv.dspace_object_id = c.uuid
|
||||||
|
left outer join metadatafieldregistry mfr on mv.metadata_field_id = mfr.metadata_field_id
|
||||||
|
left outer join metadataschemaregistry msr on mfr.metadata_schema_id = msr.metadata_schema_id
|
||||||
|
|
||||||
|
cross join (select mfr.metadata_field_id as metadata_field_id from metadatafieldregistry mfr
|
||||||
|
left outer join metadataschemaregistry msr on mfr.metadata_schema_id = msr.metadata_schema_id
|
||||||
|
where msr.short_id = 'dc'
|
||||||
|
and mfr.element = 'identifier'
|
||||||
|
and mfr.qualifier = 'uri') T1
|
||||||
|
|
||||||
|
where uuid not in (
|
||||||
|
select c.uuid as uuid from collection c
|
||||||
|
left outer join handle h on h.resource_id = c.uuid
|
||||||
|
left outer join metadatavalue mv on mv.dspace_object_id = c.uuid
|
||||||
|
left outer join metadatafieldregistry mfr on mv.metadata_field_id = mfr.metadata_field_id
|
||||||
|
left outer join metadataschemaregistry msr on mfr.metadata_schema_id = msr.metadata_schema_id
|
||||||
|
where msr.short_id = 'dc'
|
||||||
|
and mfr.element = 'identifier'
|
||||||
|
and mfr.qualifier = 'uri'
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
@@ -0,0 +1,90 @@
|
|||||||
|
--
|
||||||
|
-- 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/
|
||||||
|
--
|
||||||
|
|
||||||
|
-- ===============================================================
|
||||||
|
-- WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
|
||||||
|
--
|
||||||
|
-- DO NOT MANUALLY RUN THIS DATABASE MIGRATION. IT WILL BE EXECUTED
|
||||||
|
-- AUTOMATICALLY (IF NEEDED) BY "FLYWAY" WHEN YOU STARTUP DSPACE.
|
||||||
|
-- http://flywaydb.org/
|
||||||
|
-- ===============================================================
|
||||||
|
|
||||||
|
-------------------------------------------------------------
|
||||||
|
-- This will create COMMUNITY handle metadata
|
||||||
|
-------------------------------------------------------------
|
||||||
|
|
||||||
|
insert into metadatavalue (metadata_field_id, text_value, text_lang, place, authority, confidence, dspace_object_id)
|
||||||
|
select distinct
|
||||||
|
T1.metadata_field_id as metadata_field_id,
|
||||||
|
concat('${handle.canonical.prefix}', h.handle) as text_value,
|
||||||
|
null as text_lang, 0 as place,
|
||||||
|
null as authority,
|
||||||
|
-1 as confidence,
|
||||||
|
c.uuid as dspace_object_id
|
||||||
|
|
||||||
|
from community c
|
||||||
|
left outer join handle h on h.resource_id = c.uuid
|
||||||
|
left outer join metadatavalue mv on mv.dspace_object_id = c.uuid
|
||||||
|
left outer join metadatafieldregistry mfr on mv.metadata_field_id = mfr.metadata_field_id
|
||||||
|
left outer join metadataschemaregistry msr on mfr.metadata_schema_id = msr.metadata_schema_id
|
||||||
|
|
||||||
|
cross join (select mfr.metadata_field_id as metadata_field_id from metadatafieldregistry mfr
|
||||||
|
left outer join metadataschemaregistry msr on mfr.metadata_schema_id = msr.metadata_schema_id
|
||||||
|
where msr.short_id = 'dc'
|
||||||
|
and mfr.element = 'identifier'
|
||||||
|
and mfr.qualifier = 'uri') T1
|
||||||
|
|
||||||
|
where uuid not in (
|
||||||
|
select c.uuid as uuid from community c
|
||||||
|
left outer join handle h on h.resource_id = c.uuid
|
||||||
|
left outer join metadatavalue mv on mv.dspace_object_id = c.uuid
|
||||||
|
left outer join metadatafieldregistry mfr on mv.metadata_field_id = mfr.metadata_field_id
|
||||||
|
left outer join metadataschemaregistry msr on mfr.metadata_schema_id = msr.metadata_schema_id
|
||||||
|
where msr.short_id = 'dc'
|
||||||
|
and mfr.element = 'identifier'
|
||||||
|
and mfr.qualifier = 'uri'
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
-------------------------------------------------------------
|
||||||
|
-- This will create COLLECTION handle metadata
|
||||||
|
-------------------------------------------------------------
|
||||||
|
|
||||||
|
insert into metadatavalue (metadata_field_id, text_value, text_lang, place, authority, confidence, dspace_object_id)
|
||||||
|
select distinct
|
||||||
|
T1.metadata_field_id as metadata_field_id,
|
||||||
|
concat('${handle.canonical.prefix}', h.handle) as text_value,
|
||||||
|
null as text_lang, 0 as place,
|
||||||
|
null as authority,
|
||||||
|
-1 as confidence,
|
||||||
|
c.uuid as dspace_object_id
|
||||||
|
|
||||||
|
from collection c
|
||||||
|
left outer join handle h on h.resource_id = c.uuid
|
||||||
|
left outer join metadatavalue mv on mv.dspace_object_id = c.uuid
|
||||||
|
left outer join metadatafieldregistry mfr on mv.metadata_field_id = mfr.metadata_field_id
|
||||||
|
left outer join metadataschemaregistry msr on mfr.metadata_schema_id = msr.metadata_schema_id
|
||||||
|
|
||||||
|
cross join (select mfr.metadata_field_id as metadata_field_id from metadatafieldregistry mfr
|
||||||
|
left outer join metadataschemaregistry msr on mfr.metadata_schema_id = msr.metadata_schema_id
|
||||||
|
where msr.short_id = 'dc'
|
||||||
|
and mfr.element = 'identifier'
|
||||||
|
and mfr.qualifier = 'uri') T1
|
||||||
|
|
||||||
|
where uuid not in (
|
||||||
|
select c.uuid as uuid from collection c
|
||||||
|
left outer join handle h on h.resource_id = c.uuid
|
||||||
|
left outer join metadatavalue mv on mv.dspace_object_id = c.uuid
|
||||||
|
left outer join metadatafieldregistry mfr on mv.metadata_field_id = mfr.metadata_field_id
|
||||||
|
left outer join metadataschemaregistry msr on mfr.metadata_schema_id = msr.metadata_schema_id
|
||||||
|
where msr.short_id = 'dc'
|
||||||
|
and mfr.element = 'identifier'
|
||||||
|
and mfr.qualifier = 'uri'
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
@@ -38,6 +38,8 @@ import org.dspace.core.factory.CoreServiceFactory;
|
|||||||
import org.dspace.core.service.LicenseService;
|
import org.dspace.core.service.LicenseService;
|
||||||
import org.dspace.eperson.EPerson;
|
import org.dspace.eperson.EPerson;
|
||||||
import org.dspace.eperson.Group;
|
import org.dspace.eperson.Group;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
import org.dspace.utils.DSpace;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -159,6 +161,7 @@ public class CollectionTest extends AbstractDSpaceObjectTest {
|
|||||||
public void testCreate() throws Exception {
|
public void testCreate() throws Exception {
|
||||||
// Allow Community ADD perms
|
// Allow Community ADD perms
|
||||||
doNothing().when(authorizeServiceSpy).authorizeAction(context, owningCommunity, Constants.ADD);
|
doNothing().when(authorizeServiceSpy).authorizeAction(context, owningCommunity, Constants.ADD);
|
||||||
|
doNothing().when(authorizeServiceSpy).authorizeAction(context, owningCommunity, Constants.ADD, true);
|
||||||
|
|
||||||
Collection created = collectionService.create(context, owningCommunity);
|
Collection created = collectionService.create(context, owningCommunity);
|
||||||
assertThat("testCreate 0", created, notNullValue());
|
assertThat("testCreate 0", created, notNullValue());
|
||||||
@@ -172,6 +175,14 @@ public class CollectionTest extends AbstractDSpaceObjectTest {
|
|||||||
public void testCreateWithValidHandle() throws Exception {
|
public void testCreateWithValidHandle() throws Exception {
|
||||||
// Allow Community ADD perms
|
// Allow Community ADD perms
|
||||||
doNothing().when(authorizeServiceSpy).authorizeAction(context, owningCommunity, Constants.ADD);
|
doNothing().when(authorizeServiceSpy).authorizeAction(context, owningCommunity, Constants.ADD);
|
||||||
|
doNothing().when(authorizeServiceSpy).authorizeAction(context, owningCommunity, Constants.ADD, true);
|
||||||
|
|
||||||
|
// provide additional prefixes to the configuration in order to support them
|
||||||
|
final ConfigurationService configurationService = new DSpace().getConfigurationService();
|
||||||
|
String handleAdditionalPrefixes = configurationService.getProperty("handle.additional.prefixes");
|
||||||
|
|
||||||
|
try {
|
||||||
|
configurationService.setProperty("handle.additional.prefixes", "987654321");
|
||||||
|
|
||||||
// test creating collection with a specified handle which is NOT already in use
|
// test creating collection with a specified handle which is NOT already in use
|
||||||
// (this handle should not already be used by system, as it doesn't start with "1234567689" prefix)
|
// (this handle should not already be used by system, as it doesn't start with "1234567689" prefix)
|
||||||
@@ -180,6 +191,10 @@ public class CollectionTest extends AbstractDSpaceObjectTest {
|
|||||||
// check that collection was created, and that its handle was set to proper value
|
// check that collection was created, and that its handle was set to proper value
|
||||||
assertThat("testCreateWithValidHandle 0", created, notNullValue());
|
assertThat("testCreateWithValidHandle 0", created, notNullValue());
|
||||||
assertThat("testCreateWithValidHandle 1", created.getHandle(), equalTo("987654321/100"));
|
assertThat("testCreateWithValidHandle 1", created.getHandle(), equalTo("987654321/100"));
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
configurationService.setProperty("handle.additional.prefixes", handleAdditionalPrefixes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -19,6 +19,7 @@ import static org.junit.Assert.fail;
|
|||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.doNothing;
|
import static org.mockito.Mockito.doNothing;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.doThrow;
|
import static org.mockito.Mockito.doThrow;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
@@ -35,7 +36,10 @@ import org.dspace.authorize.factory.AuthorizeServiceFactory;
|
|||||||
import org.dspace.authorize.service.AuthorizeService;
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.eperson.EPerson;
|
||||||
import org.dspace.eperson.Group;
|
import org.dspace.eperson.Group;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
import org.dspace.utils.DSpace;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -169,6 +173,7 @@ public class CommunityTest extends AbstractDSpaceObjectTest {
|
|||||||
// Below settings default to Full Admin Rights (but not Community Admin rights)
|
// Below settings default to Full Admin Rights (but not Community Admin rights)
|
||||||
// Allow full Admin perms
|
// Allow full Admin perms
|
||||||
when(authorizeServiceSpy.isAdmin(context)).thenReturn(true);
|
when(authorizeServiceSpy.isAdmin(context)).thenReturn(true);
|
||||||
|
when(authorizeServiceSpy.isAdmin(context, eperson)).thenReturn(true);
|
||||||
|
|
||||||
//Test that a full Admin can create a Community without a parent (Top-Level Community)
|
//Test that a full Admin can create a Community without a parent (Top-Level Community)
|
||||||
Community created = communityService.create(null, context);
|
Community created = communityService.create(null, context);
|
||||||
@@ -206,6 +211,14 @@ public class CommunityTest extends AbstractDSpaceObjectTest {
|
|||||||
public void testCreateWithValidHandle() throws Exception {
|
public void testCreateWithValidHandle() throws Exception {
|
||||||
// Allow full Admin perms
|
// Allow full Admin perms
|
||||||
when(authorizeServiceSpy.isAdmin(context)).thenReturn(true);
|
when(authorizeServiceSpy.isAdmin(context)).thenReturn(true);
|
||||||
|
doReturn(true).when(authorizeServiceSpy).isAdmin(eq(context), any(EPerson.class));
|
||||||
|
|
||||||
|
// provide additional prefixes to the configuration in order to support them
|
||||||
|
final ConfigurationService configurationService = new DSpace().getConfigurationService();
|
||||||
|
String handleAdditionalPrefixes = configurationService.getProperty("handle.additional.prefixes");
|
||||||
|
|
||||||
|
try {
|
||||||
|
configurationService.setProperty("handle.additional.prefixes", "987654321");
|
||||||
|
|
||||||
// test creating community with a specified handle which is NOT already in use
|
// test creating community with a specified handle which is NOT already in use
|
||||||
// (this handle should not already be used by system, as it doesn't start with "1234567689" prefix)
|
// (this handle should not already be used by system, as it doesn't start with "1234567689" prefix)
|
||||||
@@ -214,6 +227,10 @@ public class CommunityTest extends AbstractDSpaceObjectTest {
|
|||||||
// check that community was created, and that its handle was set to proper value
|
// check that community was created, and that its handle was set to proper value
|
||||||
assertThat("testCreateWithValidHandle 0", created, notNullValue());
|
assertThat("testCreateWithValidHandle 0", created, notNullValue());
|
||||||
assertThat("testCreateWithValidHandle 1", created.getHandle(), equalTo("987654321/100c"));
|
assertThat("testCreateWithValidHandle 1", created.getHandle(), equalTo("987654321/100c"));
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
configurationService.setProperty("handle.additional.prefixes", handleAdditionalPrefixes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -602,6 +619,7 @@ public class CommunityTest extends AbstractDSpaceObjectTest {
|
|||||||
public void testCreateCollectionAuth() throws Exception {
|
public void testCreateCollectionAuth() throws Exception {
|
||||||
// Allow current Community ADD perms
|
// Allow current Community ADD perms
|
||||||
doNothing().when(authorizeServiceSpy).authorizeAction(context, c, Constants.ADD);
|
doNothing().when(authorizeServiceSpy).authorizeAction(context, c, Constants.ADD);
|
||||||
|
doNothing().when(authorizeServiceSpy).authorizeAction(context, c, Constants.ADD, true);
|
||||||
|
|
||||||
Collection result = collectionService.create(context, c);
|
Collection result = collectionService.create(context, c);
|
||||||
assertThat("testCreateCollectionAuth 0", result, notNullValue());
|
assertThat("testCreateCollectionAuth 0", result, notNullValue());
|
||||||
@@ -628,6 +646,7 @@ public class CommunityTest extends AbstractDSpaceObjectTest {
|
|||||||
public void testAddCollectionAuth() throws Exception {
|
public void testAddCollectionAuth() throws Exception {
|
||||||
// Allow current Community ADD perms
|
// Allow current Community ADD perms
|
||||||
doNothing().when(authorizeServiceSpy).authorizeAction(context, c, Constants.ADD);
|
doNothing().when(authorizeServiceSpy).authorizeAction(context, c, Constants.ADD);
|
||||||
|
doNothing().when(authorizeServiceSpy).authorizeAction(context, c, Constants.ADD, true);
|
||||||
|
|
||||||
Collection col = collectionService.create(context, c);
|
Collection col = collectionService.create(context, c);
|
||||||
c.addCollection(col);
|
c.addCollection(col);
|
||||||
@@ -929,7 +948,8 @@ public class CommunityTest extends AbstractDSpaceObjectTest {
|
|||||||
@SuppressWarnings("ObjectEqualsNull")
|
@SuppressWarnings("ObjectEqualsNull")
|
||||||
public void testEquals() throws SQLException, AuthorizeException {
|
public void testEquals() throws SQLException, AuthorizeException {
|
||||||
// Allow full Admin perms (just to create top-level community)
|
// Allow full Admin perms (just to create top-level community)
|
||||||
when(authorizeServiceSpy.isAdmin(context)).thenReturn(true);
|
doReturn(true).when(authorizeServiceSpy).isAdmin(eq(context));
|
||||||
|
doReturn(true).when(authorizeServiceSpy).isAdmin(eq(context), any(EPerson.class));
|
||||||
|
|
||||||
assertFalse("testEquals 0", c.equals(null));
|
assertFalse("testEquals 0", c.equals(null));
|
||||||
assertFalse("testEquals 1", c.equals(communityService.create(null, context)));
|
assertFalse("testEquals 1", c.equals(communityService.create(null, context)));
|
||||||
|
@@ -75,6 +75,7 @@ public class MetadataConverter implements DSpaceConverter<MetadataValueList, Met
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a DSpace object's domain metadata values from a rest representation.
|
* Sets a DSpace object's domain metadata values from a rest representation.
|
||||||
|
* Any existing metadata value is deleted or overwritten.
|
||||||
*
|
*
|
||||||
* @param context the context to use.
|
* @param context the context to use.
|
||||||
* @param dso the DSpace object.
|
* @param dso the DSpace object.
|
||||||
@@ -82,10 +83,52 @@ public class MetadataConverter implements DSpaceConverter<MetadataValueList, Met
|
|||||||
* @throws SQLException if a database error occurs.
|
* @throws SQLException if a database error occurs.
|
||||||
* @throws AuthorizeException if an authorization error occurs.
|
* @throws AuthorizeException if an authorization error occurs.
|
||||||
*/
|
*/
|
||||||
public void setMetadata(Context context, DSpaceObject dso, MetadataRest metadataRest)
|
public <T extends DSpaceObject> void setMetadata(Context context, T dso, MetadataRest metadataRest)
|
||||||
throws SQLException, AuthorizeException {
|
throws SQLException, AuthorizeException {
|
||||||
DSpaceObjectService dsoService = contentServiceFactory.getDSpaceObjectService(dso);
|
DSpaceObjectService<T> dsoService = contentServiceFactory.getDSpaceObjectService(dso);
|
||||||
dsoService.clearMetadata(context, dso, Item.ANY, Item.ANY, Item.ANY, Item.ANY);
|
dsoService.clearMetadata(context, dso, Item.ANY, Item.ANY, Item.ANY, Item.ANY);
|
||||||
|
persistMetadataRest(context, dso, metadataRest, dsoService);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add to a DSpace object's domain metadata values from a rest representation.
|
||||||
|
* Any existing metadata value is preserved.
|
||||||
|
*
|
||||||
|
* @param context the context to use.
|
||||||
|
* @param dso the DSpace object.
|
||||||
|
* @param metadataRest the rest representation of the new metadata.
|
||||||
|
* @throws SQLException if a database error occurs.
|
||||||
|
* @throws AuthorizeException if an authorization error occurs.
|
||||||
|
*/
|
||||||
|
public <T extends DSpaceObject> void addMetadata(Context context, T dso, MetadataRest metadataRest)
|
||||||
|
throws SQLException, AuthorizeException {
|
||||||
|
DSpaceObjectService<T> dsoService = contentServiceFactory.getDSpaceObjectService(dso);
|
||||||
|
persistMetadataRest(context, dso, metadataRest, dsoService);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge into a DSpace object's domain metadata values from a rest representation.
|
||||||
|
* Any existing metadata value is preserved or overwritten with the new ones
|
||||||
|
*
|
||||||
|
* @param context the context to use.
|
||||||
|
* @param dso the DSpace object.
|
||||||
|
* @param metadataRest the rest representation of the new metadata.
|
||||||
|
* @throws SQLException if a database error occurs.
|
||||||
|
* @throws AuthorizeException if an authorization error occurs.
|
||||||
|
*/
|
||||||
|
public <T extends DSpaceObject> void mergeMetadata(Context context, T dso, MetadataRest metadataRest)
|
||||||
|
throws SQLException, AuthorizeException {
|
||||||
|
DSpaceObjectService<T> dsoService = contentServiceFactory.getDSpaceObjectService(dso);
|
||||||
|
for (Map.Entry<String, List<MetadataValueRest>> entry: metadataRest.getMap().entrySet()) {
|
||||||
|
List<MetadataValue> metadataByMetadataString = dsoService.getMetadataByMetadataString(dso, entry.getKey());
|
||||||
|
dsoService.removeMetadataValues(context, dso, metadataByMetadataString);
|
||||||
|
}
|
||||||
|
persistMetadataRest(context, dso, metadataRest, dsoService);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends DSpaceObject> void persistMetadataRest(Context context, T dso, MetadataRest metadataRest,
|
||||||
|
DSpaceObjectService<T> dsoService)
|
||||||
|
throws SQLException, AuthorizeException {
|
||||||
for (Map.Entry<String, List<MetadataValueRest>> entry: metadataRest.getMap().entrySet()) {
|
for (Map.Entry<String, List<MetadataValueRest>> entry: metadataRest.getMap().entrySet()) {
|
||||||
String[] seq = entry.getKey().split("\\.");
|
String[] seq = entry.getKey().split("\\.");
|
||||||
String schema = seq[0];
|
String schema = seq[0];
|
||||||
@@ -98,4 +141,5 @@ public class MetadataConverter implements DSpaceConverter<MetadataValueList, Met
|
|||||||
}
|
}
|
||||||
dsoService.update(context, dso);
|
dsoService.update(context, dso);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -245,7 +245,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
|
|||||||
}
|
}
|
||||||
collection = cs.create(context, parent);
|
collection = cs.create(context, parent);
|
||||||
cs.update(context, collection);
|
cs.update(context, collection);
|
||||||
metadataConverter.setMetadata(context, collection, collectionRest.getMetadata());
|
metadataConverter.mergeMetadata(context, collection, collectionRest.getMetadata());
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new RuntimeException("Unable to create new Collection under parent Community " + id, e);
|
throw new RuntimeException("Unable to create new Collection under parent Community " + id, e);
|
||||||
}
|
}
|
||||||
|
@@ -91,25 +91,9 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
|
|||||||
@Override
|
@Override
|
||||||
@PreAuthorize("hasAuthority('ADMIN')")
|
@PreAuthorize("hasAuthority('ADMIN')")
|
||||||
protected CommunityRest createAndReturn(Context context) throws AuthorizeException {
|
protected CommunityRest createAndReturn(Context context) throws AuthorizeException {
|
||||||
HttpServletRequest req = getRequestService().getCurrentRequest().getHttpServletRequest();
|
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
|
||||||
CommunityRest communityRest;
|
|
||||||
try {
|
|
||||||
ServletInputStream input = req.getInputStream();
|
|
||||||
communityRest = mapper.readValue(input, CommunityRest.class);
|
|
||||||
} catch (IOException e1) {
|
|
||||||
throw new UnprocessableEntityException("Error parsing request body: " + e1.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
Community community;
|
// top-level community
|
||||||
try {
|
Community community = createCommunity(context, null);
|
||||||
// top-level community
|
|
||||||
community = cs.create(null, context);
|
|
||||||
cs.update(context, community);
|
|
||||||
metadataConverter.setMetadata(context, community, communityRest.getMetadata());
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new RuntimeException(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return converter.toRest(community, utils.obtainProjection());
|
return converter.toRest(community, utils.obtainProjection());
|
||||||
}
|
}
|
||||||
@@ -123,6 +107,24 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
|
|||||||
"Cannot create a SubCommunity without providing a parent Community.");
|
"Cannot create a SubCommunity without providing a parent Community.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Community parent;
|
||||||
|
try {
|
||||||
|
parent = cs.find(context, id);
|
||||||
|
if (parent == null) {
|
||||||
|
throw new UnprocessableEntityException("Parent community for id: "
|
||||||
|
+ id + " not found");
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// sub-community
|
||||||
|
Community community = createCommunity(context, parent);
|
||||||
|
|
||||||
|
return converter.toRest(community, utils.obtainProjection());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Community createCommunity(Context context, Community parent) throws AuthorizeException {
|
||||||
HttpServletRequest req = getRequestService().getCurrentRequest().getHttpServletRequest();
|
HttpServletRequest req = getRequestService().getCurrentRequest().getHttpServletRequest();
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
CommunityRest communityRest;
|
CommunityRest communityRest;
|
||||||
@@ -134,21 +136,15 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
|
|||||||
}
|
}
|
||||||
|
|
||||||
Community community;
|
Community community;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Community parent = cs.find(context, id);
|
|
||||||
if (parent == null) {
|
|
||||||
throw new UnprocessableEntityException("Parent community for id: "
|
|
||||||
+ id + " not found");
|
|
||||||
}
|
|
||||||
// sub-community
|
|
||||||
community = cs.create(parent, context);
|
community = cs.create(parent, context);
|
||||||
cs.update(context, community);
|
cs.update(context, community);
|
||||||
metadataConverter.setMetadata(context, community, communityRest.getMetadata());
|
metadataConverter.mergeMetadata(context, community, communityRest.getMetadata());
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new RuntimeException(e.getMessage(), e);
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
return community;
|
||||||
return converter.toRest(community, utils.obtainProjection());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -11,6 +11,8 @@ 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.MetadataMatcher.matchMetadataNotEmpty;
|
||||||
|
import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadataStringEndsWith;
|
||||||
import static org.dspace.core.Constants.WRITE;
|
import static org.dspace.core.Constants.WRITE;
|
||||||
import static org.hamcrest.Matchers.empty;
|
import static org.hamcrest.Matchers.empty;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
@@ -1074,6 +1076,7 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
|||||||
|
|
||||||
AtomicReference<UUID> idRef = new AtomicReference<>();
|
AtomicReference<UUID> idRef = new AtomicReference<>();
|
||||||
AtomicReference<UUID> idRefNoEmbeds = new AtomicReference<>();
|
AtomicReference<UUID> idRefNoEmbeds = new AtomicReference<>();
|
||||||
|
AtomicReference<String> handle = new AtomicReference<>();
|
||||||
try {
|
try {
|
||||||
|
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
@@ -1121,6 +1124,15 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
|||||||
MetadataMatcher.matchMetadata("dc.title",
|
MetadataMatcher.matchMetadata("dc.title",
|
||||||
"Title Text")
|
"Title Text")
|
||||||
)))))
|
)))))
|
||||||
|
// capture "handle" returned in JSON response and check against the metadata
|
||||||
|
.andDo(result -> handle.set(
|
||||||
|
read(result.getResponse().getContentAsString(), "$.handle")))
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
hasJsonPath("$.metadata", Matchers.allOf(
|
||||||
|
matchMetadataNotEmpty("dc.identifier.uri"),
|
||||||
|
matchMetadataStringEndsWith("dc.identifier.uri", handle.get())
|
||||||
|
)
|
||||||
|
)))
|
||||||
.andDo(result -> idRef
|
.andDo(result -> idRef
|
||||||
.set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id"))));;
|
.set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id"))));;
|
||||||
|
|
||||||
|
@@ -11,6 +11,8 @@ 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 junit.framework.TestCase.assertEquals;
|
import static junit.framework.TestCase.assertEquals;
|
||||||
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.matchMetadataNotEmpty;
|
||||||
|
import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadataStringEndsWith;
|
||||||
import static org.hamcrest.Matchers.empty;
|
import static org.hamcrest.Matchers.empty;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.not;
|
import static org.hamcrest.Matchers.not;
|
||||||
@@ -117,6 +119,8 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
// Capture the UUID of the created Community (see andDo() below)
|
// Capture the UUID of the created Community (see andDo() below)
|
||||||
AtomicReference<UUID> idRef = new AtomicReference<>();
|
AtomicReference<UUID> idRef = new AtomicReference<>();
|
||||||
AtomicReference<UUID> idRefNoEmbeds = new AtomicReference<>();
|
AtomicReference<UUID> idRefNoEmbeds = new AtomicReference<>();
|
||||||
|
AtomicReference<String> handle = new AtomicReference<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
getClient(authToken).perform(post("/api/core/communities")
|
getClient(authToken).perform(post("/api/core/communities")
|
||||||
.content(mapper.writeValueAsBytes(comm))
|
.content(mapper.writeValueAsBytes(comm))
|
||||||
@@ -136,15 +140,26 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
hasJsonPath("$._links.subcommunities.href", not(empty())),
|
hasJsonPath("$._links.subcommunities.href", not(empty())),
|
||||||
hasJsonPath("$._links.self.href", not(empty())),
|
hasJsonPath("$._links.self.href", not(empty())),
|
||||||
hasJsonPath("$.metadata", Matchers.allOf(
|
hasJsonPath("$.metadata", Matchers.allOf(
|
||||||
matchMetadata("dc.description", "<p>Some cool HTML code here</p>"),
|
matchMetadata("dc.description", "<p>Some cool HTML code here</p>"),
|
||||||
matchMetadata("dc.description.abstract",
|
matchMetadata("dc.description.abstract",
|
||||||
"Sample top-level community created via the REST API"),
|
"Sample top-level community created via the REST API"),
|
||||||
matchMetadata("dc.description.tableofcontents", "<p>HTML News</p>"),
|
matchMetadata("dc.description.tableofcontents", "<p>HTML News</p>"),
|
||||||
matchMetadata("dc.rights", "Custom Copyright Text"),
|
matchMetadata("dc.rights", "Custom Copyright Text"),
|
||||||
matchMetadata("dc.title", "Title Text")
|
matchMetadata("dc.title", "Title Text")
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
)))
|
)))
|
||||||
|
|
||||||
|
// capture "handle" returned in JSON response and check against the metadata
|
||||||
|
.andDo(result -> handle.set(
|
||||||
|
read(result.getResponse().getContentAsString(), "$.handle")))
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
hasJsonPath("$.metadata", Matchers.allOf(
|
||||||
|
matchMetadataNotEmpty("dc.identifier.uri"),
|
||||||
|
matchMetadataStringEndsWith("dc.identifier.uri", handle.get())
|
||||||
|
)
|
||||||
|
)))
|
||||||
|
|
||||||
// capture "id" returned in JSON response
|
// capture "id" returned in JSON response
|
||||||
.andDo(result -> idRef
|
.andDo(result -> idRef
|
||||||
.set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id"))));
|
.set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id"))));
|
||||||
@@ -233,8 +248,9 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
.put("dc.title",
|
.put("dc.title",
|
||||||
new MetadataValueRest("Title Text")));
|
new MetadataValueRest("Title Text")));
|
||||||
|
|
||||||
// Capture the UUID of the created Community (see andDo() below)
|
// Capture the UUID and Handle of the created Community (see andDo() below)
|
||||||
AtomicReference<UUID> idRef = new AtomicReference<>();
|
AtomicReference<UUID> idRef = new AtomicReference<>();
|
||||||
|
AtomicReference<String> handle = new AtomicReference<>();
|
||||||
try {
|
try {
|
||||||
getClient(authToken).perform(post("/api/core/communities")
|
getClient(authToken).perform(post("/api/core/communities")
|
||||||
.content(mapper.writeValueAsBytes(comm))
|
.content(mapper.writeValueAsBytes(comm))
|
||||||
@@ -253,17 +269,26 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
hasJsonPath("$._links.subcommunities.href", not(empty())),
|
hasJsonPath("$._links.subcommunities.href", not(empty())),
|
||||||
hasJsonPath("$._links.self.href", not(empty())),
|
hasJsonPath("$._links.self.href", not(empty())),
|
||||||
hasJsonPath("$.metadata", Matchers.allOf(
|
hasJsonPath("$.metadata", Matchers.allOf(
|
||||||
MetadataMatcher.matchMetadata("dc.description",
|
MetadataMatcher.matchMetadata("dc.description",
|
||||||
"<p>Some cool HTML code here</p>"),
|
"<p>Some cool HTML code here</p>"),
|
||||||
MetadataMatcher.matchMetadata("dc.description.abstract",
|
MetadataMatcher.matchMetadata("dc.description.abstract",
|
||||||
"Sample top-level community created via the REST API"),
|
"Sample top-level community created via the REST API"),
|
||||||
MetadataMatcher.matchMetadata("dc.description.tableofcontents",
|
MetadataMatcher.matchMetadata("dc.description.tableofcontents",
|
||||||
"<p>HTML News</p>"),
|
"<p>HTML News</p>"),
|
||||||
MetadataMatcher.matchMetadata("dc.rights",
|
MetadataMatcher.matchMetadata("dc.rights",
|
||||||
"Custom Copyright Text"),
|
"Custom Copyright Text"),
|
||||||
MetadataMatcher.matchMetadata("dc.title",
|
MetadataMatcher.matchMetadata("dc.title",
|
||||||
"Title Text")
|
"Title Text")
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
)))
|
||||||
|
// capture "handle" returned in JSON response and check against the metadata
|
||||||
|
.andDo(result -> handle.set(
|
||||||
|
read(result.getResponse().getContentAsString(), "$.handle")))
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
hasJsonPath("$.metadata", Matchers.allOf(
|
||||||
|
matchMetadataNotEmpty("dc.identifier.uri"),
|
||||||
|
matchMetadataStringEndsWith("dc.identifier.uri", handle.get())
|
||||||
)
|
)
|
||||||
)))
|
)))
|
||||||
// capture "id" returned in JSON response
|
// capture "id" returned in JSON response
|
||||||
|
@@ -10,6 +10,7 @@ package org.dspace.app.rest;
|
|||||||
import static com.jayway.jsonpath.JsonPath.read;
|
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.hamcrest.Matchers.allOf;
|
import static org.hamcrest.Matchers.allOf;
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
import static org.hamcrest.Matchers.empty;
|
import static org.hamcrest.Matchers.empty;
|
||||||
@@ -133,7 +134,8 @@ public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
hasJsonPath("$._links.self.href", not(empty())),
|
hasJsonPath("$._links.self.href", not(empty())),
|
||||||
hasJsonPath("$.metadata", Matchers.allOf(
|
hasJsonPath("$.metadata", Matchers.allOf(
|
||||||
matchMetadata("eperson.firstname", "John"),
|
matchMetadata("eperson.firstname", "John"),
|
||||||
matchMetadata("eperson.lastname", "Doe")
|
matchMetadata("eperson.lastname", "Doe"),
|
||||||
|
matchMetadataDoesNotExist("dc.identifier.uri")
|
||||||
)))))
|
)))))
|
||||||
.andDo(result -> idRef
|
.andDo(result -> idRef
|
||||||
.set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id"))));
|
.set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id"))));
|
||||||
|
@@ -9,10 +9,13 @@ package org.dspace.app.rest.matcher;
|
|||||||
|
|
||||||
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
||||||
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath;
|
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath;
|
||||||
|
import static org.hamcrest.Matchers.empty;
|
||||||
import static org.hamcrest.Matchers.hasItem;
|
import static org.hamcrest.Matchers.hasItem;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.not;
|
||||||
|
|
||||||
import org.hamcrest.Matcher;
|
import org.hamcrest.Matcher;
|
||||||
|
import org.hamcrest.core.StringEndsWith;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class to provide convenient matchers for metadata.
|
* Utility class to provide convenient matchers for metadata.
|
||||||
@@ -33,6 +36,25 @@ public class MetadataMatcher {
|
|||||||
return hasJsonPath("$.['" + key + "'][*].value", hasItem(value));
|
return hasJsonPath("$.['" + key + "'][*].value", hasItem(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a matcher to ensure a given key contains at least one value.
|
||||||
|
* @param key the metadata key.
|
||||||
|
* @return the matcher
|
||||||
|
*/
|
||||||
|
public static Matcher<? super Object> matchMetadataNotEmpty(String key) {
|
||||||
|
return hasJsonPath("$.['" + key + "']", not(empty()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a matcher to ensure that at least one value for a given metadata key endsWith the given subString.
|
||||||
|
* @param key the metadata key.
|
||||||
|
* @param subString the subString which the value must end with
|
||||||
|
* @return the matcher
|
||||||
|
*/
|
||||||
|
public static Matcher<? super Object> matchMetadataStringEndsWith(String key, String subString) {
|
||||||
|
return hasJsonPath("$.['" + key + "'][*].value", hasItem(StringEndsWith.endsWith(subString)));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a matcher to ensure a given value is present at a specific position in the list of values for a given key.
|
* Gets a matcher to ensure a given value is present at a specific position in the list of values for a given key.
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user