From 7828b3d9e5b7234a1f3f8cb1434343341b6aae2d Mon Sep 17 00:00:00 2001 From: Ma-Tador Date: Fri, 25 Oct 2024 10:18:08 +0200 Subject: [PATCH] SwordV2 - Add Item DOI Filter --- .../content/MetadataValueServiceImpl.java | 6 ++ .../dspace/content/dao/MetadataValueDAO.java | 3 + .../dao/impl/MetadataValueDAOImpl.java | 81 ++++++++++++++++ .../factory/ContentServiceFactory.java | 9 +- .../factory/ContentServiceFactoryImpl.java | 17 ++++ .../content/service/MetadataValueService.java | 12 +++ .../org/dspace/content/MetadataValueTest.java | 31 ++++++- .../CollectionDepositManagerDSpace.java | 59 +++++++++++- .../java/org/dspace/sword2/DepositResult.java | 10 ++ .../dspace/sword2/WorkflowManagerDefault.java | 93 +++++++++++++++---- dspace/config/modules/swordv2-server.cfg | 7 ++ 11 files changed, 303 insertions(+), 25 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/content/MetadataValueServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/MetadataValueServiceImpl.java index 0c34c04f3..54e9a35cd 100755 --- a/dspace-api/src/main/java/org/dspace/content/MetadataValueServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/MetadataValueServiceImpl.java @@ -130,4 +130,10 @@ public class MetadataValueServiceImpl implements MetadataValueService { public int countTotal(Context context) throws SQLException { return metadataValueDAO.countRows(context); } + + @Override + public Long countDoiMatches(Context context, String doi, List doiPrefixes) throws SQLException { + return metadataValueDAO.countDoiMatches(context, doi, doiPrefixes); + } + } diff --git a/dspace-api/src/main/java/org/dspace/content/dao/MetadataValueDAO.java b/dspace-api/src/main/java/org/dspace/content/dao/MetadataValueDAO.java index 6a09cfdd8..db97e8240 100755 --- a/dspace-api/src/main/java/org/dspace/content/dao/MetadataValueDAO.java +++ b/dspace-api/src/main/java/org/dspace/content/dao/MetadataValueDAO.java @@ -10,6 +10,7 @@ package org.dspace.content.dao; import java.sql.SQLException; import java.util.Iterator; import java.util.List; +import org.dspace.content.Item; import org.dspace.content.MetadataField; import org.dspace.content.MetadataValue; @@ -40,5 +41,7 @@ public interface MetadataValueDAO extends GenericDAO { throws SQLException; int countRows(Context context) throws SQLException; + + Long countDoiMatches(Context context, String doi, List doiPrefixes) throws SQLException; } diff --git a/dspace-api/src/main/java/org/dspace/content/dao/impl/MetadataValueDAOImpl.java b/dspace-api/src/main/java/org/dspace/content/dao/impl/MetadataValueDAOImpl.java index f37ced9ab..85e1f1a28 100755 --- a/dspace-api/src/main/java/org/dspace/content/dao/impl/MetadataValueDAOImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/dao/impl/MetadataValueDAOImpl.java @@ -8,13 +8,19 @@ package org.dspace.content.dao.impl; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.stream.Collectors; import javax.persistence.Query; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Join; import javax.persistence.criteria.Root; +import org.apache.commons.lang3.StringUtils; +import org.dspace.content.Item; import org.dspace.content.MetadataField; import org.dspace.content.MetadataField_; @@ -31,6 +37,13 @@ import org.dspace.core.Context; * @author kevinvandevelde at atmire.com */ public class MetadataValueDAOImpl extends AbstractHibernateDAO implements MetadataValueDAO { + + private static final String DOI_METADATA_FIELD_QUERY = + "SELECT mf.id FROM MetadataField mf WHERE mf.metadataSchema.name = 'dc' AND mf.element = 'identifier' AND mf.qualifier = 'doi'"; + + private volatile int cachedDoiMetadataFieldId = -1; + + protected MetadataValueDAOImpl() { super(); } @@ -95,5 +108,73 @@ public class MetadataValueDAOImpl extends AbstractHibernateDAO im public int countRows(Context context) throws SQLException { return count(createQuery(context, "SELECT count(*) FROM MetadataValue")); } + + + public Long countDoiMatches(Context context, String doi, List doiPrefixes) throws SQLException { + if (doi == null || doi.trim().isEmpty()) { + return 0L; // if no doi provided, skip DB query + } + + List doiVariants = generateDoiVariants(doi, doiPrefixes); + + if (doiVariants.isEmpty()) { + return 0L; + } + + String queryString = "SELECT COUNT(m) FROM MetadataValue m " + + "WHERE m.metadataField.id = :metadataFieldId " + + "AND LOWER(m.value) IN :doiVariants"; + + // Create and execute the query + Query query = createQuery(context, queryString); + query.setParameter("metadataFieldId", getDoiMetadataFieldId(context)); + query.setParameter("doiVariants", doiVariants); + return (Long) query.getSingleResult(); + } + + + // Method to get the metadata field ID for 'doi' + private int getDoiMetadataFieldId(Context context) throws SQLException { + // Double-checked locking for thread-safe caching + if (cachedDoiMetadataFieldId == -1) { + synchronized (this) { + if (cachedDoiMetadataFieldId == -1) { + Query query = createQuery(context, DOI_METADATA_FIELD_QUERY); + cachedDoiMetadataFieldId = (Integer) query.getSingleResult(); + } + } + } + return cachedDoiMetadataFieldId; + } + + + private List generateDoiVariants(String doi, List doiPrefixes) { + if (doi == null || doi.isBlank()) { + return Collections.emptyList(); + } + + doi = doi.trim().toLowerCase(); + + String normalizedDoi = doi; + //remove known prefixes + for (String prefix : doiPrefixes) { + String lowerPrefix = prefix.toLowerCase(); + if(doi.startsWith(lowerPrefix)) { + normalizedDoi = doi.substring(lowerPrefix.length()); + break; + } + } + + List doiVariants = new ArrayList<>(doiPrefixes.size() + 1); + + doiVariants.add(normalizedDoi); + + for(String prefix : doiPrefixes) { + doiVariants.add(prefix.toLowerCase() + normalizedDoi); + } + + return doiVariants; + } + } diff --git a/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactory.java b/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactory.java index 4010e1486..b1b0d500d 100755 --- a/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactory.java +++ b/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactory.java @@ -33,7 +33,10 @@ import org.dspace.content.service.RelationshipTypeService; import org.dspace.content.service.SiteService; import org.dspace.content.service.SupervisedItemService; import org.dspace.content.service.WorkspaceItemService; +import org.dspace.discovery.SearchService; import org.dspace.services.factory.DSpaceServicesFactory; +import org.dspace.workflow.WorkflowItemService; +import org.dspace.workflow.WorkflowService; import org.dspace.workflow.factory.WorkflowServiceFactory; /** @@ -48,7 +51,7 @@ public abstract class ContentServiceFactory { public abstract List> getDSpaceObjectLegacySupportServices(); - + public abstract BitstreamFormatService getBitstreamFormatService(); public abstract BitstreamService getBitstreamService(); @@ -68,12 +71,16 @@ public abstract class ContentServiceFactory { public abstract MetadataValueService getMetadataValueService(); public abstract WorkspaceItemService getWorkspaceItemService(); + + public abstract WorkflowItemService getWorkflowItemService(); public abstract InstallItemService getInstallItemService(); public abstract SupervisedItemService getSupervisedItemService(); public abstract SiteService getSiteService(); + + public abstract WorkflowService getWorkflowService(); /** * Return the implementation of the RelationshipTypeService interface diff --git a/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactoryImpl.java b/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactoryImpl.java index 6f123ae1b..4e3acb27e 100755 --- a/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactoryImpl.java @@ -30,6 +30,8 @@ import org.dspace.content.service.RelationshipTypeService; import org.dspace.content.service.SiteService; import org.dspace.content.service.SupervisedItemService; import org.dspace.content.service.WorkspaceItemService; +import org.dspace.workflow.WorkflowItemService; +import org.dspace.workflow.WorkflowService; import org.springframework.beans.factory.annotation.Autowired; /** @@ -82,6 +84,16 @@ public class ContentServiceFactoryImpl extends ContentServiceFactory { private EntityTypeService entityTypeService; @Autowired(required = true) private EntityService entityService; + + @Autowired + private WorkflowItemService workflowItemService; + @Autowired + private WorkflowService workflowService; + + @Override + public WorkflowService getWorkflowService() { + return workflowService; + } @Override public List> getDSpaceObjectServices() { @@ -142,6 +154,11 @@ public class ContentServiceFactoryImpl extends ContentServiceFactory { public WorkspaceItemService getWorkspaceItemService() { return workspaceItemService; } + + @Override + public WorkflowItemService getWorkflowItemService() { + return workflowItemService; + } @Override public InstallItemService getInstallItemService() { diff --git a/dspace-api/src/main/java/org/dspace/content/service/MetadataValueService.java b/dspace-api/src/main/java/org/dspace/content/service/MetadataValueService.java index 1cf26e37f..c95c0a5a5 100755 --- a/dspace-api/src/main/java/org/dspace/content/service/MetadataValueService.java +++ b/dspace-api/src/main/java/org/dspace/content/service/MetadataValueService.java @@ -14,6 +14,7 @@ import java.util.List; import org.dspace.authorize.AuthorizeException; import org.dspace.content.DSpaceObject; +import org.dspace.content.Item; import org.dspace.content.MetadataField; import org.dspace.content.MetadataValue; import org.dspace.core.Context; @@ -112,4 +113,15 @@ public interface MetadataValueService { throws SQLException; int countTotal(Context context) throws SQLException; + + /** + * Counts how many items have same dc.identifier.doi value as the given DOI (considering the provided DOI prefixes) + * + * @param context + * @param doi + * @param doiPrefixes + * @return + * @throws SQLException + */ + Long countDoiMatches(Context context, String doi, List doiPrefixes) throws SQLException; } diff --git a/dspace-api/src/test/java/org/dspace/content/MetadataValueTest.java b/dspace-api/src/test/java/org/dspace/content/MetadataValueTest.java index 10ec8e619..bcd9d0125 100755 --- a/dspace-api/src/test/java/org/dspace/content/MetadataValueTest.java +++ b/dspace-api/src/test/java/org/dspace/content/MetadataValueTest.java @@ -16,6 +16,7 @@ import static org.junit.Assert.fail; import java.io.IOException; import java.sql.SQLException; +import java.util.Arrays; import java.util.List; import org.apache.logging.log4j.Logger; @@ -48,6 +49,7 @@ public class MetadataValueTest extends AbstractUnitTest { * MetadataValue instance for the tests */ private MetadataValue mv = null; + private MetadataValue mvDoi = null; private Collection collection; private Community owningCommunity; @@ -58,16 +60,21 @@ public class MetadataValueTest extends AbstractUnitTest { * MetadataField instance for the tests */ private MetadataField mf; + private MetadataField mfDoi; + /** * Element of the metadata element */ private String element = "contributor"; + private String element2 = "identifier"; + /** * Qualifier of the metadata element */ private String qualifier = "author"; + private String qualifier2 = "doi"; private MetadataFieldService metadataFieldService = ContentServiceFactory.getInstance().getMetadataFieldService(); private MetadataValueService metadataValueService = ContentServiceFactory.getInstance().getMetadataValueService(); @@ -94,9 +101,11 @@ public class MetadataValueTest extends AbstractUnitTest { WorkspaceItem workspaceItem = workspaceItemService.create(context, collection, false); this.it = installItemService.installItem(context, workspaceItem); - this.mf = metadataFieldService.findByElement(context, - MetadataSchemaEnum.DC.getName(), element, qualifier); + this.mf = metadataFieldService.findByElement(context,MetadataSchemaEnum.DC.getName(), element, qualifier); + this.mfDoi = metadataFieldService.findByElement(context,MetadataSchemaEnum.DC.getName(), element2, qualifier2); this.mv = metadataValueService.create(context, it, mf); + this.mvDoi = metadataValueService.create(context, it, mfDoi); + this.mvDoi.setValue("http://doi.org/10.115/ce-2022-171"); context.restoreAuthSystemState(); } catch (AuthorizeException ex) { log.error("Authorize Error in init", ex); @@ -256,6 +265,24 @@ public class MetadataValueTest extends AbstractUnitTest { public void testCreate() throws Exception { metadataValueService.create(context, it, mf); } + + /** + * Test of countDoiMatches method when a doi exists, of class MetadataValueService. + */ + @Test + public void testCountDoiMatchesFoundOne() throws Exception { + Long count = metadataValueService.countDoiMatches(context, "http://doi.org/10.115/ce-2022-171", Arrays.asList("http://doi.org/", "https://doi.org/")); + assertThat(count, equalTo(1)); + } + + /** + * Test of countDoiMatches method when no doi exists, of class MetadataValueService. + */ + @Test + public void testCountDoiMatchesFoundNone() throws Exception { + Long count = metadataValueService.countDoiMatches(context, "doi.org/10.1111/non-existent", Arrays.asList("http://doi.org/", "https://doi.org/")); + assertThat(count, equalTo(0)); + } /** * Test of find method, of class MetadataValue. diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionDepositManagerDSpace.java b/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionDepositManagerDSpace.java index 7f77c00f0..4a201ce37 100755 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionDepositManagerDSpace.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionDepositManagerDSpace.java @@ -8,14 +8,23 @@ package org.dspace.sword2; import java.io.IOException; +import java.sql.SQLException; import java.util.Date; +import java.util.logging.Level; import org.apache.logging.log4j.Logger; +import org.dspace.authorize.AuthorizeException; import org.dspace.content.Collection; +import org.dspace.content.Item; +import org.dspace.content.WorkspaceItem; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.CollectionService; +import org.dspace.content.service.WorkspaceItemService; import org.dspace.core.Context; import org.dspace.core.LogHelper; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowItemService; +import org.dspace.workflow.WorkflowService; import org.swordapp.server.AuthCredentials; import org.swordapp.server.CollectionDepositManager; import org.swordapp.server.Deposit; @@ -37,6 +46,14 @@ public class CollectionDepositManagerDSpace extends DSpaceSwordAPI .getInstance().getCollectionService(); private VerboseDescription verboseDescription = new VerboseDescription(); + + + private final WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService(); + + private final WorkflowItemService workflowItemService = ContentServiceFactory.getInstance().getWorkflowItemService(); + + private final WorkflowService workflowService = ContentServiceFactory.getInstance().getWorkflowService(); + public DepositReceipt createNew(String collectionUri, Deposit deposit, AuthCredentials authCredentials, SwordConfiguration swordConfig) @@ -146,15 +163,19 @@ public class CollectionDepositManagerDSpace extends DSpaceSwordAPI .append("Total time for deposit processing: " + delta + " ms"); this.addVerboseDescription(receipt, this.verboseDescription); - - // if something hasn't killed it already (allowed), then complete the transaction + + // if duplicate DOI found, delete item + if(result.isDuplicateDoiFound()) { + this.deleteItem(context, result.getItem()); + } + sc.commit(); return receipt; } catch (DSpaceSwordException e) { log.error("caught exception:", e); throw new SwordServerException( - "There was a problem depositing the item", e); + e.getMessage(), e); } finally { // this is a read operation only, so there's never any need to commit the context if (sc != null) { @@ -180,7 +201,7 @@ public class CollectionDepositManagerDSpace extends DSpaceSwordAPI this.verboseDescription .append("Loaded ingester: " + si.getClass().getName()); - // do the deposit + // do the deposit (creates a WorkspaceItem with dummy metadata, as these are not processed yet) DepositResult result = si .ingest(context, deposit, collection, this.verboseDescription); this.verboseDescription.append("Archive ingest completed successfully"); @@ -293,4 +314,34 @@ public class CollectionDepositManagerDSpace extends DSpaceSwordAPI return collection; } + + private void deleteItem(Context context, Item item) { + + try { + //check if item in workflow + WorkflowItem wfi = workflowItemService.findByItem(context, item); + if (wfi != null) { + log.info("Item is in workflow - removing from workflow"); + this.workflowService.abort(context, wfi, context.getCurrentUser()); + } + //check if item in workspace + WorkspaceItem wsi = workspaceItemService.findByItem(context, item); + if (wsi != null) { + log.info("Item is in workspace - deleting workspace item"); + workspaceItemService.deleteAll(context, wsi); + } + //as a safeguard, delete the item if it still exists + if (itemService.find(context, item.getID()) != null) { + log.info("Item still exists - deleting item"); + itemService.delete(context, item); + } + } catch (SQLException ex) { + java.util.logging.Logger.getLogger(CollectionDepositManagerDSpace.class.getName()).log(Level.SEVERE, null, ex); + } catch (AuthorizeException ex) { + java.util.logging.Logger.getLogger(CollectionDepositManagerDSpace.class.getName()).log(Level.SEVERE, null, ex); + } catch (IOException ex) { + java.util.logging.Logger.getLogger(CollectionDepositManagerDSpace.class.getName()).log(Level.SEVERE, null, ex); + } + } + } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/DepositResult.java b/dspace-swordv2/src/main/java/org/dspace/sword2/DepositResult.java index 66924d088..3689da9ec 100755 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/DepositResult.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/DepositResult.java @@ -36,6 +36,16 @@ public class DepositResult { * The treatment of the item during deposit */ private String treatment; + + private boolean duplicateDoiFound = false; //default is false + + public boolean isDuplicateDoiFound() { + return duplicateDoiFound; + } + + public void setDuplicateDoiFound (boolean duplicateDoiFound) { + this.duplicateDoiFound = duplicateDoiFound; + } public Item getItem() { return item; diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManagerDefault.java b/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManagerDefault.java index ea5a52091..891c6b591 100755 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManagerDefault.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManagerDefault.java @@ -8,16 +8,31 @@ package org.dspace.sword2; import java.sql.SQLException; +import java.util.Arrays; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import org.dspace.content.Bitstream; import org.dspace.content.Bundle; import org.dspace.content.Collection; import org.dspace.content.Item; +import org.dspace.content.WorkspaceItem; +import org.dspace.content.factory.ContentServiceFactory; +import org.dspace.content.service.ItemService; +import org.dspace.content.service.MetadataValueService; +import org.dspace.content.service.WorkspaceItemService; import org.dspace.core.Constants; import org.dspace.core.Context; +import org.dspace.discovery.DiscoverQuery; +import org.dspace.discovery.DiscoverResult; +import org.dspace.discovery.SearchService; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowItemService; +import org.dspace.workflow.WorkflowService; +import org.springframework.beans.factory.annotation.Autowired; import org.swordapp.server.Deposit; import org.swordapp.server.SwordError; import org.swordapp.server.UriRegistry; @@ -28,8 +43,49 @@ import org.swordapp.server.UriRegistry; * performed on items which are in the deposit phase. */ public class WorkflowManagerDefault implements WorkflowManager { - private final ConfigurationService configurationService - = DSpaceServicesFactory.getInstance().getConfigurationService(); + + + private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(WorkflowManagerDefault.class); + + private final ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); + + private final ItemService itemService = ContentServiceFactory.getInstance().getItemService(); + + private final MetadataValueService metadataValueService = ContentServiceFactory.getInstance().getMetadataValueService(); + + + + + private boolean handleDuplicateDoi(Context context, Item item) { + try { + if(item == null) { + log.warn("handleDuplicateDoi(): Item is null, skipping duplicate check"); + return false; + } + + //retrieve the DOI from item's metadata + String doi = itemService.getMetadataFirstValue(item, "dc", "identifier", "doi", Item.ANY); + + //skip if no DOI is present + if (doi == null || doi.trim().isEmpty()) { + log.info("handleDuplicateDoi(): Incomming sword item has no DOI, skipping duplicate check"); + return false; + } + + //items with matching DOI + long result = metadataValueService.countDoiMatches(context, doi, + Arrays.asList(configurationService.getArrayProperty("swordv2-server.filter-doi.prefixes", new String[]{"https://doi.org/", "http://doi.org/"}))); + + if(result > 1) { + log.warn("handleDuplicateDoi(): Duplicate DOI found: {}", doi); + return true; + } + return false; + } catch (Exception e) { + log.warn("handleDuplicateDoi(): Error checking for DOI duplicates", e); + return false; + } + } @Override public void retrieveServiceDoc(Context context) throws SwordError { @@ -273,6 +329,14 @@ public class WorkflowManagerDefault implements WorkflowManager { // if we get to here this is a container operation, and we can decide how best to process Item item = result.getItem(); + if(configurationService.getBooleanProperty("swordv2-server.filter-doi") && this.handleDuplicateDoi(context, item)) { + log.info("Item with duplicate DOI has been found. Skipping resolveState."); + result.setDuplicateDoiFound(true); + result.setTreatment("Item skipped as the current item's DOI matches another item's DOI."); + verboseDescription.append("Duplicate Doi found, skipping import..."); + return; //avoid workflow processing + } + // find out where the item is in the workflow WorkflowTools wft = new WorkflowTools(); boolean inwf = wft.isItemInWorkflow(context, item); @@ -281,19 +345,13 @@ public class WorkflowManagerDefault implements WorkflowManager { // or find out if the item is in the archive boolean inarch = item.isArchived() || item.isWithdrawn(); - // in progress inws inwf inarch action description - // 0 0 0 1 NOTHING the deposit finished, and the item is in the - // archive; - // 0 0 1 0 NOTHING the deposit finished, and the item is in the - // workflow. Carry on as normal - // 0 1 0 0 START WF the deposit is finished, and the item is in the - // workflow, so we start it - // 1 0 0 1 NOTHING the deposit is not finished, and the item is in - // the archive; - // 1 0 1 0 STOP WF the deposit is not finished, and it is in the - // workflow. Pull it out into the workspace - // 1 1 0 0 NOTHING the deposit is not finished, and is in the - // workspace; leave it there +// in progress inws inwf inarch action description +// 0 0 0 1 NOTHING the deposit finished, and the item is in the archive; +// 0 0 1 0 NOTHING the deposit finished, and the item is in the workflow. Carry on as normal +// 0 1 0 0 START WF the deposit is finished, and the item is in the workflow, so we start it (if no DOI duplicate is found) +// 1 0 0 1 NOTHING the deposit is not finished, and the item is in the archive; +// 1 0 1 0 STOP WF the deposit is not finished, and it's in the workflow. Pull it out into the workspace +// 1 1 0 0 NOTHING the deposit is not finished, and is in the workspace; leave it there if (!deposit.isInProgress() && inarch) { verboseDescription @@ -302,11 +360,10 @@ public class WorkflowManagerDefault implements WorkflowManager { } if (!deposit.isInProgress() && inws) { - verboseDescription - .append("The deposit is finished: moving it from the workspace to the workflow"); + verboseDescription.append("The deposit is finished: moving it from the workspace to the workflow"); wft.startWorkflow(context, item); } - + if (deposit.isInProgress() && inarch) { verboseDescription .append("The deposit is not finished, and the item is already in the archive"); diff --git a/dspace/config/modules/swordv2-server.cfg b/dspace/config/modules/swordv2-server.cfg index ea191fbe0..0d0d80230 100755 --- a/dspace/config/modules/swordv2-server.cfg +++ b/dspace/config/modules/swordv2-server.cfg @@ -482,4 +482,11 @@ swordv2-server.state.withdrawn.description = The item has been withdrawn from th # URL template for items in the workspace (items in the archive will use the handle) swordv2-server.workspace.url-template = ${dspace.ui.url}/workspaceitems/#wsid#/edit +# a comma separated list of MIME types that a specific collection (provided handle) will accept (for ex.accept only pdf - NO images) +#swordv2-server.accept-mimetypes.collection.test-fau1743/20066 = application/pdf +# filter by DOI in order to check which documents are aleady imported and can be skipped +#swordv2-server.filter-doi = true + +# prefixes to consider when filtering the DOI (by default uses prefixes: http://doi.org/, https://doi.org/) +# swordv2-server.filter-doi.prefixes = http://dx.doi.org/, https://dx.doi.org/, http://doi.org, https://doi.org, doi: info:doi/ -- 2.25.1