mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-17 23:13:10 +00:00
[TLC-249] Refactor to support better filter usage, PENDING and MINTED status
This commit is contained in:
@@ -9,10 +9,17 @@ package org.dspace.content;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
|
import org.dspace.content.logic.Filter;
|
||||||
|
import org.dspace.content.logic.FilterUtils;
|
||||||
|
import org.dspace.content.logic.TrueFilter;
|
||||||
import org.dspace.content.service.CollectionService;
|
import org.dspace.content.service.CollectionService;
|
||||||
import org.dspace.content.service.InstallItemService;
|
import org.dspace.content.service.InstallItemService;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
@@ -20,8 +27,12 @@ import org.dspace.core.Constants;
|
|||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.embargo.service.EmbargoService;
|
import org.dspace.embargo.service.EmbargoService;
|
||||||
import org.dspace.event.Event;
|
import org.dspace.event.Event;
|
||||||
|
import org.dspace.identifier.DOI;
|
||||||
|
import org.dspace.identifier.Handle;
|
||||||
|
import org.dspace.identifier.Identifier;
|
||||||
import org.dspace.identifier.IdentifierException;
|
import org.dspace.identifier.IdentifierException;
|
||||||
import org.dspace.identifier.service.IdentifierService;
|
import org.dspace.identifier.service.IdentifierService;
|
||||||
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,9 +53,11 @@ public class InstallItemServiceImpl implements InstallItemService {
|
|||||||
protected IdentifierService identifierService;
|
protected IdentifierService identifierService;
|
||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
protected ItemService itemService;
|
protected ItemService itemService;
|
||||||
|
@Autowired(required = false)
|
||||||
|
|
||||||
|
Logger log = LogManager.getLogger(InstallItemServiceImpl.class);
|
||||||
|
|
||||||
protected InstallItemServiceImpl() {
|
protected InstallItemServiceImpl() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -59,11 +72,17 @@ public class InstallItemServiceImpl implements InstallItemService {
|
|||||||
AuthorizeException {
|
AuthorizeException {
|
||||||
Item item = is.getItem();
|
Item item = is.getItem();
|
||||||
Collection collection = is.getCollection();
|
Collection collection = is.getCollection();
|
||||||
|
// Get map of filters to use for identifier types
|
||||||
|
Map<Class<? extends Identifier>, Filter> filters = FilterUtils.getIdentifierFilters("install");
|
||||||
try {
|
try {
|
||||||
if (suppliedHandle == null) {
|
if (suppliedHandle == null) {
|
||||||
identifierService.register(c, item);
|
// Register with the filters we've set up
|
||||||
|
identifierService.register(c, item, filters);
|
||||||
} else {
|
} else {
|
||||||
|
// This will register the handle but a pending DOI won't be compatible and so won't be registered
|
||||||
identifierService.register(c, item, suppliedHandle);
|
identifierService.register(c, item, suppliedHandle);
|
||||||
|
// Continue to register just a DOI
|
||||||
|
identifierService.register(c, item, DOI.class, filters.get(DOI.class));
|
||||||
}
|
}
|
||||||
} catch (IdentifierException e) {
|
} catch (IdentifierException e) {
|
||||||
throw new RuntimeException("Can't create an Identifier!", e);
|
throw new RuntimeException("Can't create an Identifier!", e);
|
||||||
|
@@ -24,6 +24,8 @@ import org.dspace.authorize.AuthorizeException;
|
|||||||
import org.dspace.authorize.ResourcePolicy;
|
import org.dspace.authorize.ResourcePolicy;
|
||||||
import org.dspace.authorize.service.AuthorizeService;
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
import org.dspace.content.dao.WorkspaceItemDAO;
|
import org.dspace.content.dao.WorkspaceItemDAO;
|
||||||
|
import org.dspace.content.logic.Filter;
|
||||||
|
import org.dspace.content.logic.FilterUtils;
|
||||||
import org.dspace.content.service.CollectionService;
|
import org.dspace.content.service.CollectionService;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
import org.dspace.content.service.WorkspaceItemService;
|
import org.dspace.content.service.WorkspaceItemService;
|
||||||
@@ -32,8 +34,12 @@ import org.dspace.core.Context;
|
|||||||
import org.dspace.core.LogHelper;
|
import org.dspace.core.LogHelper;
|
||||||
import org.dspace.eperson.EPerson;
|
import org.dspace.eperson.EPerson;
|
||||||
import org.dspace.event.Event;
|
import org.dspace.event.Event;
|
||||||
|
import org.dspace.identifier.DOI;
|
||||||
|
import org.dspace.identifier.DOIIdentifierProvider;
|
||||||
|
import org.dspace.identifier.Identifier;
|
||||||
import org.dspace.identifier.IdentifierException;
|
import org.dspace.identifier.IdentifierException;
|
||||||
import org.dspace.identifier.factory.IdentifierServiceFactory;
|
import org.dspace.identifier.factory.IdentifierServiceFactory;
|
||||||
|
import org.dspace.identifier.service.DOIService;
|
||||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
import org.dspace.workflow.WorkflowItem;
|
import org.dspace.workflow.WorkflowItem;
|
||||||
import org.dspace.workflow.WorkflowService;
|
import org.dspace.workflow.WorkflowService;
|
||||||
@@ -61,6 +67,8 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService {
|
|||||||
protected ItemService itemService;
|
protected ItemService itemService;
|
||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
protected WorkflowService workflowService;
|
protected WorkflowService workflowService;
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected DOIService doiService;
|
||||||
|
|
||||||
|
|
||||||
protected WorkspaceItemServiceImpl() {
|
protected WorkspaceItemServiceImpl() {
|
||||||
@@ -169,7 +177,15 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService {
|
|||||||
if (DSpaceServicesFactory.getInstance().getConfigurationService()
|
if (DSpaceServicesFactory.getInstance().getConfigurationService()
|
||||||
.getBooleanProperty("identifiers.submission.register", false)) {
|
.getBooleanProperty("identifiers.submission.register", false)) {
|
||||||
try {
|
try {
|
||||||
IdentifierServiceFactory.getInstance().getIdentifierService().register(context, item);
|
// Get map of filters to use for identifier types
|
||||||
|
Map<Class<? extends Identifier>, Filter> filters = FilterUtils.getIdentifierFilters("workspace");
|
||||||
|
IdentifierServiceFactory.getInstance().getIdentifierService().register(context, item, filters);
|
||||||
|
// Look for a DOI and move it to PENDING
|
||||||
|
DOI doi = doiService.findDOIByDSpaceObject(context, item);
|
||||||
|
if (doi != null) {
|
||||||
|
doi.setStatus(DOIIdentifierProvider.PENDING);
|
||||||
|
doiService.update(context, doi);
|
||||||
|
}
|
||||||
} catch (IdentifierException e) {
|
} catch (IdentifierException e) {
|
||||||
log.error("Could not register identifier(s) for item {}: {}", item.getID(), e.getMessage());
|
log.error("Could not register identifier(s) for item {}: {}", item.getID(), e.getMessage());
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,7 @@ import org.dspace.core.Context;
|
|||||||
*/
|
*/
|
||||||
public class DefaultFilter implements Filter {
|
public class DefaultFilter implements Filter {
|
||||||
private LogicalStatement statement;
|
private LogicalStatement statement;
|
||||||
|
private String name;
|
||||||
private final static Logger log = LogManager.getLogger();
|
private final static Logger log = LogManager.getLogger();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,4 +45,15 @@ public class DefaultFilter implements Filter {
|
|||||||
public boolean getResult(Context context, Item item) throws LogicalStatementException {
|
public boolean getResult(Context context, Item item) throws LogicalStatementException {
|
||||||
return this.statement.getResult(context, item);
|
return this.statement.getResult(context, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBeanName(String name) {
|
||||||
|
log.debug("Initialize bean " + name);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,7 @@ package org.dspace.content.logic;
|
|||||||
|
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
|
import org.springframework.beans.factory.BeanNameAware;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The interface for Filter currently doesn't add anything to LogicalStatement but inherits from it
|
* The interface for Filter currently doesn't add anything to LogicalStatement but inherits from it
|
||||||
@@ -22,7 +23,7 @@ import org.dspace.core.Context;
|
|||||||
* @author Kim Shepherd
|
* @author Kim Shepherd
|
||||||
* @see org.dspace.content.logic.DefaultFilter
|
* @see org.dspace.content.logic.DefaultFilter
|
||||||
*/
|
*/
|
||||||
public interface Filter extends LogicalStatement {
|
public interface Filter extends LogicalStatement, BeanNameAware {
|
||||||
/**
|
/**
|
||||||
* Get the result of logical evaluation for an item
|
* Get the result of logical evaluation for an item
|
||||||
* @param context DSpace context
|
* @param context DSpace context
|
||||||
@@ -32,4 +33,6 @@ public interface Filter extends LogicalStatement {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
boolean getResult(Context context, Item item) throws LogicalStatementException;
|
boolean getResult(Context context, Item item) throws LogicalStatementException;
|
||||||
|
|
||||||
|
String getName();
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,74 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.content.logic;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.dspace.identifier.DOI;
|
||||||
|
import org.dspace.identifier.Handle;
|
||||||
|
import org.dspace.identifier.Identifier;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General utility methods for logical item filtering
|
||||||
|
*
|
||||||
|
* @author Kim Shepherd
|
||||||
|
*/
|
||||||
|
public class FilterUtils {
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
ConfigurationService configurationService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a Filter by name
|
||||||
|
* @param property DSpace configuration property name (Apache Commons config)
|
||||||
|
* @return Filter or null
|
||||||
|
*/
|
||||||
|
public static Filter getFilterFromConfiguration(String property) {
|
||||||
|
String filterName = DSpaceServicesFactory.getInstance().getConfigurationService().getProperty(property);
|
||||||
|
if (filterName != null) {
|
||||||
|
return DSpaceServicesFactory.getInstance().getServiceManager().getServiceByName(filterName, Filter.class);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a Filter by name
|
||||||
|
* @param property DSpace configuration property name (Apache Commons config)
|
||||||
|
* @return Filter or null
|
||||||
|
*/
|
||||||
|
public static Filter getFilterFromConfiguration(String property, Filter defaultFilter) {
|
||||||
|
Filter filter = getFilterFromConfiguration(property);
|
||||||
|
if (filter != null) {
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
return defaultFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a map of identifier types and filters to use when creating workspace or archived items
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Map<Class<? extends Identifier>, Filter> getIdentifierFilters(String status) {
|
||||||
|
if (status == null) {
|
||||||
|
status = "install";
|
||||||
|
}
|
||||||
|
Map<Class<? extends Identifier>, Filter> filters = new HashMap<>();
|
||||||
|
// Put DOI 'can we create DOI on install / workspace?' filter
|
||||||
|
Filter filter = FilterUtils.getFilterFromConfiguration("identifiers.submission.filter." + status);
|
||||||
|
// A null filter should be handled safely by the identifier provier (default, or "always true")
|
||||||
|
filters.put(DOI.class, filter);
|
||||||
|
// This won't have an affect until handle providers implement filtering, but is an example of
|
||||||
|
// how the filters can be used for other types
|
||||||
|
filters.put(Handle.class, new TrueFilter());
|
||||||
|
return filters;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.content.logic;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extremely simple filter that always returns true!
|
||||||
|
* Useful to pass to methods that expect a filter, in order to effectively say "all items".
|
||||||
|
* This could be configured in Spring XML but it is more stable and reliable to have it hard-coded here
|
||||||
|
* so that any broken configuration doesn't silently break parts of DSpace that expect it to work.
|
||||||
|
*
|
||||||
|
* @author Kim Shepherd
|
||||||
|
*/
|
||||||
|
public class TrueFilter implements Filter {
|
||||||
|
private String name;
|
||||||
|
private final static Logger log = LogManager.getLogger();
|
||||||
|
|
||||||
|
public boolean getResult(Context context, Item item) throws LogicalStatementException {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBeanName(String name) {
|
||||||
|
log.debug("Initialize bean " + name);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.content.logic.condition;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.logic.LogicalStatementException;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A condition that returns true if the item is withdrawn
|
||||||
|
*
|
||||||
|
* @author Kim Shepherd
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
public class IsArchivedCondition extends AbstractCondition {
|
||||||
|
private final static Logger log = LogManager.getLogger();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if item is withdrawn
|
||||||
|
* Return false if not
|
||||||
|
* @param context DSpace context
|
||||||
|
* @param item Item to evaluate
|
||||||
|
* @return boolean result of evaluation
|
||||||
|
* @throws LogicalStatementException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean getResult(Context context, Item item) throws LogicalStatementException {
|
||||||
|
log.debug("Result of isWithdrawn is " + item.isArchived());
|
||||||
|
return item.isArchived();
|
||||||
|
}
|
||||||
|
}
|
@@ -13,6 +13,9 @@ import java.sql.SQLException;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.logic.Filter;
|
||||||
|
import org.dspace.content.logic.FilterUtils;
|
||||||
|
import org.dspace.content.logic.TrueFilter;
|
||||||
import org.dspace.curate.AbstractCurationTask;
|
import org.dspace.curate.AbstractCurationTask;
|
||||||
import org.dspace.curate.Curator;
|
import org.dspace.curate.Curator;
|
||||||
import org.dspace.identifier.DOIIdentifierProvider;
|
import org.dspace.identifier.DOIIdentifierProvider;
|
||||||
@@ -46,8 +49,6 @@ public class RegisterDOI extends AbstractCurationTask {
|
|||||||
@Override
|
@Override
|
||||||
public void init(Curator curator, String taskId) throws IOException {
|
public void init(Curator curator, String taskId) throws IOException {
|
||||||
super.init(curator, taskId);
|
super.init(curator, taskId);
|
||||||
// Get 'skip filter' behaviour from configuration, with a default value of 'true'
|
|
||||||
skipFilter = configurationService.getBooleanProperty(PLUGIN_PREFIX + ".skip-filter", true);
|
|
||||||
// Get distribution behaviour from configuration, with a default value of 'false'
|
// Get distribution behaviour from configuration, with a default value of 'false'
|
||||||
distributed = configurationService.getBooleanProperty(PLUGIN_PREFIX + ".distributed", false);
|
distributed = configurationService.getBooleanProperty(PLUGIN_PREFIX + ".distributed", false);
|
||||||
log.debug("PLUGIN_PREFIX = " + PLUGIN_PREFIX + ", skipFilter = " + skipFilter +
|
log.debug("PLUGIN_PREFIX = " + PLUGIN_PREFIX + ", skipFilter = " + skipFilter +
|
||||||
@@ -118,8 +119,9 @@ public class RegisterDOI extends AbstractCurationTask {
|
|||||||
String doi = null;
|
String doi = null;
|
||||||
// Attempt DOI registration and report successes and failures
|
// Attempt DOI registration and report successes and failures
|
||||||
try {
|
try {
|
||||||
log.debug("Registering DOI with skipFilter = " + skipFilter);
|
Filter filter = FilterUtils.getFilterFromConfiguration("identifiers.submission.filter.curation",
|
||||||
doi = provider.register(Curator.curationContext(), item, skipFilter);
|
new TrueFilter());
|
||||||
|
doi = provider.register(Curator.curationContext(), item, filter);
|
||||||
if (doi != null) {
|
if (doi != null) {
|
||||||
String message = "New DOI minted in database for item " + item.getHandle() + ": " + doi
|
String message = "New DOI minted in database for item " + item.getHandle() + ": " + doi
|
||||||
+ ". This DOI will be registered online with the DOI provider when the queue is next run";
|
+ ". This DOI will be registered online with the DOI provider when the queue is next run";
|
||||||
|
@@ -21,6 +21,7 @@ import org.dspace.content.MetadataValue;
|
|||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
import org.dspace.content.logic.Filter;
|
import org.dspace.content.logic.Filter;
|
||||||
import org.dspace.content.logic.LogicalStatementException;
|
import org.dspace.content.logic.LogicalStatementException;
|
||||||
|
import org.dspace.content.logic.TrueFilter;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
@@ -44,6 +45,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
* <p>Any identifier a method of this class returns is a string in the following format: doi:10.123/456.</p>
|
* <p>Any identifier a method of this class returns is a string in the following format: doi:10.123/456.</p>
|
||||||
*
|
*
|
||||||
* @author Pascal-Nicolas Becker
|
* @author Pascal-Nicolas Becker
|
||||||
|
* @author Kim Shepherd
|
||||||
*/
|
*/
|
||||||
public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
||||||
private static final Logger log = LoggerFactory.getLogger(DOIIdentifierProvider.class);
|
private static final Logger log = LoggerFactory.getLogger(DOIIdentifierProvider.class);
|
||||||
@@ -71,16 +73,29 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
public static final String MD_SCHEMA = "dc";
|
public static final String MD_SCHEMA = "dc";
|
||||||
public static final String DOI_ELEMENT = "identifier";
|
public static final String DOI_ELEMENT = "identifier";
|
||||||
public static final String DOI_QUALIFIER = "uri";
|
public static final String DOI_QUALIFIER = "uri";
|
||||||
|
// The DOI is queued for registered with the service provider
|
||||||
public static final Integer TO_BE_REGISTERED = 1;
|
public static final Integer TO_BE_REGISTERED = 1;
|
||||||
|
// The DOI is queued for reservation with the service provider
|
||||||
public static final Integer TO_BE_RESERVED = 2;
|
public static final Integer TO_BE_RESERVED = 2;
|
||||||
|
// The DOI has been registered online
|
||||||
public static final Integer IS_REGISTERED = 3;
|
public static final Integer IS_REGISTERED = 3;
|
||||||
|
// The DOI has been reserved online
|
||||||
public static final Integer IS_RESERVED = 4;
|
public static final Integer IS_RESERVED = 4;
|
||||||
|
// The DOI is reserved and requires an updated metadata record to be sent to the service provider
|
||||||
public static final Integer UPDATE_RESERVED = 5;
|
public static final Integer UPDATE_RESERVED = 5;
|
||||||
|
// The DOI is registered and requires an updated metadata record to be sent to the service provider
|
||||||
public static final Integer UPDATE_REGISTERED = 6;
|
public static final Integer UPDATE_REGISTERED = 6;
|
||||||
|
// The DOI metadata record should be updated before performing online registration
|
||||||
public static final Integer UPDATE_BEFORE_REGISTRATION = 7;
|
public static final Integer UPDATE_BEFORE_REGISTRATION = 7;
|
||||||
|
// The DOI will be deleted locally and marked as deleted in the DOI service provider
|
||||||
public static final Integer TO_BE_DELETED = 8;
|
public static final Integer TO_BE_DELETED = 8;
|
||||||
|
// The DOI has been deleted and is no longer associated with an item
|
||||||
public static final Integer DELETED = 9;
|
public static final Integer DELETED = 9;
|
||||||
|
// The DOI is created in the database and is waiting for either successful filter check on item install or
|
||||||
|
// manual intervention by an administrator to proceed to reservation or registration
|
||||||
|
public static final Integer PENDING = 10;
|
||||||
|
// The DOI is created in the database, but no more context is known
|
||||||
|
public static final Integer MINTED = 11;
|
||||||
|
|
||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
protected DOIService doiService;
|
protected DOIService doiService;
|
||||||
@@ -89,8 +104,6 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
@Autowired(required = true)
|
@Autowired(required = true)
|
||||||
protected ItemService itemService;
|
protected ItemService itemService;
|
||||||
|
|
||||||
protected Filter filterService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Empty / default constructor for Spring
|
* Empty / default constructor for Spring
|
||||||
*/
|
*/
|
||||||
@@ -153,16 +166,6 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
this.connector = connector;
|
this.connector = connector;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the Filter to use when testing items to see if a DOI should be registered
|
|
||||||
* Spring will use this setter to set the filter from the configured property in identifier-services.xml
|
|
||||||
* @param filterService - an object implementing the org.dspace.content.logic.Filter interface
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setFilterService(Filter filterService) {
|
|
||||||
this.filterService = filterService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This identifier provider supports identifiers of type
|
* This identifier provider supports identifiers of type
|
||||||
* {@link org.dspace.identifier.DOI}.
|
* {@link org.dspace.identifier.DOI}.
|
||||||
@@ -206,7 +209,7 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
@Override
|
@Override
|
||||||
public String register(Context context, DSpaceObject dso)
|
public String register(Context context, DSpaceObject dso)
|
||||||
throws IdentifierException {
|
throws IdentifierException {
|
||||||
return register(context, dso, false);
|
return register(context, dso, this.filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -219,29 +222,29 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
@Override
|
@Override
|
||||||
public void register(Context context, DSpaceObject dso, String identifier)
|
public void register(Context context, DSpaceObject dso, String identifier)
|
||||||
throws IdentifierException {
|
throws IdentifierException {
|
||||||
register(context, dso, identifier, false);
|
register(context, dso, identifier, this.filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a new DOI for a given DSpaceObject
|
* Register a new DOI for a given DSpaceObject
|
||||||
* @param context - DSpace context
|
* @param context - DSpace context
|
||||||
* @param dso - DSpaceObject identified by the new DOI
|
* @param dso - DSpaceObject identified by the new DOI
|
||||||
* @param skipFilter - boolean indicating whether to skip any filtering of items before performing registration
|
* @param filter - Logical item filter to determine whether this identifier should be registered
|
||||||
* @throws IdentifierException
|
* @throws IdentifierException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String register(Context context, DSpaceObject dso, boolean skipFilter)
|
public String register(Context context, DSpaceObject dso, Filter filter)
|
||||||
throws IdentifierException {
|
throws IdentifierException {
|
||||||
if (!(dso instanceof Item)) {
|
if (!(dso instanceof Item)) {
|
||||||
// DOI are currently assigned only to Item
|
// DOI are currently assigned only to Item
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String doi = mint(context, dso, skipFilter);
|
String doi = mint(context, dso, filter);
|
||||||
|
|
||||||
// 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.
|
||||||
register(context, dso, doi, skipFilter);
|
register(context, dso, doi, filter);
|
||||||
return doi;
|
return doi;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,11 +253,11 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
* @param context - DSpace context
|
* @param context - DSpace context
|
||||||
* @param dso - DSpaceObject identified by the new DOI
|
* @param dso - DSpaceObject identified by the new DOI
|
||||||
* @param identifier - String containing the DOI to register
|
* @param identifier - String containing the DOI to register
|
||||||
* @param skipFilter - boolean indicating whether to skip any filtering of items before performing registration
|
* @param filter - Logical item filter to determine whether this identifier should be registered
|
||||||
* @throws IdentifierException
|
* @throws IdentifierException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void register(Context context, DSpaceObject dso, String identifier, boolean skipFilter)
|
public void register(Context context, DSpaceObject dso, String identifier, Filter filter)
|
||||||
throws IdentifierException {
|
throws IdentifierException {
|
||||||
if (!(dso instanceof Item)) {
|
if (!(dso instanceof Item)) {
|
||||||
// DOI are currently assigned only to Item
|
// DOI are currently assigned only to Item
|
||||||
@@ -265,7 +268,7 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
|
|
||||||
// search DOI in our db
|
// search DOI in our db
|
||||||
try {
|
try {
|
||||||
doiRow = loadOrCreateDOI(context, dso, doi, skipFilter);
|
doiRow = loadOrCreateDOI(context, dso, doi, filter);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
log.error("Error in databse connection: " + ex.getMessage());
|
log.error("Error in databse connection: " + ex.getMessage());
|
||||||
throw new RuntimeException("Error in database conncetion.", ex);
|
throw new RuntimeException("Error in database conncetion.", ex);
|
||||||
@@ -277,7 +280,6 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
+ "is marked as DELETED.", DOIIdentifierException.DOI_IS_DELETED);
|
+ "is marked as DELETED.", DOIIdentifierException.DOI_IS_DELETED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check status of DOI
|
|
||||||
if (IS_REGISTERED.equals(doiRow.getStatus())) {
|
if (IS_REGISTERED.equals(doiRow.getStatus())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -290,6 +292,7 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
log.warn("SQLException while changing status of DOI {} to be registered.", doi);
|
log.warn("SQLException while changing status of DOI {} to be registered.", doi);
|
||||||
throw new RuntimeException(sqle);
|
throw new RuntimeException(sqle);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -309,7 +312,7 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
@Override
|
@Override
|
||||||
public void reserve(Context context, DSpaceObject dso, String identifier)
|
public void reserve(Context context, DSpaceObject dso, String identifier)
|
||||||
throws IdentifierException, IllegalArgumentException {
|
throws IdentifierException, IllegalArgumentException {
|
||||||
reserve(context, dso, identifier, false);
|
reserve(context, dso, identifier, this.filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -317,20 +320,18 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
* @param context - DSpace context
|
* @param context - DSpace context
|
||||||
* @param dso - DSpaceObject identified by this DOI
|
* @param dso - DSpaceObject identified by this DOI
|
||||||
* @param identifier - String containing the DOI to reserve
|
* @param identifier - String containing the DOI to reserve
|
||||||
* @param skipFilter - boolean indicating whether to skip any filtering of items before performing reservation
|
* @param filter - Logical item filter to determine whether this identifier should be reserved
|
||||||
* @throws IdentifierException
|
* @throws IdentifierException
|
||||||
* @throws IllegalArgumentException
|
* @throws IllegalArgumentException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void reserve(Context context, DSpaceObject dso, String identifier, boolean skipFilter)
|
public void reserve(Context context, DSpaceObject dso, String identifier, Filter filter)
|
||||||
throws IdentifierException, IllegalArgumentException {
|
throws IdentifierException, IllegalArgumentException {
|
||||||
String doi = doiService.formatIdentifier(identifier);
|
String doi = doiService.formatIdentifier(identifier);
|
||||||
DOI doiRow = null;
|
DOI doiRow = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// if the doi is in our db already loadOrCreateDOI just returns.
|
doiRow = loadOrCreateDOI(context, dso, doi, filter);
|
||||||
// if it is not loadOrCreateDOI safes the doi.
|
|
||||||
doiRow = loadOrCreateDOI(context, dso, doi, skipFilter);
|
|
||||||
} catch (SQLException sqle) {
|
} catch (SQLException sqle) {
|
||||||
throw new RuntimeException(sqle);
|
throw new RuntimeException(sqle);
|
||||||
}
|
}
|
||||||
@@ -359,7 +360,7 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
*/
|
*/
|
||||||
public void reserveOnline(Context context, DSpaceObject dso, String identifier)
|
public void reserveOnline(Context context, DSpaceObject dso, String identifier)
|
||||||
throws IdentifierException, IllegalArgumentException, SQLException {
|
throws IdentifierException, IllegalArgumentException, SQLException {
|
||||||
reserveOnline(context, dso, identifier, false);
|
reserveOnline(context, dso, identifier, this.filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -367,16 +368,16 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
* @param context - DSpace context
|
* @param context - DSpace context
|
||||||
* @param dso - DSpaceObject identified by this DOI
|
* @param dso - DSpaceObject identified by this DOI
|
||||||
* @param identifier - String containing the DOI to reserve
|
* @param identifier - String containing the DOI to reserve
|
||||||
* @param skipFilter - skip the filters for {@link checkMintable(Context, DSpaceObject)}
|
* @param filter - Logical item filter to determine whether this identifier should be reserved online
|
||||||
* @throws IdentifierException
|
* @throws IdentifierException
|
||||||
* @throws IllegalArgumentException
|
* @throws IllegalArgumentException
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
*/
|
*/
|
||||||
public void reserveOnline(Context context, DSpaceObject dso, String identifier, boolean skipFilter)
|
public void reserveOnline(Context context, DSpaceObject dso, String identifier, Filter filter)
|
||||||
throws IdentifierException, IllegalArgumentException, SQLException {
|
throws IdentifierException, IllegalArgumentException, SQLException {
|
||||||
String doi = doiService.formatIdentifier(identifier);
|
String doi = doiService.formatIdentifier(identifier);
|
||||||
// get TableRow and ensure DOI belongs to dso regarding our db
|
// get TableRow and ensure DOI belongs to dso regarding our db
|
||||||
DOI doiRow = loadOrCreateDOI(context, dso, doi, skipFilter);
|
DOI doiRow = loadOrCreateDOI(context, dso, doi, filter);
|
||||||
|
|
||||||
if (DELETED.equals(doiRow.getStatus()) || TO_BE_DELETED.equals(doiRow.getStatus())) {
|
if (DELETED.equals(doiRow.getStatus()) || TO_BE_DELETED.equals(doiRow.getStatus())) {
|
||||||
throw new DOIIdentifierException("You tried to reserve a DOI that "
|
throw new DOIIdentifierException("You tried to reserve a DOI that "
|
||||||
@@ -402,7 +403,7 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
public void registerOnline(Context context, DSpaceObject dso, String identifier)
|
public void registerOnline(Context context, DSpaceObject dso, String identifier)
|
||||||
throws IdentifierException, IllegalArgumentException, SQLException {
|
throws IdentifierException, IllegalArgumentException, SQLException {
|
||||||
|
|
||||||
registerOnline(context, dso, identifier, false);
|
registerOnline(context, dso, identifier, this.filter);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,18 +412,17 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
* @param context - DSpace context
|
* @param context - DSpace context
|
||||||
* @param dso - DSpaceObject identified by this DOI
|
* @param dso - DSpaceObject identified by this DOI
|
||||||
* @param identifier - String containing the DOI to register
|
* @param identifier - String containing the DOI to register
|
||||||
* @param skipFilter - skip filters for {@link checkMintable(Context, DSpaceObject)}
|
* @param filter - Logical item filter to determine whether this identifier should be registered online
|
||||||
* @throws IdentifierException
|
* @throws IdentifierException
|
||||||
* @throws IllegalArgumentException
|
* @throws IllegalArgumentException
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
*/
|
*/
|
||||||
public void registerOnline(Context context, DSpaceObject dso, String identifier, boolean skipFilter)
|
public void registerOnline(Context context, DSpaceObject dso, String identifier, Filter filter)
|
||||||
throws IdentifierException, IllegalArgumentException, SQLException {
|
throws IdentifierException, IllegalArgumentException, SQLException {
|
||||||
log.debug("registerOnline: skipFilter is " + skipFilter);
|
|
||||||
|
|
||||||
String doi = doiService.formatIdentifier(identifier);
|
String doi = doiService.formatIdentifier(identifier);
|
||||||
// get TableRow and ensure DOI belongs to dso regarding our db
|
// get TableRow and ensure DOI belongs to dso regarding our db
|
||||||
DOI doiRow = loadOrCreateDOI(context, dso, doi, skipFilter);
|
DOI doiRow = loadOrCreateDOI(context, dso, doi, filter);
|
||||||
|
|
||||||
if (DELETED.equals(doiRow.getStatus()) || TO_BE_DELETED.equals(doiRow.getStatus())) {
|
if (DELETED.equals(doiRow.getStatus()) || TO_BE_DELETED.equals(doiRow.getStatus())) {
|
||||||
throw new DOIIdentifierException("You tried to register a DOI that "
|
throw new DOIIdentifierException("You tried to register a DOI that "
|
||||||
@@ -435,7 +435,7 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
} catch (DOIIdentifierException die) {
|
} catch (DOIIdentifierException die) {
|
||||||
// do we have to reserve DOI before we can register it?
|
// do we have to reserve DOI before we can register it?
|
||||||
if (die.getCode() == DOIIdentifierException.RESERVE_FIRST) {
|
if (die.getCode() == DOIIdentifierException.RESERVE_FIRST) {
|
||||||
this.reserveOnline(context, dso, identifier, skipFilter);
|
this.reserveOnline(context, dso, identifier, filter);
|
||||||
connector.registerDOI(context, dso, doi);
|
connector.registerDOI(context, dso, doi);
|
||||||
} else {
|
} else {
|
||||||
throw die;
|
throw die;
|
||||||
@@ -471,17 +471,22 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
throws IdentifierException, IllegalArgumentException, SQLException {
|
throws IdentifierException, IllegalArgumentException, SQLException {
|
||||||
|
|
||||||
String doi = doiService.formatIdentifier(identifier);
|
String doi = doiService.formatIdentifier(identifier);
|
||||||
|
// Use the default filter unless we find the object
|
||||||
boolean skipFilter = false;
|
Filter updateFilter = this.filter;
|
||||||
|
|
||||||
if (doiService.findDOIByDSpaceObject(context, dso) != null) {
|
if (doiService.findDOIByDSpaceObject(context, dso) != null) {
|
||||||
// We can skip the filter here since we know the DOI already exists for the item
|
// We can skip the filter here since we know the DOI already exists for the item
|
||||||
log.debug("updateMetadata: found DOIByDSpaceObject: " +
|
log.debug("updateMetadata: found DOIByDSpaceObject: " +
|
||||||
doiService.findDOIByDSpaceObject(context, dso).getDoi());
|
doiService.findDOIByDSpaceObject(context, dso).getDoi());
|
||||||
skipFilter = true;
|
updateFilter = new TrueFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
DOI doiRow = loadOrCreateDOI(context, dso, doi, skipFilter);
|
DOI doiRow = loadOrCreateDOI(context, dso, doi, updateFilter);
|
||||||
|
|
||||||
|
if (PENDING.equals(doiRow.getStatus())) {
|
||||||
|
log.info("Not updating metadata for PENDING doi: " + doi);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (DELETED.equals(doiRow.getStatus()) || TO_BE_DELETED.equals(doiRow.getStatus())) {
|
if (DELETED.equals(doiRow.getStatus()) || TO_BE_DELETED.equals(doiRow.getStatus())) {
|
||||||
throw new DOIIdentifierException("You tried to register a DOI that "
|
throw new DOIIdentifierException("You tried to register a DOI that "
|
||||||
@@ -571,19 +576,19 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
@Override
|
@Override
|
||||||
public String mint(Context context, DSpaceObject dso)
|
public String mint(Context context, DSpaceObject dso)
|
||||||
throws IdentifierException {
|
throws IdentifierException {
|
||||||
return mint(context, dso, false);
|
return mint(context, dso, this.filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mint a new DOI in DSpace - this is usually the first step of registration
|
* Mint a new DOI in DSpace - this is usually the first step of registration
|
||||||
* @param context - DSpace context
|
* @param context - DSpace context
|
||||||
* @param dso - DSpaceObject identified by the new identifier
|
* @param dso - DSpaceObject identified by the new identifier
|
||||||
* @param skipFilter - boolean indicating whether to skip any filtering of items before minting.
|
* @param filter - Logical item filter to determine whether this identifier should be registered
|
||||||
* @return a String containing the new identifier
|
* @return a String containing the new identifier
|
||||||
* @throws IdentifierException
|
* @throws IdentifierException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String mint(Context context, DSpaceObject dso, boolean skipFilter) throws IdentifierException {
|
public String mint(Context context, DSpaceObject dso, Filter filter) throws IdentifierException {
|
||||||
|
|
||||||
String doi = null;
|
String doi = null;
|
||||||
try {
|
try {
|
||||||
@@ -597,7 +602,7 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
}
|
}
|
||||||
if (null == doi) {
|
if (null == doi) {
|
||||||
try {
|
try {
|
||||||
DOI doiRow = loadOrCreateDOI(context, dso, null, skipFilter);
|
DOI doiRow = loadOrCreateDOI(context, dso, null, filter);
|
||||||
doi = DOI.SCHEME + doiRow.getDoi();
|
doi = DOI.SCHEME + doiRow.getDoi();
|
||||||
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
@@ -895,7 +900,7 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
*/
|
*/
|
||||||
protected DOI loadOrCreateDOI(Context context, DSpaceObject dso, String doiIdentifier)
|
protected DOI loadOrCreateDOI(Context context, DSpaceObject dso, String doiIdentifier)
|
||||||
throws SQLException, DOIIdentifierException, IdentifierNotApplicableException {
|
throws SQLException, DOIIdentifierException, IdentifierNotApplicableException {
|
||||||
return loadOrCreateDOI(context, dso, doiIdentifier, false);
|
return loadOrCreateDOI(context, dso, doiIdentifier, this.filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -910,13 +915,13 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
* @param context - DSpace context
|
* @param context - DSpace context
|
||||||
* @param dso - DSpaceObject to identify
|
* @param dso - DSpaceObject to identify
|
||||||
* @param doiIdentifier - DOI to load or create (null to mint a new one)
|
* @param doiIdentifier - DOI to load or create (null to mint a new one)
|
||||||
* @param skipFilter - Whether or not to skip the filters for the checkMintable() check
|
* @param filter - Logical item filter to determine whether this identifier should be registered
|
||||||
* @return
|
* @return
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
* @throws DOIIdentifierException
|
* @throws DOIIdentifierException
|
||||||
* @throws org.dspace.identifier.IdentifierNotApplicableException passed through.
|
* @throws org.dspace.identifier.IdentifierNotApplicableException passed through.
|
||||||
*/
|
*/
|
||||||
protected DOI loadOrCreateDOI(Context context, DSpaceObject dso, String doiIdentifier, boolean skipFilter)
|
protected DOI loadOrCreateDOI(Context context, DSpaceObject dso, String doiIdentifier, Filter filter)
|
||||||
throws SQLException, DOIIdentifierException, IdentifierNotApplicableException {
|
throws SQLException, DOIIdentifierException, IdentifierNotApplicableException {
|
||||||
|
|
||||||
DOI doi = null;
|
DOI doi = null;
|
||||||
@@ -954,6 +959,8 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
// doi is assigned to a DSO; is it assigned to our specific dso?
|
// doi is assigned to a DSO; is it assigned to our specific dso?
|
||||||
// check if DOI already belongs to dso
|
// check if DOI already belongs to dso
|
||||||
if (dso.getID().equals(doi.getDSpaceObject().getID())) {
|
if (dso.getID().equals(doi.getDSpaceObject().getID())) {
|
||||||
|
// Before we return this, check the filter
|
||||||
|
checkMintable(context, filter, dso);
|
||||||
return doi;
|
return doi;
|
||||||
} else {
|
} else {
|
||||||
throw new DOIIdentifierException("Trying to create a DOI " +
|
throw new DOIIdentifierException("Trying to create a DOI " +
|
||||||
@@ -963,15 +970,8 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we did not find the doi in the database or shall reassign it. Before doing so, we should check if a
|
// Check if this item is eligible for minting. An IdentifierNotApplicableException will be thrown if not.
|
||||||
// filter is in place to prevent the creation of new DOIs for certain items.
|
checkMintable(context, filter, dso);
|
||||||
if (skipFilter) {
|
|
||||||
log.warn("loadOrCreateDOI: Skipping default item filter");
|
|
||||||
} else {
|
|
||||||
// Find out if we're allowed to create a DOI
|
|
||||||
// throws an exception if creation of a new DOI is prohibited by a filter
|
|
||||||
checkMintable(context, dso);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check prefix
|
// check prefix
|
||||||
if (!doiIdentifier.startsWith(this.getPrefix() + "/")) {
|
if (!doiIdentifier.startsWith(this.getPrefix() + "/")) {
|
||||||
@@ -984,15 +984,8 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
doi = doiService.create(context);
|
doi = doiService.create(context);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We need to generate a new DOI. Before doing so, we should check if a
|
// Check if this item is eligible for minting. An IdentifierNotApplicableException will be thrown if not.
|
||||||
// filter is in place to prevent the creation of new DOIs for certain items.
|
checkMintable(context, filter, dso);
|
||||||
if (skipFilter) {
|
|
||||||
log.warn("loadOrCreateDOI: Skipping default item filter");
|
|
||||||
} else {
|
|
||||||
// Find out if we're allowed to create a DOI
|
|
||||||
// throws an exception if creation of a new DOI is prohibited by a filter
|
|
||||||
checkMintable(context, dso);
|
|
||||||
}
|
|
||||||
|
|
||||||
doi = doiService.create(context);
|
doi = doiService.create(context);
|
||||||
doiIdentifier = this.getPrefix() + "/" + this.getNamespaceSeparator() +
|
doiIdentifier = this.getPrefix() + "/" + this.getNamespaceSeparator() +
|
||||||
@@ -1002,7 +995,7 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
// prepare new doiRow
|
// prepare new doiRow
|
||||||
doi.setDoi(doiIdentifier);
|
doi.setDoi(doiIdentifier);
|
||||||
doi.setDSpaceObject(dso);
|
doi.setDSpaceObject(dso);
|
||||||
doi.setStatus(null);
|
doi.setStatus(MINTED);
|
||||||
try {
|
try {
|
||||||
doiService.update(context, doi);
|
doiService.update(context, doi);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
@@ -1102,20 +1095,26 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
/**
|
/**
|
||||||
* Checks to see if an item can have a DOI minted, using the configured logical filter
|
* Checks to see if an item can have a DOI minted, using the configured logical filter
|
||||||
* @param context
|
* @param context
|
||||||
|
* @param filter Logical item filter to apply
|
||||||
* @param dso The item to be evaluated
|
* @param dso The item to be evaluated
|
||||||
* @throws DOIIdentifierNotApplicableException
|
* @throws DOIIdentifierNotApplicableException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void checkMintable(Context context, DSpaceObject dso) throws DOIIdentifierNotApplicableException {
|
public void checkMintable(Context context, Filter filter, DSpaceObject dso)
|
||||||
|
throws DOIIdentifierNotApplicableException {
|
||||||
|
if (filter == null) {
|
||||||
|
// If a null filter was passed and we have a good default filter to apply, apply it.
|
||||||
|
// Otherwise set to TrueFilter which means "no filtering"
|
||||||
|
filter = Objects.requireNonNullElseGet(this.filter, TrueFilter::new);
|
||||||
|
}
|
||||||
// If the check fails, an exception will be thrown to be caught by the calling method
|
// If the check fails, an exception will be thrown to be caught by the calling method
|
||||||
if (this.filterService != null && contentServiceFactory
|
if (contentServiceFactory.getDSpaceObjectService(dso).getTypeText(dso).equals("ITEM")) {
|
||||||
.getDSpaceObjectService(dso).getTypeText(dso).equals("ITEM")) {
|
|
||||||
try {
|
try {
|
||||||
boolean result = filterService.getResult(context, (Item) dso);
|
boolean result = filter.getResult(context, (Item) dso);
|
||||||
log.debug("Result of filter for " + dso.getHandle() + " is " + result);
|
log.debug("Result of filter for " + dso.getHandle() + " is " + result);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
throw new DOIIdentifierNotApplicableException("Item " + dso.getHandle() +
|
throw new DOIIdentifierNotApplicableException("Item " + dso.getHandle() +
|
||||||
" was evaluated as 'false' by the item filter, not minting");
|
" was evaluated as 'false' by the item filter, not minting");
|
||||||
}
|
}
|
||||||
} catch (LogicalStatementException e) {
|
} catch (LogicalStatementException e) {
|
||||||
log.error("Error evaluating item with logical filter: " + e.getLocalizedMessage());
|
log.error("Error evaluating item with logical filter: " + e.getLocalizedMessage());
|
||||||
@@ -1125,4 +1124,16 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
|||||||
log.debug("DOI Identifier Provider: filterService is null (ie. don't prevent DOI minting)");
|
log.debug("DOI Identifier Provider: filterService is null (ie. don't prevent DOI minting)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if an item can have a DOI minted, using the configured logical filter
|
||||||
|
* @param context
|
||||||
|
* @param dso The item to be evaluated
|
||||||
|
* @throws DOIIdentifierNotApplicableException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void checkMintable(Context context, DSpaceObject dso) throws DOIIdentifierNotApplicableException {
|
||||||
|
checkMintable(context, this.filter, dso);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@@ -12,8 +12,8 @@ import java.sql.SQLException;
|
|||||||
|
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.logic.Filter;
|
import org.dspace.content.logic.Filter;
|
||||||
|
import org.dspace.content.logic.TrueFilter;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This abstract class adds extra method signatures so that implementing IdentifierProviders can
|
* This abstract class adds extra method signatures so that implementing IdentifierProviders can
|
||||||
@@ -24,26 +24,28 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
*/
|
*/
|
||||||
public abstract class FilteredIdentifierProvider extends IdentifierProvider {
|
public abstract class FilteredIdentifierProvider extends IdentifierProvider {
|
||||||
|
|
||||||
protected Filter filterService;
|
protected Filter filter = new TrueFilter();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setter for spring to set the filter service from the property in configuration XML
|
* Setter for spring to set the default filter from the property in configuration XML
|
||||||
* @param filterService - an object implementing the org.dspace.content.logic.Filter interface
|
* @param filter - an object implementing the org.dspace.content.logic.Filter interface
|
||||||
*/
|
*/
|
||||||
@Autowired
|
public void setFilter(Filter filter) {
|
||||||
public void setFilterService(Filter filterService) {
|
this.filter = filter;
|
||||||
this.filterService = filterService;
|
if (this.filter == null) {
|
||||||
|
this.filter = new TrueFilter();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a new identifier for a given DSpaceObject
|
* Register a new identifier for a given DSpaceObject
|
||||||
* @param context - DSpace context
|
* @param context - DSpace context
|
||||||
* @param dso - DSpaceObject to use for identifier registration
|
* @param dso - DSpaceObject to use for identifier registration
|
||||||
* @param skipFilter - boolean indicating whether to skip any filtering of items before performing registration
|
* @param filter - Logical item filter to determine whether this identifier should be registered
|
||||||
* @return identifier
|
* @return identifier
|
||||||
* @throws IdentifierException
|
* @throws IdentifierException
|
||||||
*/
|
*/
|
||||||
public abstract String register(Context context, DSpaceObject dso, boolean skipFilter)
|
public abstract String register(Context context, DSpaceObject dso, Filter filter)
|
||||||
throws IdentifierException;
|
throws IdentifierException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,10 +53,10 @@ public abstract class FilteredIdentifierProvider extends IdentifierProvider {
|
|||||||
* @param context - DSpace context
|
* @param context - DSpace context
|
||||||
* @param dso - DSpaceObject identified by the new identifier
|
* @param dso - DSpaceObject identified by the new identifier
|
||||||
* @param identifier - String containing the identifier to register
|
* @param identifier - String containing the identifier to register
|
||||||
* @param skipFilter - boolean indicating whether to skip any filtering of items before performing registration
|
* @param filter - Logical item filter to determine whether this identifier should be registered
|
||||||
* @throws IdentifierException
|
* @throws IdentifierException
|
||||||
*/
|
*/
|
||||||
public abstract void register(Context context, DSpaceObject dso, String identifier, boolean skipFilter)
|
public abstract void register(Context context, DSpaceObject dso, String identifier, Filter filter)
|
||||||
throws IdentifierException;
|
throws IdentifierException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,23 +64,23 @@ public abstract class FilteredIdentifierProvider extends IdentifierProvider {
|
|||||||
* @param context - DSpace context
|
* @param context - DSpace context
|
||||||
* @param dso - DSpaceObject identified by this identifier
|
* @param dso - DSpaceObject identified by this identifier
|
||||||
* @param identifier - String containing the identifier to reserve
|
* @param identifier - String containing the identifier to reserve
|
||||||
* @param skipFilter - boolean indicating whether to skip any filtering of items before performing reservation
|
* @param filter - Logical item filter to determine whether this identifier should be reserved
|
||||||
* @throws IdentifierException
|
* @throws IdentifierException
|
||||||
* @throws IllegalArgumentException
|
* @throws IllegalArgumentException
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
*/
|
*/
|
||||||
public abstract void reserve(Context context, DSpaceObject dso, String identifier, boolean skipFilter)
|
public abstract void reserve(Context context, DSpaceObject dso, String identifier, Filter filter)
|
||||||
throws IdentifierException, IllegalArgumentException, SQLException;
|
throws IdentifierException, IllegalArgumentException, SQLException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mint a new identifier in DSpace - this is usually the first step of registration
|
* Mint a new identifier in DSpace - this is usually the first step of registration
|
||||||
* @param context - DSpace context
|
* @param context - DSpace context
|
||||||
* @param dso - DSpaceObject identified by the new identifier
|
* @param dso - DSpaceObject identified by the new identifier
|
||||||
* @param skipFilter - boolean indicating whether to skip any filtering of items before minting.
|
* @param filter - Logical item filter to determine whether this identifier should be registered
|
||||||
* @return a String containing the new identifier
|
* @return a String containing the new identifier
|
||||||
* @throws IdentifierException
|
* @throws IdentifierException
|
||||||
*/
|
*/
|
||||||
public abstract String mint(Context context, DSpaceObject dso, boolean skipFilter) throws IdentifierException;
|
public abstract String mint(Context context, DSpaceObject dso, Filter filter) throws IdentifierException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check configured item filters to see if this identifier is allowed to be minted
|
* Check configured item filters to see if this identifier is allowed to be minted
|
||||||
@@ -88,5 +90,13 @@ public abstract class FilteredIdentifierProvider extends IdentifierProvider {
|
|||||||
*/
|
*/
|
||||||
public abstract void checkMintable(Context context, DSpaceObject dso) throws IdentifierException;
|
public abstract void checkMintable(Context context, DSpaceObject dso) throws IdentifierException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check configured item filters to see if this identifier is allowed to be minted
|
||||||
|
* @param context - DSpace context
|
||||||
|
* @param filter - Logical item filter
|
||||||
|
* @param dso - DSpaceObject to be inspected
|
||||||
|
* @throws IdentifierException
|
||||||
|
*/
|
||||||
|
public abstract void checkMintable(Context context, Filter filter, DSpaceObject dso) throws IdentifierException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,7 @@ package org.dspace.identifier;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
@@ -17,6 +18,8 @@ import org.apache.logging.log4j.Logger;
|
|||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
|
import org.dspace.content.logic.Filter;
|
||||||
|
import org.dspace.content.logic.TrueFilter;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.handle.service.HandleService;
|
import org.dspace.handle.service.HandleService;
|
||||||
import org.dspace.identifier.service.IdentifierService;
|
import org.dspace.identifier.service.IdentifierService;
|
||||||
@@ -98,7 +101,7 @@ public class IdentifierServiceImpl implements IdentifierService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void register(Context context, DSpaceObject dso)
|
public void register(Context context, DSpaceObject dso)
|
||||||
throws AuthorizeException, SQLException, IdentifierException {
|
throws AuthorizeException, SQLException, IdentifierException {
|
||||||
//We need to commit our context because one of the providers might require the handle created above
|
//We need to commit our context because one of the providers might require the handle created above
|
||||||
// Next resolve all other services
|
// Next resolve all other services
|
||||||
for (IdentifierProvider service : providers) {
|
for (IdentifierProvider service : providers) {
|
||||||
@@ -112,6 +115,98 @@ public class IdentifierServiceImpl implements IdentifierService {
|
|||||||
contentServiceFactory.getDSpaceObjectService(dso).update(context, dso);
|
contentServiceFactory.getDSpaceObjectService(dso).update(context, dso);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register(Context context, DSpaceObject dso, Class<? extends Identifier> type, Filter filter)
|
||||||
|
throws AuthorizeException, SQLException, IdentifierException {
|
||||||
|
//We need to commit our context because one of the providers might require the handle created above
|
||||||
|
// Next resolve all other services
|
||||||
|
boolean registered = false;
|
||||||
|
for (IdentifierProvider service : providers) {
|
||||||
|
if (service.supports(type)) {
|
||||||
|
try {
|
||||||
|
if (service instanceof FilteredIdentifierProvider) {
|
||||||
|
FilteredIdentifierProvider filteredService = (FilteredIdentifierProvider)service;
|
||||||
|
filteredService.register(context, dso, filter);
|
||||||
|
} else {
|
||||||
|
service.register(context, dso);
|
||||||
|
}
|
||||||
|
registered = true;
|
||||||
|
} catch (IdentifierNotApplicableException e) {
|
||||||
|
log.warn("Identifier not registered (inapplicable): " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!registered) {
|
||||||
|
throw new IdentifierException("Cannot register identifier: Didn't "
|
||||||
|
+ "find a provider that supports this identifier.");
|
||||||
|
}
|
||||||
|
//Update our item / collection / community
|
||||||
|
contentServiceFactory.getDSpaceObjectService(dso).update(context, dso);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register(Context context, DSpaceObject dso, Class<? extends Identifier> type)
|
||||||
|
throws AuthorizeException, SQLException, IdentifierException {
|
||||||
|
//We need to commit our context because one of the providers might require the handle created above
|
||||||
|
// Next resolve all other services
|
||||||
|
boolean registered = false;
|
||||||
|
for (IdentifierProvider service : providers) {
|
||||||
|
if (service.supports(type)) {
|
||||||
|
try {
|
||||||
|
service.register(context, dso);
|
||||||
|
registered = true;
|
||||||
|
} catch (IdentifierNotApplicableException e) {
|
||||||
|
log.warn("Identifier not registered (inapplicable): " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!registered) {
|
||||||
|
throw new IdentifierException("Cannot register identifier: Didn't "
|
||||||
|
+ "find a provider that supports this identifier.");
|
||||||
|
}
|
||||||
|
//Update our item / collection / community
|
||||||
|
contentServiceFactory.getDSpaceObjectService(dso).update(context, dso);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register(Context context, DSpaceObject dso, Map<Class<? extends Identifier>, Filter> typeFilters)
|
||||||
|
throws AuthorizeException, SQLException, IdentifierException {
|
||||||
|
//We need to commit our context because one of the providers might require the handle created above
|
||||||
|
// Next resolve all other services
|
||||||
|
for (IdentifierProvider service : providers) {
|
||||||
|
try {
|
||||||
|
// If the service supports filtering, look through the map and the first supported class
|
||||||
|
// we find, set the filter and break. If no filter was seen for this type, just let the provider
|
||||||
|
// use its own implementation.
|
||||||
|
if (service instanceof FilteredIdentifierProvider) {
|
||||||
|
FilteredIdentifierProvider filteredService = (FilteredIdentifierProvider)service;
|
||||||
|
Filter filter = null;
|
||||||
|
for (Class<? extends Identifier> type : typeFilters.keySet()) {
|
||||||
|
if (service.supports(type)) {
|
||||||
|
filter = typeFilters.get(type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (filter != null) {
|
||||||
|
// Pass the found filter to the provider
|
||||||
|
filteredService.register(context, dso, filter);
|
||||||
|
} else {
|
||||||
|
// Let the provider use the default filter / behaviour
|
||||||
|
filteredService.register(context, dso);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
service.register(context, dso);
|
||||||
|
}
|
||||||
|
} catch (IdentifierNotApplicableException e) {
|
||||||
|
log.warn("Identifier not registered (inapplicable): " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Update our item / collection / community
|
||||||
|
contentServiceFactory.getDSpaceObjectService(dso).update(context, dso);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void register(Context context, DSpaceObject object, String identifier)
|
public void register(Context context, DSpaceObject object, String identifier)
|
||||||
throws AuthorizeException, SQLException, IdentifierException {
|
throws AuthorizeException, SQLException, IdentifierException {
|
||||||
|
@@ -18,6 +18,7 @@ import org.dspace.authorize.AuthorizeException;
|
|||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
|
import org.dspace.content.logic.Filter;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.identifier.doi.DOIConnector;
|
import org.dspace.identifier.doi.DOIConnector;
|
||||||
import org.dspace.identifier.doi.DOIIdentifierException;
|
import org.dspace.identifier.doi.DOIIdentifierException;
|
||||||
@@ -49,7 +50,12 @@ public class VersionedDOIIdentifierProvider extends DOIIdentifierProvider {
|
|||||||
protected VersionHistoryService versionHistoryService;
|
protected VersionHistoryService versionHistoryService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String mint(Context context, DSpaceObject dso)
|
public String mint(Context context, DSpaceObject dso) throws IdentifierException {
|
||||||
|
return mint(context, dso, this.filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String mint(Context context, DSpaceObject dso, Filter filter)
|
||||||
throws IdentifierException {
|
throws IdentifierException {
|
||||||
if (!(dso instanceof Item)) {
|
if (!(dso instanceof Item)) {
|
||||||
throw new IdentifierException("Currently only Items are supported for DOIs.");
|
throw new IdentifierException("Currently only Items are supported for DOIs.");
|
||||||
@@ -79,6 +85,9 @@ public class VersionedDOIIdentifierProvider extends DOIIdentifierProvider {
|
|||||||
+ " with ID " + dso.getID() + ".", ex);
|
+ " with ID " + dso.getID() + ".", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make a call to the filter here to throw an exception instead of carrying on with removal + creation
|
||||||
|
checkMintable(context, filter, dso);
|
||||||
|
|
||||||
// check whether we have a DOI in the metadata and if we have to remove it
|
// check whether we have a DOI in the metadata and if we have to remove it
|
||||||
String metadataDOI = getDOIOutOfObject(dso);
|
String metadataDOI = getDOIOutOfObject(dso);
|
||||||
if (metadataDOI != null) {
|
if (metadataDOI != null) {
|
||||||
@@ -111,7 +120,7 @@ public class VersionedDOIIdentifierProvider extends DOIIdentifierProvider {
|
|||||||
// ensure DOI exists in our database as well and return.
|
// ensure DOI exists in our database as well and return.
|
||||||
// this also checks that the doi is not assigned to another dso already.
|
// this also checks that the doi is not assigned to another dso already.
|
||||||
try {
|
try {
|
||||||
loadOrCreateDOI(context, dso, versionedDOI);
|
loadOrCreateDOI(context, dso, versionedDOI, filter);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
log.error(
|
log.error(
|
||||||
"A problem with the database connection occurd while processing DOI " + versionedDOI + ".", ex);
|
"A problem with the database connection occurd while processing DOI " + versionedDOI + ".", ex);
|
||||||
@@ -127,7 +136,7 @@ public class VersionedDOIIdentifierProvider extends DOIIdentifierProvider {
|
|||||||
// if we have a history, we have a item
|
// if we have a history, we have a item
|
||||||
doi = makeIdentifierBasedOnHistory(context, dso, history);
|
doi = makeIdentifierBasedOnHistory(context, dso, history);
|
||||||
} else {
|
} else {
|
||||||
doi = loadOrCreateDOI(context, dso, null).getDoi();
|
doi = loadOrCreateDOI(context, dso, null, filter).getDoi();
|
||||||
}
|
}
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
log.error("SQLException while creating a new DOI: ", ex);
|
log.error("SQLException while creating a new DOI: ", ex);
|
||||||
@@ -140,7 +149,12 @@ public class VersionedDOIIdentifierProvider extends DOIIdentifierProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void register(Context context, DSpaceObject dso, String identifier)
|
public void register(Context context, DSpaceObject dso, String identifier) throws IdentifierException {
|
||||||
|
register(context, dso, identifier, this.filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register(Context context, DSpaceObject dso, String identifier, Filter filter)
|
||||||
throws IdentifierException {
|
throws IdentifierException {
|
||||||
if (!(dso instanceof Item)) {
|
if (!(dso instanceof Item)) {
|
||||||
throw new IdentifierException("Currently only Items are supported for DOIs.");
|
throw new IdentifierException("Currently only Items are supported for DOIs.");
|
||||||
@@ -220,8 +234,14 @@ public class VersionedDOIIdentifierProvider extends DOIIdentifierProvider {
|
|||||||
return doiPostfix;
|
return doiPostfix;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should never return null!
|
|
||||||
protected String makeIdentifierBasedOnHistory(Context context, DSpaceObject dso, VersionHistory history)
|
protected String makeIdentifierBasedOnHistory(Context context, DSpaceObject dso, VersionHistory history)
|
||||||
|
throws AuthorizeException, SQLException, DOIIdentifierException, IdentifierNotApplicableException {
|
||||||
|
return makeIdentifierBasedOnHistory(context, dso, history, this.filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should never return null!
|
||||||
|
protected String makeIdentifierBasedOnHistory(Context context, DSpaceObject dso, VersionHistory history,
|
||||||
|
Filter filter)
|
||||||
throws AuthorizeException, SQLException, DOIIdentifierException, IdentifierNotApplicableException {
|
throws AuthorizeException, SQLException, DOIIdentifierException, IdentifierNotApplicableException {
|
||||||
// Mint foreach new version an identifier like: 12345/100.versionNumber
|
// Mint foreach new version an identifier like: 12345/100.versionNumber
|
||||||
// use the bare handle (g.e. 12345/100) for the first version.
|
// use the bare handle (g.e. 12345/100) for the first version.
|
||||||
@@ -244,6 +264,9 @@ public class VersionedDOIIdentifierProvider extends DOIIdentifierProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (previousVersionDOI == null) {
|
if (previousVersionDOI == null) {
|
||||||
|
// Before continuing with any new DOI creation, apply the filter
|
||||||
|
checkMintable(context, filter, dso);
|
||||||
|
|
||||||
// We need to generate a new DOI.
|
// We need to generate a new DOI.
|
||||||
DOI doi = doiService.create(context);
|
DOI doi = doiService.create(context);
|
||||||
|
|
||||||
@@ -269,7 +292,7 @@ public class VersionedDOIIdentifierProvider extends DOIIdentifierProvider {
|
|||||||
String.valueOf(versionHistoryService.getVersion(context, history, item).getVersionNumber()));
|
String.valueOf(versionHistoryService.getVersion(context, history, item).getVersionNumber()));
|
||||||
}
|
}
|
||||||
|
|
||||||
loadOrCreateDOI(context, dso, identifier);
|
loadOrCreateDOI(context, dso, identifier, filter);
|
||||||
return identifier;
|
return identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,23 +7,32 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.identifier.doi;
|
package org.dspace.identifier.doi;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
|
import org.dspace.content.logic.Filter;
|
||||||
|
import org.dspace.content.logic.FilterUtils;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.event.Consumer;
|
import org.dspace.event.Consumer;
|
||||||
import org.dspace.event.Event;
|
import org.dspace.event.Event;
|
||||||
|
import org.dspace.identifier.DOI;
|
||||||
import org.dspace.identifier.DOIIdentifierProvider;
|
import org.dspace.identifier.DOIIdentifierProvider;
|
||||||
import org.dspace.identifier.IdentifierException;
|
import org.dspace.identifier.IdentifierException;
|
||||||
import org.dspace.identifier.IdentifierNotFoundException;
|
import org.dspace.identifier.IdentifierNotApplicableException;
|
||||||
|
import org.dspace.identifier.factory.IdentifierServiceFactory;
|
||||||
|
import org.dspace.identifier.service.DOIService;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
import org.dspace.utils.DSpace;
|
import org.dspace.utils.DSpace;
|
||||||
import org.dspace.workflow.factory.WorkflowServiceFactory;
|
import org.dspace.workflow.factory.WorkflowServiceFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Pascal-Nicolas Becker (p dot becker at tu hyphen berlin dot de)
|
* @author Pascal-Nicolas Becker (p dot becker at tu hyphen berlin dot de)
|
||||||
|
* @author Kim Shepherd
|
||||||
*/
|
*/
|
||||||
public class DOIConsumer implements Consumer {
|
public class DOIConsumer implements Consumer {
|
||||||
/**
|
/**
|
||||||
@@ -31,12 +40,15 @@ public class DOIConsumer implements Consumer {
|
|||||||
*/
|
*/
|
||||||
private static Logger log = org.apache.logging.log4j.LogManager.getLogger(DOIConsumer.class);
|
private static Logger log = org.apache.logging.log4j.LogManager.getLogger(DOIConsumer.class);
|
||||||
|
|
||||||
|
ConfigurationService configurationService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() throws Exception {
|
public void initialize() throws Exception {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
// we can ask spring to give as a properly setuped instance of
|
// we can ask spring to give as a properly setuped instance of
|
||||||
// DOIIdentifierProvider. Doing so we don't have to configure it and
|
// DOIIdentifierProvider. Doing so we don't have to configure it and
|
||||||
// can load it in consume method as this is not very expensive.
|
// can load it in consume method as this is not very expensive.
|
||||||
|
configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,77 +75,73 @@ public class DOIConsumer implements Consumer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Item item = (Item) dso;
|
Item item = (Item) dso;
|
||||||
|
DOIIdentifierProvider provider = new DSpace().getSingletonService(DOIIdentifierProvider.class);
|
||||||
|
boolean inProgress = (ContentServiceFactory.getInstance().getWorkspaceItemService().findByItem(ctx, item)
|
||||||
|
!= null || WorkflowServiceFactory.getInstance().getWorkflowItemService().findByItem(ctx, item) != null);
|
||||||
|
boolean identifiersInSubmission = configurationService.getBooleanProperty("identifiers.submission.register",
|
||||||
|
false);
|
||||||
|
DOIService doiService = IdentifierServiceFactory.getInstance().getDOIService();
|
||||||
|
Filter workspaceFilter = null;
|
||||||
|
if (identifiersInSubmission) {
|
||||||
|
workspaceFilter = FilterUtils.getFilterFromConfiguration("identifiers.submission.filter.workspace");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
if (inProgress && !identifiersInSubmission) {
|
||||||
if (ContentServiceFactory.getInstance().getWorkspaceItemService().findByItem(ctx, item) != null
|
// ignore workflow and workspace items, DOI will be minted and updated when item is installed
|
||||||
|| WorkflowServiceFactory.getInstance().getWorkflowItemService().findByItem(ctx, item) != null) {
|
// UNLESS special pending filter is set
|
||||||
// ignore workflow and workspace items, DOI will be minted when item is installed
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*/
|
DOI doi = null;
|
||||||
DOIIdentifierProvider provider = new DSpace().getSingletonService(
|
|
||||||
DOIIdentifierProvider.class);
|
|
||||||
|
|
||||||
String doi = null;
|
|
||||||
try {
|
try {
|
||||||
doi = provider.lookup(ctx, dso);
|
doi = doiService.findDOIByDSpaceObject(ctx, dso);
|
||||||
} catch (IdentifierNotFoundException ex) {
|
} catch (SQLException ex) {
|
||||||
// nothing to do here, next if clause will stop us from processing
|
// nothing to do here, next if clause will stop us from processing
|
||||||
// items without dois.
|
// items without dois.
|
||||||
}
|
}
|
||||||
if (doi == null) {
|
if (doi == null) {
|
||||||
// if the item is workflow or workspace, there is a special case here - the ShowIdentifersStep
|
// No DOI. The only time something should be minted is if we have enabled submission reg'n and
|
||||||
// needs this consumer to reserve DOIs in the event that the item now meets criteria for a pre-mint
|
// it passes the workspace filter. We also need to update status to PENDING straight after.
|
||||||
if (ContentServiceFactory.getInstance().getWorkspaceItemService().findByItem(ctx, item) != null
|
if (inProgress) {
|
||||||
|| WorkflowServiceFactory.getInstance().getWorkflowItemService().findByItem(ctx, item) != null) {
|
provider.mint(ctx, dso, workspaceFilter);
|
||||||
if (DSpaceServicesFactory.getInstance().getConfigurationService()
|
DOI newDoi = doiService.findDOIByDSpaceObject(ctx, dso);
|
||||||
.getBooleanProperty("identifiers.submission.register", false)) {
|
if (newDoi != null) {
|
||||||
try {
|
newDoi.setStatus(DOIIdentifierProvider.PENDING);
|
||||||
String newDoi = provider.mint(ctx, item);
|
doiService.update(ctx, newDoi);
|
||||||
if (newDoi != null) {
|
|
||||||
provider.reserve(ctx, item, newDoi);
|
|
||||||
log.debug("Consumer minting and reserving new DOI for in-progress item: " + newDoi);
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (DOIIdentifierNotApplicableException e) {
|
|
||||||
log.debug("Consumer skipping mint for item as it was filtered out: " + item.getID());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.debug("Consumer skipping mint for item as it is in-progress and" +
|
|
||||||
"identifiers.submission.register=false: " + item.getID());
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.debug("DOIConsumer cannot handles items without DOIs, skipping: "
|
log.debug("DOIConsumer cannot handles items without DOIs, skipping: " + event.toString());
|
||||||
+ event.toString());
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} else if (ContentServiceFactory.getInstance().getWorkspaceItemService().findByItem(ctx, item) != null
|
} else {
|
||||||
|| WorkflowServiceFactory.getInstance().getWorkflowItemService().findByItem(ctx, item) != null) {
|
// If in progress, we can also switch PENDING and MINTED status depending on the latest filter
|
||||||
if (DSpaceServicesFactory.getInstance().getConfigurationService()
|
// evaluation
|
||||||
.getBooleanProperty("identifiers.submission.register", false)) {
|
if (inProgress) {
|
||||||
// We have a DOI for an in-progress submission item -- if the filter says "no", we should delete
|
|
||||||
// the minted DOI so it doesn't get registered on item install.
|
|
||||||
try {
|
try {
|
||||||
provider.checkMintable(ctx, item);
|
// Check the filter
|
||||||
} catch (DOIIdentifierNotApplicableException e) {
|
provider.checkMintable(ctx, workspaceFilter, dso);
|
||||||
log.debug("Consumer deleting DOI for in-progress item: " + doi);
|
// If we made it here, the existing doi should be back to PENDING
|
||||||
provider.delete(ctx, item, doi);
|
if (DOIIdentifierProvider.MINTED.equals(doi.getStatus())) {
|
||||||
return;
|
doi.setStatus(DOIIdentifierProvider.PENDING);
|
||||||
|
}
|
||||||
|
} catch (IdentifierNotApplicableException e) {
|
||||||
|
// Set status to MINTED if configured to downgrade existing DOIs
|
||||||
|
if (configurationService
|
||||||
|
.getBooleanProperty("identifiers.submission.strip_pending_during_submission", true)) {
|
||||||
|
doi.setStatus(DOIIdentifierProvider.MINTED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
doiService.update(ctx, doi);
|
||||||
} else {
|
} else {
|
||||||
log.debug("Consumer skipping mint for item as it is in-progress and" +
|
try {
|
||||||
"identifiers.submission.register=false: " + item.getID());
|
provider.updateMetadata(ctx, dso, doi.getDoi());
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
// should not happen, as we got the DOI from the DOIProvider
|
||||||
|
log.warn("DOIConsumer caught an IdentifierException.", ex);
|
||||||
|
} catch (IdentifierException ex) {
|
||||||
|
log.warn("DOIConsumer cannot update metadata for Item with ID "
|
||||||
|
+ item.getID() + " and DOI " + doi + ".", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
ctx.commit();
|
||||||
try {
|
|
||||||
provider.updateMetadata(ctx, dso, doi);
|
|
||||||
} catch (IllegalArgumentException ex) {
|
|
||||||
// should not happen, as we got the DOI from the DOIProvider
|
|
||||||
log.warn("DOIConsumer caught an IdentifierException.", ex);
|
|
||||||
} catch (IdentifierException ex) {
|
|
||||||
log.warn("DOIConsumer cannot update metadata for Item with ID "
|
|
||||||
+ item.getID() + " and DOI " + doi + ".", ex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -30,6 +30,9 @@ import org.apache.logging.log4j.LogManager;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
|
import org.dspace.content.logic.Filter;
|
||||||
|
import org.dspace.content.logic.FilterUtils;
|
||||||
|
import org.dspace.content.logic.TrueFilter;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
@@ -61,7 +64,8 @@ public class DOIOrganiser {
|
|||||||
protected ItemService itemService;
|
protected ItemService itemService;
|
||||||
protected DOIService doiService;
|
protected DOIService doiService;
|
||||||
protected ConfigurationService configurationService;
|
protected ConfigurationService configurationService;
|
||||||
protected boolean skipFilter;
|
// This filter will override the default provider filter / behaviour
|
||||||
|
protected Filter filter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor to be called within the main() method
|
* Constructor to be called within the main() method
|
||||||
@@ -76,7 +80,7 @@ public class DOIOrganiser {
|
|||||||
this.itemService = ContentServiceFactory.getInstance().getItemService();
|
this.itemService = ContentServiceFactory.getInstance().getItemService();
|
||||||
this.doiService = IdentifierServiceFactory.getInstance().getDOIService();
|
this.doiService = IdentifierServiceFactory.getInstance().getDOIService();
|
||||||
this.configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
|
this.configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
|
||||||
this.skipFilter = false;
|
this.filter = new TrueFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -121,12 +125,13 @@ public class DOIOrganiser {
|
|||||||
"Perform online metadata update for all identifiers queued for metadata update.");
|
"Perform online metadata update for all identifiers queued for metadata update.");
|
||||||
options.addOption("d", "delete-all", false,
|
options.addOption("d", "delete-all", false,
|
||||||
"Perform online deletion for all identifiers queued for deletion.");
|
"Perform online deletion for all identifiers queued for deletion.");
|
||||||
|
|
||||||
options.addOption("q", "quiet", false,
|
options.addOption("q", "quiet", false,
|
||||||
"Turn the command line output off.");
|
"Turn the command line output off.");
|
||||||
|
|
||||||
options.addOption(null, "skip-filter", false,
|
Option filterDoi = Option.builder().optionalArg(true).longOpt("filter").hasArg().argName("filterName")
|
||||||
"Skip the configured item filter when registering or reserving.");
|
.desc("Use the specified filter name instead of the provider's filter. Defaults to a special " +
|
||||||
|
"'always true' filter to force operations").build();
|
||||||
|
options.addOption(filterDoi);
|
||||||
|
|
||||||
Option registerDoi = Option.builder()
|
Option registerDoi = Option.builder()
|
||||||
.longOpt("register-doi")
|
.longOpt("register-doi")
|
||||||
@@ -203,10 +208,12 @@ public class DOIOrganiser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DOIService doiService = IdentifierServiceFactory.getInstance().getDOIService();
|
DOIService doiService = IdentifierServiceFactory.getInstance().getDOIService();
|
||||||
// Should we skip the filter?
|
// Do we get a filter?
|
||||||
if (line.hasOption("skip-filter")) {
|
if (line.hasOption("filter")) {
|
||||||
System.out.println("Skipping the item filter");
|
String filter = line.getOptionValue("filter");
|
||||||
organiser.skipFilter = true;
|
if (null != filter) {
|
||||||
|
organiser.filter = FilterUtils.getFilterFromConfiguration(filter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.hasOption('s')) {
|
if (line.hasOption('s')) {
|
||||||
@@ -394,19 +401,18 @@ public class DOIOrganiser {
|
|||||||
/**
|
/**
|
||||||
* Register DOI with the provider
|
* Register DOI with the provider
|
||||||
* @param doiRow - doi to register
|
* @param doiRow - doi to register
|
||||||
* @param skipFilter - whether filters should be skipped before registration
|
* @param filter - logical item filter to override
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
* @throws DOIIdentifierException
|
* @throws DOIIdentifierException
|
||||||
*/
|
*/
|
||||||
public void register(DOI doiRow, boolean skipFilter) throws SQLException, DOIIdentifierException {
|
public void register(DOI doiRow, Filter filter) throws SQLException, DOIIdentifierException {
|
||||||
DSpaceObject dso = doiRow.getDSpaceObject();
|
DSpaceObject dso = doiRow.getDSpaceObject();
|
||||||
if (Constants.ITEM != dso.getType()) {
|
if (Constants.ITEM != dso.getType()) {
|
||||||
throw new IllegalArgumentException("Currenty DSpace supports DOIs for Items only.");
|
throw new IllegalArgumentException("Currenty DSpace supports DOIs for Items only.");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
provider.registerOnline(context, dso,
|
provider.registerOnline(context, dso, DOI.SCHEME + doiRow.getDoi(), filter);
|
||||||
DOI.SCHEME + doiRow.getDoi());
|
|
||||||
|
|
||||||
if (!quiet) {
|
if (!quiet) {
|
||||||
System.out.println("This identifier: "
|
System.out.println("This identifier: "
|
||||||
@@ -466,29 +472,23 @@ public class DOIOrganiser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register DOI with the provider, always applying (ie. never skipping) any configured filters
|
* Register DOI with the provider
|
||||||
* @param doiRow - doi to register
|
* @param doiRow - doi to register
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
* @throws DOIIdentifierException
|
* @throws DOIIdentifierException
|
||||||
*/
|
*/
|
||||||
public void register(DOI doiRow) throws SQLException, DOIIdentifierException {
|
public void register(DOI doiRow) throws SQLException, DOIIdentifierException {
|
||||||
if (this.skipFilter) {
|
register(doiRow, this.filter);
|
||||||
System.out.println("Skipping the filter for " + doiRow.getDoi());
|
|
||||||
}
|
|
||||||
register(doiRow, this.skipFilter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reserve DOI with the provider, always applying (ie. never skipping) any configured filters
|
* Reserve DOI with the provider,
|
||||||
* @param doiRow - doi to reserve
|
* @param doiRow - doi to reserve
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
* @throws DOIIdentifierException
|
* @throws DOIIdentifierException
|
||||||
*/
|
*/
|
||||||
public void reserve(DOI doiRow) {
|
public void reserve(DOI doiRow) {
|
||||||
if (this.skipFilter) {
|
reserve(doiRow, this.filter);
|
||||||
System.out.println("Skipping the filter for " + doiRow.getDoi());
|
|
||||||
}
|
|
||||||
reserve(doiRow, this.skipFilter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -497,14 +497,14 @@ public class DOIOrganiser {
|
|||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
* @throws DOIIdentifierException
|
* @throws DOIIdentifierException
|
||||||
*/
|
*/
|
||||||
public void reserve(DOI doiRow, boolean skipFilter) {
|
public void reserve(DOI doiRow, Filter filter) {
|
||||||
DSpaceObject dso = doiRow.getDSpaceObject();
|
DSpaceObject dso = doiRow.getDSpaceObject();
|
||||||
if (Constants.ITEM != dso.getType()) {
|
if (Constants.ITEM != dso.getType()) {
|
||||||
throw new IllegalArgumentException("Currently DSpace supports DOIs for Items only.");
|
throw new IllegalArgumentException("Currently DSpace supports DOIs for Items only.");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
provider.reserveOnline(context, dso, DOI.SCHEME + doiRow.getDoi(), skipFilter);
|
provider.reserveOnline(context, dso, DOI.SCHEME + doiRow.getDoi(), filter);
|
||||||
|
|
||||||
if (!quiet) {
|
if (!quiet) {
|
||||||
System.out.println("This identifier : " + DOI.SCHEME + doiRow.getDoi() + " is successfully reserved.");
|
System.out.println("This identifier : " + DOI.SCHEME + doiRow.getDoi() + " is successfully reserved.");
|
||||||
@@ -699,7 +699,7 @@ public class DOIOrganiser {
|
|||||||
|
|
||||||
//Check if this Item has an Identifier, mint one if it doesn't
|
//Check if this Item has an Identifier, mint one if it doesn't
|
||||||
if (null == doiRow) {
|
if (null == doiRow) {
|
||||||
doi = provider.mint(context, dso, this.skipFilter);
|
doi = provider.mint(context, dso, this.filter);
|
||||||
doiRow = doiService.findByDoi(context,
|
doiRow = doiService.findByDoi(context,
|
||||||
doi.substring(DOI.SCHEME.length()));
|
doi.substring(DOI.SCHEME.length()));
|
||||||
return doiRow;
|
return doiRow;
|
||||||
@@ -723,7 +723,7 @@ public class DOIOrganiser {
|
|||||||
doiRow = doiService.findDOIByDSpaceObject(context, dso);
|
doiRow = doiService.findDOIByDSpaceObject(context, dso);
|
||||||
|
|
||||||
if (null == doiRow) {
|
if (null == doiRow) {
|
||||||
doi = provider.mint(context, dso, this.skipFilter);
|
doi = provider.mint(context, dso, this.filter);
|
||||||
doiRow = doiService.findByDoi(context,
|
doiRow = doiService.findByDoi(context,
|
||||||
doi.substring(DOI.SCHEME.length()));
|
doi.substring(DOI.SCHEME.length()));
|
||||||
}
|
}
|
||||||
|
@@ -9,9 +9,11 @@ package org.dspace.identifier.service;
|
|||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
|
import org.dspace.content.logic.Filter;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.identifier.Identifier;
|
import org.dspace.identifier.Identifier;
|
||||||
import org.dspace.identifier.IdentifierException;
|
import org.dspace.identifier.IdentifierException;
|
||||||
@@ -103,6 +105,40 @@ public interface IdentifierService {
|
|||||||
*/
|
*/
|
||||||
void register(Context context, DSpaceObject dso) throws AuthorizeException, SQLException, IdentifierException;
|
void register(Context context, DSpaceObject dso) throws AuthorizeException, SQLException, IdentifierException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param context The relevant DSpace Context.
|
||||||
|
* @param dso DSpace object to be registered
|
||||||
|
* @param typeFilters If a service supports a given Identifier implementation, apply the associated filter
|
||||||
|
* @throws AuthorizeException if authorization error
|
||||||
|
* @throws SQLException if database error
|
||||||
|
* @throws IdentifierException if identifier error
|
||||||
|
*/
|
||||||
|
void register(Context context, DSpaceObject dso, Map<Class<? extends Identifier>, Filter> typeFilters)
|
||||||
|
throws AuthorizeException, SQLException, IdentifierException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param context The relevant DSpace Context.
|
||||||
|
* @param dso DSpace object to be registered
|
||||||
|
* @param type Type of identifier to register
|
||||||
|
* @param filter If a service supports a given Identifier implementation, apply this specific filter
|
||||||
|
* @throws AuthorizeException if authorization error
|
||||||
|
* @throws SQLException if database error
|
||||||
|
* @throws IdentifierException if identifier error
|
||||||
|
*/
|
||||||
|
void register(Context context, DSpaceObject dso, Class<? extends Identifier> type, Filter filter)
|
||||||
|
throws AuthorizeException, SQLException, IdentifierException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param context The relevant DSpace Context.
|
||||||
|
* @param dso DSpace object to be registered
|
||||||
|
* @param type Type of identifier to register
|
||||||
|
* @throws AuthorizeException if authorization error
|
||||||
|
* @throws SQLException if database error
|
||||||
|
* @throws IdentifierException if identifier error
|
||||||
|
*/
|
||||||
|
void register(Context context, DSpaceObject dso, Class<? extends Identifier> type)
|
||||||
|
throws AuthorizeException, SQLException, IdentifierException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to Register a specific Identifier (for example a Handle, hdl:1234.5/6).
|
* Used to Register a specific Identifier (for example a Handle, hdl:1234.5/6).
|
||||||
* The provider is responsible for detecting and processing the appropriate
|
* The provider is responsible for detecting and processing the appropriate
|
||||||
|
@@ -36,6 +36,7 @@ import org.dspace.content.WorkspaceItem;
|
|||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
import org.dspace.content.logic.DefaultFilter;
|
import org.dspace.content.logic.DefaultFilter;
|
||||||
import org.dspace.content.logic.LogicalStatement;
|
import org.dspace.content.logic.LogicalStatement;
|
||||||
|
import org.dspace.content.logic.TrueFilter;
|
||||||
import org.dspace.content.service.CollectionService;
|
import org.dspace.content.service.CollectionService;
|
||||||
import org.dspace.content.service.CommunityService;
|
import org.dspace.content.service.CommunityService;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
@@ -128,7 +129,7 @@ public class DOIIdentifierProviderTest
|
|||||||
provider.itemService = itemService;
|
provider.itemService = itemService;
|
||||||
provider.setConfigurationService(config);
|
provider.setConfigurationService(config);
|
||||||
provider.setDOIConnector(connector);
|
provider.setDOIConnector(connector);
|
||||||
provider.setFilterService(null);
|
provider.setFilter(null);
|
||||||
} catch (AuthorizeException ex) {
|
} catch (AuthorizeException ex) {
|
||||||
log.error("Authorization Error in init", ex);
|
log.error("Authorization Error in init", ex);
|
||||||
fail("Authorization Error in init: " + ex.getMessage());
|
fail("Authorization Error in init: " + ex.getMessage());
|
||||||
@@ -504,7 +505,7 @@ public class DOIIdentifierProviderTest
|
|||||||
String doi = null;
|
String doi = null;
|
||||||
try {
|
try {
|
||||||
// get a DOI (skipping any filters)
|
// get a DOI (skipping any filters)
|
||||||
doi = provider.mint(context, item, true);
|
doi = provider.mint(context, item);
|
||||||
} catch (IdentifierException e) {
|
} catch (IdentifierException e) {
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
fail("Got an IdentifierException: " + e.getMessage());
|
fail("Got an IdentifierException: " + e.getMessage());
|
||||||
@@ -544,23 +545,18 @@ public class DOIIdentifierProviderTest
|
|||||||
Item item = newItem();
|
Item item = newItem();
|
||||||
boolean wasFiltered = false;
|
boolean wasFiltered = false;
|
||||||
try {
|
try {
|
||||||
// Temporarily set the provider to have a filter that always returns false for an item
|
// Mint this with the filter
|
||||||
// (therefore, the item should be 'filtered' out and not apply to this minting request)
|
|
||||||
DefaultFilter doiFilter = new DefaultFilter();
|
DefaultFilter doiFilter = new DefaultFilter();
|
||||||
LogicalStatement alwaysFalse = (context, i) -> false;
|
LogicalStatement alwaysFalse = (context, i) -> false;
|
||||||
doiFilter.setStatement(alwaysFalse);
|
doiFilter.setStatement(alwaysFalse);
|
||||||
provider.setFilterService(doiFilter);
|
|
||||||
// get a DOI with the method that applies filters by default
|
// get a DOI with the method that applies filters by default
|
||||||
provider.mint(context, item);
|
provider.mint(context, item, doiFilter);
|
||||||
} catch (DOIIdentifierNotApplicableException e) {
|
} catch (DOIIdentifierNotApplicableException e) {
|
||||||
// This is what we wanted to see - we can return safely
|
// This is what we wanted to see - we can return safely
|
||||||
wasFiltered = true;
|
wasFiltered = true;
|
||||||
} catch (IdentifierException e) {
|
} catch (IdentifierException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
fail("Got an IdentifierException: " + e.getMessage());
|
fail("Got an IdentifierException: " + e.getMessage());
|
||||||
} finally {
|
|
||||||
// Set filter service back to null
|
|
||||||
provider.setFilterService(null);
|
|
||||||
}
|
}
|
||||||
// Fail the test if the filter didn't throw a "not applicable" exception
|
// Fail the test if the filter didn't throw a "not applicable" exception
|
||||||
assertTrue("DOI minting attempt was not filtered by filter service", wasFiltered);
|
assertTrue("DOI minting attempt was not filtered by filter service", wasFiltered);
|
||||||
@@ -583,17 +579,14 @@ public class DOIIdentifierProviderTest
|
|||||||
DefaultFilter doiFilter = new DefaultFilter();
|
DefaultFilter doiFilter = new DefaultFilter();
|
||||||
LogicalStatement alwaysTrue = (context, i) -> true;
|
LogicalStatement alwaysTrue = (context, i) -> true;
|
||||||
doiFilter.setStatement(alwaysTrue);
|
doiFilter.setStatement(alwaysTrue);
|
||||||
provider.setFilterService(doiFilter);
|
|
||||||
// get a DOI with the method that applies filters by default
|
// get a DOI with the method that applies filters by default
|
||||||
doi = provider.mint(context, item);
|
doi = provider.mint(context, item, doiFilter);
|
||||||
} catch (DOIIdentifierNotApplicableException e) {
|
} catch (DOIIdentifierNotApplicableException e) {
|
||||||
// This is what we wanted to see - we can return safely
|
// This is what we wanted to see - we can return safely
|
||||||
wasFiltered = true;
|
wasFiltered = true;
|
||||||
} catch (IdentifierException e) {
|
} catch (IdentifierException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
fail("Got an IdentifierException: " + e.getMessage());
|
fail("Got an IdentifierException: " + e.getMessage());
|
||||||
} finally {
|
|
||||||
provider.setFilterService(null);
|
|
||||||
}
|
}
|
||||||
// If the attempt was filtered, fail
|
// If the attempt was filtered, fail
|
||||||
assertFalse("DOI minting attempt was incorrectly filtered by filter service", wasFiltered);
|
assertFalse("DOI minting attempt was incorrectly filtered by filter service", wasFiltered);
|
||||||
@@ -665,7 +658,7 @@ public class DOIIdentifierProviderTest
|
|||||||
Item item = newItem();
|
Item item = newItem();
|
||||||
|
|
||||||
// Register, skipping the filter
|
// Register, skipping the filter
|
||||||
String doi = provider.register(context, item, true);
|
String doi = provider.register(context, item, new TrueFilter());
|
||||||
|
|
||||||
// we want the created DOI to be returned in the following format:
|
// we want the created DOI to be returned in the following format:
|
||||||
// doi:10.<prefix>/<suffix>.
|
// doi:10.<prefix>/<suffix>.
|
||||||
|
@@ -0,0 +1,144 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest;
|
||||||
|
|
||||||
|
import static org.dspace.app.rest.utils.RegexUtils.REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.converter.ConverterService;
|
||||||
|
import org.dspace.app.rest.converter.MetadataConverter;
|
||||||
|
import org.dspace.app.rest.model.IdentifierRest;
|
||||||
|
import org.dspace.app.rest.model.IdentifiersRest;
|
||||||
|
import org.dspace.app.rest.model.ItemRest;
|
||||||
|
import org.dspace.app.rest.repository.ItemRestRepository;
|
||||||
|
import org.dspace.app.rest.utils.ContextUtil;
|
||||||
|
import org.dspace.app.rest.utils.Utils;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.logic.TrueFilter;
|
||||||
|
import org.dspace.content.service.ItemService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.handle.factory.HandleServiceFactory;
|
||||||
|
import org.dspace.identifier.DOI;
|
||||||
|
import org.dspace.identifier.DOIIdentifierProvider;
|
||||||
|
import org.dspace.identifier.IdentifierException;
|
||||||
|
import org.dspace.identifier.IdentifierNotFoundException;
|
||||||
|
import org.dspace.identifier.service.DOIService;
|
||||||
|
import org.dspace.identifier.service.IdentifierService;
|
||||||
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.rest.webmvc.ControllerUtils;
|
||||||
|
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
||||||
|
import org.springframework.hateoas.RepresentationModel;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller to register identifiers
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/" + ItemRest.CATEGORY + "/" + ItemRest.PLURAL_NAME + REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID
|
||||||
|
+ "/" + IdentifiersRest.PLURAL_NAME)
|
||||||
|
public class ItemIdentifierController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ConverterService converter;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ItemService itemService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ItemRestRepository itemRestRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
MetadataConverter metadataConverter;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
IdentifierService identifierService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
DOIService doiService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
Utils utils;
|
||||||
|
|
||||||
|
public IdentifiersRest get(@PathVariable UUID uuid, HttpServletRequest request,
|
||||||
|
HttpServletResponse response)
|
||||||
|
throws SQLException, AuthorizeException {
|
||||||
|
Context context = ContextUtil.obtainContext(request);
|
||||||
|
Item item = itemService.find(context, uuid);
|
||||||
|
if (item == null) {
|
||||||
|
throw new ResourceNotFoundException("Could not find item with id " + uuid);
|
||||||
|
}
|
||||||
|
IdentifiersRest identifiersRest = new IdentifiersRest();
|
||||||
|
List<IdentifierRest> identifierRests = new ArrayList<>();
|
||||||
|
DOI doi = doiService.findDOIByDSpaceObject(context, item);
|
||||||
|
String handle = HandleServiceFactory.getInstance().getHandleService().findHandle(context, item);
|
||||||
|
try {
|
||||||
|
if (doi != null) {
|
||||||
|
String doiUrl = doiService.DOIToExternalForm(doi.getDoi());
|
||||||
|
IdentifierRest identifierRest = new IdentifierRest(doiUrl, "doi", String.valueOf(doi.getStatus()));
|
||||||
|
identifierRests.add(identifierRest);
|
||||||
|
}
|
||||||
|
if (handle != null) {
|
||||||
|
identifierRests.add(new IdentifierRest(handle, "handle", null));
|
||||||
|
}
|
||||||
|
} catch (IdentifierException e) {
|
||||||
|
throw new IllegalStateException("Failed to register identifier: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return identifiersRest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to register an identifier for an item.
|
||||||
|
*
|
||||||
|
* @return OK
|
||||||
|
*/
|
||||||
|
@RequestMapping(method = RequestMethod.POST)
|
||||||
|
@PreAuthorize("hasPermission(#uuid, 'ITEM', 'ADMIN')")
|
||||||
|
public ResponseEntity<RepresentationModel<?>> registerIdentifierForItem(@PathVariable UUID uuid,
|
||||||
|
HttpServletRequest request,
|
||||||
|
HttpServletResponse response)
|
||||||
|
throws SQLException, AuthorizeException {
|
||||||
|
Context context = ContextUtil.obtainContext(request);
|
||||||
|
|
||||||
|
Item item = itemService.find(context, uuid);
|
||||||
|
|
||||||
|
if (item == null) {
|
||||||
|
throw new ResourceNotFoundException("Could not find item with id " + uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
String identifier = null;
|
||||||
|
try {
|
||||||
|
DOIIdentifierProvider doiIdentifierProvider = DSpaceServicesFactory.getInstance().getServiceManager()
|
||||||
|
.getServiceByName("org.dspace.identifier.DOIIdentifierProvider", DOIIdentifierProvider.class);
|
||||||
|
doiIdentifierProvider.register(context, item, new TrueFilter());
|
||||||
|
if (context != null) {
|
||||||
|
context.commit();
|
||||||
|
}
|
||||||
|
} catch (IdentifierNotFoundException e) {
|
||||||
|
return ControllerUtils.toEmptyResponse(HttpStatus.NO_CONTENT);
|
||||||
|
} catch (IdentifierException e) {
|
||||||
|
throw new IllegalStateException("Failed to register identifier: " + identifier);
|
||||||
|
}
|
||||||
|
return ControllerUtils.toEmptyResponse(HttpStatus.CREATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* <p>
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of IdentifierRest REST resource, representing some DSpace identifier
|
||||||
|
* for use with the REST API
|
||||||
|
*
|
||||||
|
* @author Kim Shepherd <kim@shepherd.nz>
|
||||||
|
*/
|
||||||
|
public class IdentifierRest implements RestModel {
|
||||||
|
|
||||||
|
// Set names used in component wiring
|
||||||
|
public static final String NAME = "identifier";
|
||||||
|
public static final String PLURAL_NAME = "identifiers";
|
||||||
|
private String value;
|
||||||
|
private String identifierType;
|
||||||
|
private String identifierStatus;
|
||||||
|
|
||||||
|
// Empty constructor
|
||||||
|
public IdentifierRest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public IdentifierRest(String value, String identifierType, String identifierStatus) {
|
||||||
|
this.value = value;
|
||||||
|
this.identifierType = identifierType;
|
||||||
|
this.identifierStatus = identifierStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return name for getType()
|
||||||
|
@Override
|
||||||
|
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||||
|
public String getType() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIdentifierType() {
|
||||||
|
return identifierType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdentifierType(String identifierType) {
|
||||||
|
this.identifierType = identifierType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIdentifierStatus() {
|
||||||
|
return identifierStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdentifierStatus(String identifierStatus) {
|
||||||
|
this.identifierStatus = identifierStatus;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* <p>
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.model;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of IdentifierRest REST resource, representing a list of all identifiers
|
||||||
|
* for use with the REST API
|
||||||
|
*
|
||||||
|
* @author Kim Shepherd <kim@shepherd.nz>
|
||||||
|
*/
|
||||||
|
public class IdentifiersRest implements RestModel {
|
||||||
|
|
||||||
|
// Set names used in component wiring
|
||||||
|
public static final String NAME = "identifier";
|
||||||
|
public static final String PLURAL_NAME = "identifiers";
|
||||||
|
private List<IdentifierRest> identifiers;
|
||||||
|
|
||||||
|
// Empty constructor
|
||||||
|
public IdentifiersRest() {
|
||||||
|
identifiers = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return name for getType()
|
||||||
|
@Override
|
||||||
|
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||||
|
public String getType() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<IdentifierRest> getIdentifiers() {
|
||||||
|
return identifiers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdentifiers(List<IdentifierRest> identifiers) {
|
||||||
|
this.identifiers = identifiers;
|
||||||
|
}
|
||||||
|
}
|
@@ -25,6 +25,10 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||||||
name = ItemRest.BUNDLES,
|
name = ItemRest.BUNDLES,
|
||||||
method = "getBundles"
|
method = "getBundles"
|
||||||
),
|
),
|
||||||
|
//@LinkRest(
|
||||||
|
// name = ItemRest.IDENTIFIERS,
|
||||||
|
// method = "getIdentifiers"
|
||||||
|
//),
|
||||||
@LinkRest(
|
@LinkRest(
|
||||||
name = ItemRest.MAPPED_COLLECTIONS,
|
name = ItemRest.MAPPED_COLLECTIONS,
|
||||||
method = "getMappedCollections"
|
method = "getMappedCollections"
|
||||||
@@ -57,6 +61,7 @@ public class ItemRest extends DSpaceObjectRest {
|
|||||||
|
|
||||||
public static final String ACCESS_STATUS = "accessStatus";
|
public static final String ACCESS_STATUS = "accessStatus";
|
||||||
public static final String BUNDLES = "bundles";
|
public static final String BUNDLES = "bundles";
|
||||||
|
public static final String IDENTIFIERS = "identifiers";
|
||||||
public static final String MAPPED_COLLECTIONS = "mappedCollections";
|
public static final String MAPPED_COLLECTIONS = "mappedCollections";
|
||||||
public static final String OWNING_COLLECTION = "owningCollection";
|
public static final String OWNING_COLLECTION = "owningCollection";
|
||||||
public static final String RELATIONSHIPS = "relationships";
|
public static final String RELATIONSHIPS = "relationships";
|
||||||
|
@@ -20,6 +20,10 @@ public class DataIdentifiers implements SectionData {
|
|||||||
String doi;
|
String doi;
|
||||||
List<String> otherIdentifiers;
|
List<String> otherIdentifiers;
|
||||||
|
|
||||||
|
public DataIdentifiers() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public String getHandle() {
|
public String getHandle() {
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
@@ -45,6 +45,10 @@ import org.dspace.content.service.RelationshipService;
|
|||||||
import org.dspace.content.service.RelationshipTypeService;
|
import org.dspace.content.service.RelationshipTypeService;
|
||||||
import org.dspace.content.service.WorkspaceItemService;
|
import org.dspace.content.service.WorkspaceItemService;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.identifier.IdentifierException;
|
||||||
|
import org.dspace.identifier.VersionedHandleIdentifierProviderWithCanonicalHandles;
|
||||||
|
import org.dspace.identifier.service.IdentifierService;
|
||||||
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
import org.dspace.util.UUIDUtils;
|
import org.dspace.util.UUIDUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
@@ -92,6 +96,9 @@ public class ItemRestRepository extends DSpaceObjectRestRepository<Item, ItemRes
|
|||||||
@Autowired
|
@Autowired
|
||||||
RelationshipTypeService relationshipTypeService;
|
RelationshipTypeService relationshipTypeService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
IdentifierService identifierService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UriListHandlerService uriListHandlerService;
|
private UriListHandlerService uriListHandlerService;
|
||||||
|
|
||||||
@@ -357,6 +364,44 @@ public class ItemRestRepository extends DSpaceObjectRestRepository<Item, ItemRes
|
|||||||
return bundle;
|
return bundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register an identifier for an item
|
||||||
|
* @param context
|
||||||
|
* @param item
|
||||||
|
* @param identifier
|
||||||
|
* @return
|
||||||
|
* @throws SQLException
|
||||||
|
* @throws AuthorizeException
|
||||||
|
* @throws IdentifierException
|
||||||
|
*/
|
||||||
|
@PreAuthorize("hasPermission(#uuid, 'ITEM', 'ADMIN')")
|
||||||
|
public boolean registerIdentifier(Context context, Item item, String identifier)
|
||||||
|
throws SQLException, AuthorizeException, IdentifierException {
|
||||||
|
if (item != null) {
|
||||||
|
if (identifier != null) {
|
||||||
|
// Try to register the supplied identifier
|
||||||
|
identifierService.register(context, item, identifier);
|
||||||
|
return item.equals(identifierService.resolve(context, identifier));
|
||||||
|
} else {
|
||||||
|
DSpaceServicesFactory.getInstance().getServiceManager()
|
||||||
|
.getServicesByType(VersionedHandleIdentifierProviderWithCanonicalHandles.class);
|
||||||
|
// Call plain 'register' which will mint a new DOI, handle, etc if needed
|
||||||
|
// this NOT compatible with versioned handle provider with canonical handles
|
||||||
|
boolean compatible = DSpaceServicesFactory.getInstance().getServiceManager()
|
||||||
|
.getServicesByType(VersionedHandleIdentifierProviderWithCanonicalHandles.class).isEmpty();
|
||||||
|
if (compatible) {
|
||||||
|
// Register without a supplied identifier
|
||||||
|
identifierService.register(context, item);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
log.error("This register method is NOT compatible with" +
|
||||||
|
"VersionedHandleIdentifierProviderWithCanonicalHandles");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ItemRest createAndReturn(Context context, List<String> stringList)
|
protected ItemRest createAndReturn(Context context, List<String> stringList)
|
||||||
throws AuthorizeException, SQLException, RepositoryMethodNotImplementedException {
|
throws AuthorizeException, SQLException, RepositoryMethodNotImplementedException {
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.app.rest.submit.step;
|
package org.dspace.app.rest.submit.step;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
@@ -26,6 +27,7 @@ import org.dspace.core.Context;
|
|||||||
import org.dspace.handle.factory.HandleServiceFactory;
|
import org.dspace.handle.factory.HandleServiceFactory;
|
||||||
import org.dspace.handle.service.HandleService;
|
import org.dspace.handle.service.HandleService;
|
||||||
import org.dspace.identifier.DOI;
|
import org.dspace.identifier.DOI;
|
||||||
|
import org.dspace.identifier.DOIIdentifierProvider;
|
||||||
import org.dspace.identifier.Handle;
|
import org.dspace.identifier.Handle;
|
||||||
import org.dspace.identifier.IdentifierException;
|
import org.dspace.identifier.IdentifierException;
|
||||||
import org.dspace.identifier.factory.IdentifierServiceFactory;
|
import org.dspace.identifier.factory.IdentifierServiceFactory;
|
||||||
@@ -90,20 +92,31 @@ public class ShowIdentifiersStep extends AbstractProcessingStep {
|
|||||||
IdentifierServiceFactory.getInstance().getIdentifierService();
|
IdentifierServiceFactory.getInstance().getIdentifierService();
|
||||||
// Attempt to look up handle and DOI identifiers for this item
|
// Attempt to look up handle and DOI identifiers for this item
|
||||||
String handle = identifierService.lookup(context, obj.getItem(), Handle.class);
|
String handle = identifierService.lookup(context, obj.getItem(), Handle.class);
|
||||||
String doi = identifierService.lookup(context, obj.getItem(), DOI.class);
|
String simpleDoi = identifierService.lookup(context, obj.getItem(), DOI.class);
|
||||||
|
DOI doi = null;
|
||||||
|
String doiString = null;
|
||||||
|
try {
|
||||||
|
doi = IdentifierServiceFactory.getInstance().getDOIService().findDOIByDSpaceObject(context, obj.getItem());
|
||||||
|
if (doi != null && !DOIIdentifierProvider.MINTED.equals(doi.getStatus())
|
||||||
|
&& !DOIIdentifierProvider.MINTED.equals(doi.getStatus())) {
|
||||||
|
doiString = doi.getDoi();
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
// Look up all identifiers and if they're not the DOI or handle, add them to the 'other' list
|
// Look up all identifiers and if they're not the DOI or handle, add them to the 'other' list
|
||||||
List<String> otherIdentifiers = new ArrayList<>();
|
List<String> otherIdentifiers = new ArrayList<>();
|
||||||
for (String identifier : identifierService.lookup(context, obj.getItem())) {
|
for (String identifier : identifierService.lookup(context, obj.getItem())) {
|
||||||
if (!StringUtils.equals(doi, identifier) && !StringUtils.equals(handle, identifier)) {
|
if (!StringUtils.equals(simpleDoi, identifier) && !StringUtils.equals(handle, identifier)) {
|
||||||
otherIdentifiers.add(identifier);
|
otherIdentifiers.add(identifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we got a DOI, format it to its external form
|
// If we got a DOI, format it to its external form
|
||||||
if (StringUtils.isNotEmpty(doi)) {
|
if (StringUtils.isNotEmpty(doiString)) {
|
||||||
try {
|
try {
|
||||||
doi = IdentifierServiceFactory.getInstance().getDOIService().DOIToExternalForm(doi);
|
doiString = IdentifierServiceFactory.getInstance().getDOIService().DOIToExternalForm(doiString);
|
||||||
} catch (IdentifierException e) {
|
} catch (IdentifierException e) {
|
||||||
log.error("Error formatting DOI: " + doi);
|
log.error("Error formatting DOI: " + doi);
|
||||||
}
|
}
|
||||||
@@ -114,7 +127,7 @@ public class ShowIdentifiersStep extends AbstractProcessingStep {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Populate bean with data and return
|
// Populate bean with data and return
|
||||||
result.setDoi(doi);
|
result.setDoi(doiString);
|
||||||
result.setHandle(handle);
|
result.setHandle(handle);
|
||||||
result.setOtherIdentifiers(otherIdentifiers);
|
result.setOtherIdentifiers(otherIdentifiers);
|
||||||
|
|
||||||
|
@@ -240,7 +240,7 @@
|
|||||||
<!--<step id="sample"/> -->
|
<!--<step id="sample"/> -->
|
||||||
|
|
||||||
<step id="collection"/>
|
<step id="collection"/>
|
||||||
|
<step id="identifiers"/>
|
||||||
<!--Step will be to Describe the item. -->
|
<!--Step will be to Describe the item. -->
|
||||||
<step id="traditionalpageone"/>
|
<step id="traditionalpageone"/>
|
||||||
<step id="traditionalpagetwo"/>
|
<step id="traditionalpagetwo"/>
|
||||||
|
@@ -5,7 +5,35 @@
|
|||||||
# as the Show Identifiers step which can "pre-mint" DOIs and Handles #
|
# as the Show Identifiers step which can "pre-mint" DOIs and Handles #
|
||||||
#----------------------------------------------------------------------#
|
#----------------------------------------------------------------------#
|
||||||
|
|
||||||
# Should identifiers be registered in the Show Identifiers step and minted / updated / deleted as appropriate
|
# Should DOIs be minted for (future) registration at workspace item creation?
|
||||||
# in the DOI Consumer? Setting this property to 'true' is recommended
|
# A DOI created at this stage will be in a 'PENDING' status while in workspace and workflow.
|
||||||
|
# At the time of item install, the DOI filter (if any) will be applied and if the item matches the filter, the DOI
|
||||||
|
# status will be updated to TO_BE_REGISTERED. An administrator can also manually progress the DOI status, overriding
|
||||||
|
# any filters, in the item status page.
|
||||||
|
# This option doesn't require the Show Identifiers submission step to be visible.
|
||||||
# Default: false
|
# Default: false
|
||||||
#identifiers.submission.register = false
|
#identifiers.submission.register = true
|
||||||
|
|
||||||
|
# This configuration property can be set to a filter name to determine if a PENDING DOI for an item
|
||||||
|
# should be queued for registration. If the filter doesn't match, the DOI will stay in PENDING or MINTED status
|
||||||
|
# so that the identifier itself persists in case it is considered for registration in the future.
|
||||||
|
# See doi-filter and other example filters in item-filters.xml.
|
||||||
|
# Default (always_true_filter)
|
||||||
|
#identifiers.submission.filter.install = doi-filter
|
||||||
|
|
||||||
|
# This optional configuration property can be set to a filter name, in case there are some initial rules to apply
|
||||||
|
# when first deciding whether a DOI should be be created for a new workspace item with a PENDING status.
|
||||||
|
# This filter is only applied if identifiers.submission.register is true.
|
||||||
|
# This filter is updated as submission data is saved.
|
||||||
|
# Default: (always_true_filter)
|
||||||
|
#identifiers.submission.filter.workspace = always_true_filter
|
||||||
|
|
||||||
|
# If true, the workspace filter will be applied as submission data is saved. If the filter no longer
|
||||||
|
# matches the item, the DOI will be shifted into a MINTED status and not displayed in the submission section.
|
||||||
|
# If false, then once a DOI has been created with PENDING status it will remain that way until final item install
|
||||||
|
# Default: true
|
||||||
|
#identifiers.submission.strip_pending_during_submission = true
|
||||||
|
|
||||||
|
# This configuration property can be set to a filter name to determine if an item processed by RegisterDOI curation
|
||||||
|
# task should be eligible for a DOI
|
||||||
|
#identifiers.submission.filter.curation = always_true_filter
|
@@ -13,7 +13,7 @@
|
|||||||
scope="singleton"/>
|
scope="singleton"/>
|
||||||
|
|
||||||
<!-- If you enabled versioning, you should use one of the versioned
|
<!-- If you enabled versioning, you should use one of the versioned
|
||||||
handle identifier provider instead of the default one.
|
handle identifier provider instead of the default one.
|
||||||
The VersionedHandleIdentifierProvider creates a new versioned
|
The VersionedHandleIdentifierProvider creates a new versioned
|
||||||
handle for every new version.
|
handle for every new version.
|
||||||
-->
|
-->
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
a DOIConnector that handles all API calls to your DOI registration
|
a DOIConnector that handles all API calls to your DOI registration
|
||||||
agency. Please configure a DOIConnector as well! -->
|
agency. Please configure a DOIConnector as well! -->
|
||||||
|
|
||||||
<!-- In order to mint DOIs with DSpace, get an agreement with a DOI
|
<!-- In order to mint DOIs with DSpace, get an agreement with a DOI
|
||||||
registration agency, take a look into dspace.cfg, and activate either
|
registration agency, take a look into dspace.cfg, and activate either
|
||||||
the DOIIdentifierProvider or the VersionedDOIIdentifierProvider,
|
the DOIIdentifierProvider or the VersionedDOIIdentifierProvider,
|
||||||
depending on whether you have Item Level Versioning activated or not.
|
depending on whether you have Item Level Versioning activated or not.
|
||||||
@@ -55,6 +55,7 @@
|
|||||||
ref="org.dspace.services.ConfigurationService" />
|
ref="org.dspace.services.ConfigurationService" />
|
||||||
<property name="DOIConnector"
|
<property name="DOIConnector"
|
||||||
ref="org.dspace.identifier.doi.DOIConnector" />
|
ref="org.dspace.identifier.doi.DOIConnector" />
|
||||||
|
<property name="filter" ref="doi-filter" />
|
||||||
</bean>
|
</bean>
|
||||||
-->
|
-->
|
||||||
<!--
|
<!--
|
||||||
@@ -78,11 +79,11 @@
|
|||||||
ref="org.dspace.services.ConfigurationService" />
|
ref="org.dspace.services.ConfigurationService" />
|
||||||
<property name="DOIConnector"
|
<property name="DOIConnector"
|
||||||
ref="org.dspace.identifier.doi.DOIConnector" />
|
ref="org.dspace.identifier.doi.DOIConnector" />
|
||||||
<property name="filterService" ref="openaire_filter" />
|
<property name="filter" ref="doi-filter" />
|
||||||
</bean>
|
</bean>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
||||||
<!-- The DOIConnector will handle the API calls to your DOI registration
|
<!-- The DOIConnector will handle the API calls to your DOI registration
|
||||||
agency for the DOIIdentifierProvider. If your registration agency
|
agency for the DOIIdentifierProvider. If your registration agency
|
||||||
tells you to use the DataCite API directly, you can use the
|
tells you to use the DataCite API directly, you can use the
|
||||||
@@ -105,9 +106,9 @@
|
|||||||
|
|
||||||
<!-- Provider to mint and register DOIs using EZID as the registrar.
|
<!-- Provider to mint and register DOIs using EZID as the registrar.
|
||||||
-->
|
-->
|
||||||
<!--
|
<!--
|
||||||
Set generateDataciteXML to true to send metadata in DataCite xml schema for EZID DOI mint requests.
|
Set generateDataciteXML to true to send metadata in DataCite xml schema for EZID DOI mint requests.
|
||||||
When generateDataciteXML is enabled, EZIDIdentifierProvider uses
|
When generateDataciteXML is enabled, EZIDIdentifierProvider uses
|
||||||
dspace.cfg:crosswalk.dissemination.DataCite.stylesheet XSL configuration for metadata mapping
|
dspace.cfg:crosswalk.dissemination.DataCite.stylesheet XSL configuration for metadata mapping
|
||||||
-->
|
-->
|
||||||
<!-- Uncomment to enable DOI using EZID
|
<!-- Uncomment to enable DOI using EZID
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
<!-- default-autowire-candidates="*Service,*DAO,javax.sql.DataSource"> -->
|
<!-- default-autowire-candidates="*Service,*DAO,javax.sql.DataSource"> -->
|
||||||
|
|
||||||
<context:annotation-config /> <!-- allows us to use spring annotations in beans -->
|
<context:annotation-config /> <!-- allows us to use spring annotations in beans -->
|
||||||
|
<bean id="always_true_filter" class="org.dspace.content.logic.TrueFilter"/>
|
||||||
|
|
||||||
<!-- DEFINE CONDITIONS
|
<!-- DEFINE CONDITIONS
|
||||||
Define condition beans below for use as sub-statements in operator and filter beans
|
Define condition beans below for use as sub-statements in operator and filter beans
|
||||||
@@ -168,6 +168,17 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="is-archived_condition" class="org.dspace.content.logic.condition.IsArchivedCondition">
|
||||||
|
<property name="parameters">
|
||||||
|
<map></map>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
<bean id="is-withdrawn_condition" class="org.dspace.content.logic.condition.IsWithdrawnCondition">
|
||||||
|
<property name="parameters">
|
||||||
|
<map></map>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<!-- DEFINE OPERATORS
|
<!-- DEFINE OPERATORS
|
||||||
Operators can be defined too, if a particular AND or OR statement needs to be re-used a lot, though
|
Operators can be defined too, if a particular AND or OR statement needs to be re-used a lot, though
|
||||||
it may be easier in most cases to turn that into a filter and reference the filter in other sub-statements
|
it may be easier in most cases to turn that into a filter and reference the filter in other sub-statements
|
||||||
@@ -195,11 +206,15 @@
|
|||||||
<bean class="org.dspace.content.logic.operator.And">
|
<bean class="org.dspace.content.logic.operator.And">
|
||||||
<property name="statements">
|
<property name="statements">
|
||||||
<list>
|
<list>
|
||||||
|
<!-- Make sure the item is archived -->
|
||||||
|
<ref bean="is-archived_condition"/>
|
||||||
|
<!-- Make sure the item is not withdrawn -->
|
||||||
|
<bean class="org.dspace.content.logic.operator.Not">
|
||||||
|
<property name="statements" ref="is-withdrawn_condition"/>
|
||||||
|
</bean>
|
||||||
<!-- Don't create new DOIs for items that already have one -->
|
<!-- Don't create new DOIs for items that already have one -->
|
||||||
<bean class="org.dspace.content.logic.operator.Not">
|
<bean class="org.dspace.content.logic.operator.Not">
|
||||||
<property name="statements">
|
<property name="statements" ref="dc-identifier-uri-contains-doi_condition"/>
|
||||||
<ref bean="dc-identifier-uri-contains-doi_condition"/>
|
|
||||||
</property>
|
|
||||||
</bean>
|
</bean>
|
||||||
<!-- Create DOIs for items only that do have at least one bitstream. -->
|
<!-- Create DOIs for items only that do have at least one bitstream. -->
|
||||||
<ref bean="has-at-least-one-bitstream_condition"/>
|
<ref bean="has-at-least-one-bitstream_condition"/>
|
||||||
@@ -226,16 +241,12 @@
|
|||||||
|
|
||||||
<!-- A very simple demonstration filter, using the metadata match condition -->
|
<!-- A very simple demonstration filter, using the metadata match condition -->
|
||||||
<bean id="simple-demo_filter" class="org.dspace.content.logic.DefaultFilter">
|
<bean id="simple-demo_filter" class="org.dspace.content.logic.DefaultFilter">
|
||||||
<property name="statement">
|
<property name="statement" ref="title-contains-demo_condition"/>
|
||||||
<ref bean="title-contains-demo_condition"/>
|
|
||||||
</property>
|
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- A very simple filter for items with at least one bitstream -->
|
<!-- A very simple filter for items with at least one bitstream -->
|
||||||
<bean id="has-bitstream_filter" class="org.dspace.content.logic.DefaultFilter">
|
<bean id="has-bitstream_filter" class="org.dspace.content.logic.DefaultFilter">
|
||||||
<property name="statement">
|
<property name="statement" ref="has-at-least-one-bitstream_condition"/>
|
||||||
<ref bean="has-at-least-one-bitstream_condition"/>
|
|
||||||
</property>
|
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
@@ -335,5 +346,27 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="example-doi_filter" class="org.dspace.content.logic.DefaultFilter">
|
||||||
|
<property name="statement">
|
||||||
|
<bean class="org.dspace.content.logic.operator.And">
|
||||||
|
<property name="statements">
|
||||||
|
<list>
|
||||||
|
<!-- Has a non-empty title -->
|
||||||
|
<bean id="has-title_condition"
|
||||||
|
class="org.dspace.content.logic.condition.MetadataValueMatchCondition">
|
||||||
|
<property name="parameters">
|
||||||
|
<map>
|
||||||
|
<entry key="field" value="dc.title" />
|
||||||
|
<entry key="pattern" value=".*" />
|
||||||
|
</map>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
Reference in New Issue
Block a user