mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +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.harvest.HarvestedCollection;
|
||||
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.xmlworkflow.WorkflowConfigurationException;
|
||||
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
|
||||
@@ -92,6 +94,8 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
||||
protected CommunityService communityService;
|
||||
@Autowired(required = true)
|
||||
protected GroupService groupService;
|
||||
@Autowired(required = true)
|
||||
protected IdentifierService identifierService;
|
||||
|
||||
@Autowired(required = true)
|
||||
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
|
||||
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
|
||||
// of 'anonymous' READ
|
||||
Group anonymousGroup = groupService.findByName(context, Group.ANONYMOUS);
|
||||
@@ -150,6 +147,18 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
||||
authorizeService
|
||||
.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,
|
||||
newCollection.getID(), newCollection.getHandle(),
|
||||
@@ -159,7 +168,6 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
||||
"collection_id=" + newCollection.getID())
|
||||
+ ",handle=" + newCollection.getHandle());
|
||||
|
||||
collectionDAO.save(context, newCollection);
|
||||
return newCollection;
|
||||
}
|
||||
|
||||
|
@@ -37,6 +37,8 @@ import org.dspace.core.LogManager;
|
||||
import org.dspace.eperson.Group;
|
||||
import org.dspace.eperson.service.GroupService;
|
||||
import org.dspace.event.Event;
|
||||
import org.dspace.identifier.IdentifierException;
|
||||
import org.dspace.identifier.service.IdentifierService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
@@ -69,6 +71,8 @@ public class CommunityServiceImpl extends DSpaceObjectServiceImpl<Community> imp
|
||||
protected BitstreamService bitstreamService;
|
||||
@Autowired(required = true)
|
||||
protected SiteService siteService;
|
||||
@Autowired(required = true)
|
||||
protected IdentifierService identifierService;
|
||||
|
||||
protected CommunityServiceImpl() {
|
||||
super();
|
||||
@@ -90,17 +94,6 @@ public class CommunityServiceImpl extends DSpaceObjectServiceImpl<Community> imp
|
||||
|
||||
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) {
|
||||
parent.addSubCommunity(newCommunity);
|
||||
newCommunity.addParentCommunity(parent);
|
||||
@@ -115,14 +108,24 @@ public class CommunityServiceImpl extends DSpaceObjectServiceImpl<Community> imp
|
||||
|
||||
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(),
|
||||
getIdentifiers(context, newCommunity)));
|
||||
getIdentifiers(context, newCommunity)));
|
||||
|
||||
// if creating a top-level Community, simulate an ADD event at the Site.
|
||||
if (parent == null) {
|
||||
context.addEvent(new Event(Event.ADD, Constants.SITE, siteService.findSite(context).getID(),
|
||||
Constants.COMMUNITY, newCommunity.getID(), newCommunity.getHandle(),
|
||||
getIdentifiers(context, newCommunity)));
|
||||
Constants.COMMUNITY, newCommunity.getID(), newCommunity.getHandle(),
|
||||
getIdentifiers(context, newCommunity)));
|
||||
}
|
||||
|
||||
log.info(LogManager.getHeader(context, "create_community",
|
||||
|
@@ -169,6 +169,10 @@ public class DOIIdentifierProvider
|
||||
@Override
|
||||
public String register(Context context, DSpaceObject dso)
|
||||
throws IdentifierException {
|
||||
if (!(dso instanceof Item)) {
|
||||
// DOI are currently assigned only to Item
|
||||
return null;
|
||||
}
|
||||
String doi = mint(context, dso);
|
||||
// register tries to reserve doi if it's not already.
|
||||
// So we don't have to reserve it here.
|
||||
@@ -179,6 +183,10 @@ public class DOIIdentifierProvider
|
||||
@Override
|
||||
public void register(Context context, DSpaceObject dso, String identifier)
|
||||
throws IdentifierException {
|
||||
if (!(dso instanceof Item)) {
|
||||
// DOI are currently assigned only to Item
|
||||
return;
|
||||
}
|
||||
String doi = doiService.formatIdentifier(identifier);
|
||||
DOI doiRow = null;
|
||||
|
||||
|
@@ -148,6 +148,10 @@ public class EZIDIdentifierProvider
|
||||
throws IdentifierException {
|
||||
log.debug("register {}", dso);
|
||||
|
||||
if (!(dso instanceof Item)) {
|
||||
// DOI are currently assigned only to Item
|
||||
return null;
|
||||
}
|
||||
DSpaceObjectService<DSpaceObject> dsoService = contentServiceFactory.getDSpaceObjectService(dso);
|
||||
List<MetadataValue> identifiers = dsoService.getMetadata(dso, MD_SCHEMA, DOI_ELEMENT, DOI_QUALIFIER, null);
|
||||
for (MetadataValue identifier : identifiers) {
|
||||
@@ -171,6 +175,10 @@ public class EZIDIdentifierProvider
|
||||
public void register(Context context, DSpaceObject object, String identifier) {
|
||||
log.debug("register {} as {}", object, identifier);
|
||||
|
||||
if (!(object instanceof Item)) {
|
||||
// DOI are currently assigned only to Item
|
||||
return;
|
||||
}
|
||||
EZIDResponse response;
|
||||
try {
|
||||
EZIDRequest request = requestFactory.getInstance(loadAuthority(),
|
||||
|
@@ -13,11 +13,14 @@ import java.util.List;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.MetadataSchemaEnum;
|
||||
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.Context;
|
||||
import org.dspace.core.LogManager;
|
||||
@@ -48,7 +51,7 @@ public class HandleIdentifierProvider extends IdentifierProvider {
|
||||
@Autowired(required = true)
|
||||
protected HandleService handleService;
|
||||
@Autowired(required = true)
|
||||
protected ItemService itemService;
|
||||
protected ContentServiceFactory contentServiceFactory;
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<? extends Identifier> identifier) {
|
||||
@@ -91,7 +94,7 @@ public class HandleIdentifierProvider extends IdentifierProvider {
|
||||
String id = mint(context, dso);
|
||||
|
||||
// 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;
|
||||
populateHandleMetadata(context, item, id);
|
||||
}
|
||||
@@ -108,7 +111,7 @@ public class HandleIdentifierProvider extends IdentifierProvider {
|
||||
public void register(Context context, DSpaceObject dso, String identifier) {
|
||||
try {
|
||||
handleService.createHandle(context, dso, identifier);
|
||||
if (dso instanceof Item) {
|
||||
if (dso instanceof Item || dso instanceof Collection || dso instanceof Community) {
|
||||
Item item = (Item) dso;
|
||||
populateHandleMetadata(context, item, identifier);
|
||||
}
|
||||
@@ -220,23 +223,25 @@ public class HandleIdentifierProvider extends IdentifierProvider {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
protected void populateHandleMetadata(Context context, Item item, String handle)
|
||||
throws SQLException, IOException, AuthorizeException {
|
||||
protected void populateHandleMetadata(Context context, DSpaceObject dso, String handle)
|
||||
throws SQLException, IOException, AuthorizeException {
|
||||
String handleref = handleService.getCanonicalForm(handle);
|
||||
|
||||
DSpaceObjectService<DSpaceObject> dsoService = contentServiceFactory.getDSpaceObjectService(dso);
|
||||
|
||||
// Add handle as identifier.uri DC value.
|
||||
// First check that identifier doesn't already exist.
|
||||
boolean identifierExists = false;
|
||||
List<MetadataValue> identifiers = itemService
|
||||
.getMetadata(item, MetadataSchemaEnum.DC.getName(), "identifier", "uri", Item.ANY);
|
||||
List<MetadataValue> identifiers = dsoService
|
||||
.getMetadata(dso, MetadataSchemaEnum.DC.getName(), "identifier", "uri", Item.ANY);
|
||||
for (MetadataValue identifier : identifiers) {
|
||||
if (handleref.equals(identifier.getValue())) {
|
||||
identifierExists = true;
|
||||
}
|
||||
}
|
||||
if (!identifierExists) {
|
||||
itemService.addMetadata(context, item, MetadataSchemaEnum.DC.getName(),
|
||||
"identifier", "uri", null, handleref);
|
||||
dsoService.addMetadata(context, dso, MetadataSchemaEnum.DC.getName(),
|
||||
"identifier", "uri", null, handleref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -97,7 +97,7 @@ public class IdentifierServiceImpl implements IdentifierService {
|
||||
for (IdentifierProvider service : providers) {
|
||||
service.register(context, dso);
|
||||
}
|
||||
//Update our item
|
||||
//Update our item / collection / community
|
||||
contentServiceFactory.getDSpaceObjectService(dso).update(context, dso);
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ public class IdentifierServiceImpl implements IdentifierService {
|
||||
throw new IdentifierException("Cannot register identifier: Didn't "
|
||||
+ "find a provider that supports this identifier.");
|
||||
}
|
||||
//Update our item
|
||||
//Update our item / collection / community
|
||||
contentServiceFactory.getDSpaceObjectService(object).update(context, object);
|
||||
}
|
||||
|
||||
|
@@ -17,11 +17,14 @@ import java.util.regex.Pattern;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.MetadataSchemaEnum;
|
||||
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.Constants;
|
||||
import org.dspace.core.Context;
|
||||
@@ -65,7 +68,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
|
||||
private HandleService handleService;
|
||||
|
||||
@Autowired(required = true)
|
||||
private ItemService itemService;
|
||||
protected ContentServiceFactory contentServiceFactory;
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<? extends Identifier> identifier) {
|
||||
@@ -107,8 +110,8 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
|
||||
public String register(Context context, DSpaceObject dso) {
|
||||
String id = mint(context, dso);
|
||||
try {
|
||||
if (dso instanceof Item) {
|
||||
populateHandleMetadata(context, (Item) dso, id);
|
||||
if (dso instanceof Item || dso instanceof Collection || dso instanceof Community) {
|
||||
populateHandleMetadata(context, dso, id);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(LogManager.getHeader(context, "Error while attempting to create handle",
|
||||
@@ -410,16 +413,17 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
protected void populateHandleMetadata(Context context, Item item, String handle)
|
||||
protected void populateHandleMetadata(Context context, DSpaceObject dso, String handle)
|
||||
throws SQLException, IOException, AuthorizeException {
|
||||
String handleref = handleService.getCanonicalForm(handle);
|
||||
// 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
|
||||
// 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",
|
||||
Item.ANY);
|
||||
itemService.clearMetadata(context, item, MetadataSchemaEnum.DC.getName(),
|
||||
dsoService.clearMetadata(context, dso, MetadataSchemaEnum.DC.getName(),
|
||||
"identifier", "uri", Item.ANY);
|
||||
for (MetadataValue identifier : identifiers) {
|
||||
if (this.supports(identifier.getValue())) {
|
||||
@@ -428,8 +432,8 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
|
||||
continue;
|
||||
}
|
||||
log.debug("Preserving identifier " + identifier.getValue());
|
||||
itemService.addMetadata(context,
|
||||
item,
|
||||
dsoService.addMetadata(context,
|
||||
dso,
|
||||
identifier.getMetadataField(),
|
||||
identifier.getLanguage(),
|
||||
identifier.getValue(),
|
||||
@@ -439,9 +443,9 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
|
||||
|
||||
// Add handle as identifier.uri DC value.
|
||||
if (StringUtils.isNotBlank(handleref)) {
|
||||
itemService.addMetadata(context, item, MetadataSchemaEnum.DC.getName(),
|
||||
dsoService.addMetadata(context, dso, MetadataSchemaEnum.DC.getName(),
|
||||
"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.eperson.EPerson;
|
||||
import org.dspace.eperson.Group;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.dspace.utils.DSpace;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -159,6 +161,7 @@ public class CollectionTest extends AbstractDSpaceObjectTest {
|
||||
public void testCreate() throws Exception {
|
||||
// Allow Community ADD perms
|
||||
doNothing().when(authorizeServiceSpy).authorizeAction(context, owningCommunity, Constants.ADD);
|
||||
doNothing().when(authorizeServiceSpy).authorizeAction(context, owningCommunity, Constants.ADD, true);
|
||||
|
||||
Collection created = collectionService.create(context, owningCommunity);
|
||||
assertThat("testCreate 0", created, notNullValue());
|
||||
@@ -172,6 +175,14 @@ public class CollectionTest extends AbstractDSpaceObjectTest {
|
||||
public void testCreateWithValidHandle() throws Exception {
|
||||
// Allow Community ADD perms
|
||||
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
|
||||
// (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
|
||||
assertThat("testCreateWithValidHandle 0", created, notNullValue());
|
||||
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.eq;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.spy;
|
||||
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.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.Group;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.dspace.utils.DSpace;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
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)
|
||||
// Allow full Admin perms
|
||||
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)
|
||||
Community created = communityService.create(null, context);
|
||||
@@ -206,6 +211,14 @@ public class CommunityTest extends AbstractDSpaceObjectTest {
|
||||
public void testCreateWithValidHandle() throws Exception {
|
||||
// Allow full Admin perms
|
||||
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
|
||||
// (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
|
||||
assertThat("testCreateWithValidHandle 0", created, notNullValue());
|
||||
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 {
|
||||
// Allow current Community ADD perms
|
||||
doNothing().when(authorizeServiceSpy).authorizeAction(context, c, Constants.ADD);
|
||||
doNothing().when(authorizeServiceSpy).authorizeAction(context, c, Constants.ADD, true);
|
||||
|
||||
Collection result = collectionService.create(context, c);
|
||||
assertThat("testCreateCollectionAuth 0", result, notNullValue());
|
||||
@@ -628,6 +646,7 @@ public class CommunityTest extends AbstractDSpaceObjectTest {
|
||||
public void testAddCollectionAuth() throws Exception {
|
||||
// Allow current Community ADD perms
|
||||
doNothing().when(authorizeServiceSpy).authorizeAction(context, c, Constants.ADD);
|
||||
doNothing().when(authorizeServiceSpy).authorizeAction(context, c, Constants.ADD, true);
|
||||
|
||||
Collection col = collectionService.create(context, c);
|
||||
c.addCollection(col);
|
||||
@@ -929,7 +948,8 @@ public class CommunityTest extends AbstractDSpaceObjectTest {
|
||||
@SuppressWarnings("ObjectEqualsNull")
|
||||
public void testEquals() throws SQLException, AuthorizeException {
|
||||
// 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 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.
|
||||
* Any existing metadata value is deleted or overwritten.
|
||||
*
|
||||
* @param context the context to use.
|
||||
* @param dso the DSpace object.
|
||||
@@ -82,10 +83,52 @@ public class MetadataConverter implements DSpaceConverter<MetadataValueList, Met
|
||||
* @throws SQLException if a database 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 {
|
||||
DSpaceObjectService dsoService = contentServiceFactory.getDSpaceObjectService(dso);
|
||||
DSpaceObjectService<T> dsoService = contentServiceFactory.getDSpaceObjectService(dso);
|
||||
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()) {
|
||||
String[] seq = entry.getKey().split("\\.");
|
||||
String schema = seq[0];
|
||||
@@ -98,4 +141,5 @@ public class MetadataConverter implements DSpaceConverter<MetadataValueList, Met
|
||||
}
|
||||
dsoService.update(context, dso);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -245,7 +245,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
|
||||
}
|
||||
collection = cs.create(context, parent);
|
||||
cs.update(context, collection);
|
||||
metadataConverter.setMetadata(context, collection, collectionRest.getMetadata());
|
||||
metadataConverter.mergeMetadata(context, collection, collectionRest.getMetadata());
|
||||
} catch (SQLException 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
|
||||
@PreAuthorize("hasAuthority('ADMIN')")
|
||||
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;
|
||||
try {
|
||||
// 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);
|
||||
}
|
||||
// top-level community
|
||||
Community community = createCommunity(context, null);
|
||||
|
||||
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.");
|
||||
}
|
||||
|
||||
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();
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
CommunityRest communityRest;
|
||||
@@ -134,21 +136,15 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
|
||||
}
|
||||
|
||||
Community community;
|
||||
|
||||
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);
|
||||
cs.update(context, community);
|
||||
metadataConverter.setMetadata(context, community, communityRest.getMetadata());
|
||||
metadataConverter.mergeMetadata(context, community, communityRest.getMetadata());
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return converter.toRest(community, utils.obtainProjection());
|
||||
return community;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -11,6 +11,8 @@ import static com.jayway.jsonpath.JsonPath.read;
|
||||
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.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.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
@@ -1074,6 +1076,7 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
||||
|
||||
AtomicReference<UUID> idRef = new AtomicReference<>();
|
||||
AtomicReference<UUID> idRefNoEmbeds = new AtomicReference<>();
|
||||
AtomicReference<String> handle = new AtomicReference<>();
|
||||
try {
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
@@ -1121,6 +1124,15 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
|
||||
MetadataMatcher.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())
|
||||
)
|
||||
)))
|
||||
.andDo(result -> idRef
|
||||
.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 junit.framework.TestCase.assertEquals;
|
||||
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.is;
|
||||
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)
|
||||
AtomicReference<UUID> idRef = new AtomicReference<>();
|
||||
AtomicReference<UUID> idRefNoEmbeds = new AtomicReference<>();
|
||||
AtomicReference<String> handle = new AtomicReference<>();
|
||||
|
||||
try {
|
||||
getClient(authToken).perform(post("/api/core/communities")
|
||||
.content(mapper.writeValueAsBytes(comm))
|
||||
@@ -136,15 +140,26 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
||||
hasJsonPath("$._links.subcommunities.href", not(empty())),
|
||||
hasJsonPath("$._links.self.href", not(empty())),
|
||||
hasJsonPath("$.metadata", Matchers.allOf(
|
||||
matchMetadata("dc.description", "<p>Some cool HTML code here</p>"),
|
||||
matchMetadata("dc.description.abstract",
|
||||
"Sample top-level community created via the REST API"),
|
||||
matchMetadata("dc.description.tableofcontents", "<p>HTML News</p>"),
|
||||
matchMetadata("dc.rights", "Custom Copyright Text"),
|
||||
matchMetadata("dc.title", "Title Text")
|
||||
matchMetadata("dc.description", "<p>Some cool HTML code here</p>"),
|
||||
matchMetadata("dc.description.abstract",
|
||||
"Sample top-level community created via the REST API"),
|
||||
matchMetadata("dc.description.tableofcontents", "<p>HTML News</p>"),
|
||||
matchMetadata("dc.rights", "Custom Copyright 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
|
||||
.andDo(result -> idRef
|
||||
.set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id"))));
|
||||
@@ -233,8 +248,9 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
||||
.put("dc.title",
|
||||
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<String> handle = new AtomicReference<>();
|
||||
try {
|
||||
getClient(authToken).perform(post("/api/core/communities")
|
||||
.content(mapper.writeValueAsBytes(comm))
|
||||
@@ -253,17 +269,26 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
||||
hasJsonPath("$._links.subcommunities.href", not(empty())),
|
||||
hasJsonPath("$._links.self.href", not(empty())),
|
||||
hasJsonPath("$.metadata", Matchers.allOf(
|
||||
MetadataMatcher.matchMetadata("dc.description",
|
||||
"<p>Some cool HTML code here</p>"),
|
||||
MetadataMatcher.matchMetadata("dc.description.abstract",
|
||||
"Sample top-level community created via the REST API"),
|
||||
MetadataMatcher.matchMetadata("dc.description.tableofcontents",
|
||||
"<p>HTML News</p>"),
|
||||
MetadataMatcher.matchMetadata("dc.rights",
|
||||
"Custom Copyright Text"),
|
||||
MetadataMatcher.matchMetadata("dc.title",
|
||||
"Title Text")
|
||||
MetadataMatcher.matchMetadata("dc.description",
|
||||
"<p>Some cool HTML code here</p>"),
|
||||
MetadataMatcher.matchMetadata("dc.description.abstract",
|
||||
"Sample top-level community created via the REST API"),
|
||||
MetadataMatcher.matchMetadata("dc.description.tableofcontents",
|
||||
"<p>HTML News</p>"),
|
||||
MetadataMatcher.matchMetadata("dc.rights",
|
||||
"Custom Copyright Text"),
|
||||
MetadataMatcher.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
|
||||
|
@@ -10,6 +10,7 @@ package org.dspace.app.rest;
|
||||
import static com.jayway.jsonpath.JsonPath.read;
|
||||
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.matchMetadataDoesNotExist;
|
||||
import static org.hamcrest.Matchers.allOf;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
@@ -133,7 +134,8 @@ public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest {
|
||||
hasJsonPath("$._links.self.href", not(empty())),
|
||||
hasJsonPath("$.metadata", Matchers.allOf(
|
||||
matchMetadata("eperson.firstname", "John"),
|
||||
matchMetadata("eperson.lastname", "Doe")
|
||||
matchMetadata("eperson.lastname", "Doe"),
|
||||
matchMetadataDoesNotExist("dc.identifier.uri")
|
||||
)))))
|
||||
.andDo(result -> idRef
|
||||
.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.hasNoJsonPath;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.core.StringEndsWith;
|
||||
|
||||
/**
|
||||
* Utility class to provide convenient matchers for metadata.
|
||||
@@ -33,6 +36,25 @@ public class MetadataMatcher {
|
||||
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.
|
||||
*
|
||||
|
Reference in New Issue
Block a user