diff --git a/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java index ddc4f2df2b..d378ecdb27 100644 --- a/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java @@ -147,6 +147,12 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService { return workspaceItemDAO.findByEPerson(context, ep); } + @Override + public List findByEPerson(Context context, EPerson ep, Integer limit, Integer offset) + throws SQLException { + return workspaceItemDAO.findByEPerson(context, ep, limit, offset); + } + @Override public List findByCollection(Context context, Collection collection) throws SQLException { return workspaceItemDAO.findByCollection(context, collection); @@ -231,6 +237,11 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService { return workspaceItemDAO.countRows(context); } + @Override + public int countByEPerson(Context context, EPerson ep) throws SQLException { + return workspaceItemDAO.countRows(context, ep); + } + @Override public List> getStageReachedCounts(Context context) throws SQLException { return workspaceItemDAO.getStageReachedCounts(context); diff --git a/dspace-api/src/main/java/org/dspace/content/dao/WorkspaceItemDAO.java b/dspace-api/src/main/java/org/dspace/content/dao/WorkspaceItemDAO.java index 63a66013f7..4ae8dc620b 100644 --- a/dspace-api/src/main/java/org/dspace/content/dao/WorkspaceItemDAO.java +++ b/dspace-api/src/main/java/org/dspace/content/dao/WorkspaceItemDAO.java @@ -30,6 +30,9 @@ public interface WorkspaceItemDAO extends GenericDAO { public List findByEPerson(Context context, EPerson ep) throws SQLException; + public List findByEPerson(Context context, EPerson ep, Integer limit, Integer offset) + throws SQLException; + public List findByCollection(Context context, Collection c) throws SQLException; public WorkspaceItem findByItem(Context context, Item i) throws SQLException; @@ -45,4 +48,7 @@ public interface WorkspaceItemDAO extends GenericDAO { int countRows(Context context) throws SQLException; List> getStageReachedCounts(Context context) throws SQLException; + + public int countRows(Context context, EPerson ep) throws SQLException; + } diff --git a/dspace-api/src/main/java/org/dspace/content/dao/impl/WorkspaceItemDAOImpl.java b/dspace-api/src/main/java/org/dspace/content/dao/impl/WorkspaceItemDAOImpl.java index 735f0cbf9d..ee98889294 100644 --- a/dspace-api/src/main/java/org/dspace/content/dao/impl/WorkspaceItemDAOImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/dao/impl/WorkspaceItemDAOImpl.java @@ -46,6 +46,20 @@ public class WorkspaceItemDAOImpl extends AbstractHibernateDAO im return list(query); } + @Override + public List findByEPerson(Context context, EPerson ep, Integer limit, Integer offset) + throws SQLException { + Criteria criteria = createCriteria(context, WorkspaceItem.class, "wi"); + criteria.addOrder(Order.asc("workspaceItemId")); + criteria.createAlias("wi.item", "item"); + criteria.createAlias("item.submitter", "submitter"); + + criteria.add(Restrictions.eq("submitter.id", ep.getID())); + criteria.setFirstResult(offset); + criteria.setMaxResults(limit); + return list(criteria); + } + @Override public List findByCollection(Context context, Collection c) throws SQLException { Criteria criteria = createCriteria(context, WorkspaceItem.class); @@ -99,6 +113,14 @@ public class WorkspaceItemDAOImpl extends AbstractHibernateDAO im return count(createQuery(context, "SELECT count(*) from WorkspaceItem")); } + @Override + public int countRows(Context context, EPerson ep) throws SQLException { + Query query = createQuery(context, + "SELECT count(*) from WorkspaceItem ws where ws.item.submitter = :submitter"); + query.setParameter("submitter", ep); + return count(query); + } + @Override @SuppressWarnings("unchecked") public List> getStageReachedCounts(Context context) throws SQLException { diff --git a/dspace-api/src/main/java/org/dspace/content/service/WorkspaceItemService.java b/dspace-api/src/main/java/org/dspace/content/service/WorkspaceItemService.java index 5b3f17e863..6f85033906 100644 --- a/dspace-api/src/main/java/org/dspace/content/service/WorkspaceItemService.java +++ b/dspace-api/src/main/java/org/dspace/content/service/WorkspaceItemService.java @@ -72,6 +72,21 @@ public interface WorkspaceItemService extends InProgressSubmissionService findByEPerson(Context context, EPerson ep) throws SQLException; + /** + * Get a page of workspace items for a particular e-person. These are ordered by + * workspace item ID, since this should likely keep them in the order in + * which they were created. + * + * @param context the context object + * @param ep the eperson + * @param limit the max number of workspaceitems to return + * @param offset the offset + * @return the corresponding workspace items + * @throws SQLException if database error + */ + public List findByEPerson(Context context, EPerson ep, Integer limit, Integer offset) + throws SQLException; + /** * Get all workspace items for a particular collection. * @@ -146,4 +161,8 @@ public interface WorkspaceItemService extends InProgressSubmissionService> getStageReachedCounts(Context context) throws SQLException; + + + public int countByEPerson(Context context, EPerson ep) throws SQLException; + } diff --git a/dspace-api/src/main/java/org/dspace/submit/AbstractProcessingStep.java b/dspace-api/src/main/java/org/dspace/submit/AbstractProcessingStep.java index 7424ab2942..17bd6423c0 100644 --- a/dspace-api/src/main/java/org/dspace/submit/AbstractProcessingStep.java +++ b/dspace-api/src/main/java/org/dspace/submit/AbstractProcessingStep.java @@ -7,10 +7,12 @@ */ package org.dspace.submit; +import org.dspace.app.itemimport.BTEBatchImportService; import org.dspace.authorize.factory.AuthorizeServiceFactory; import org.dspace.authorize.service.AuthorizeService; import org.dspace.content.InProgressSubmission; import org.dspace.content.factory.ContentServiceFactory; +import org.dspace.content.service.BitstreamFormatService; import org.dspace.content.service.BitstreamService; import org.dspace.content.service.BundleService; import org.dspace.content.service.CollectionService; @@ -20,24 +22,27 @@ import org.dspace.content.service.WorkspaceItemService; import org.dspace.core.Context; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; -import org.dspace.services.model.Request; /** - * Abstract processing class for DSpace Submission Steps. This defines the base - * methods which are required for any Step processing class. + * Abstract processing class for DSpace Submission Steps. This defines the base methods which are required for any Step + * processing class. */ public abstract class AbstractProcessingStep { protected AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService(); protected BitstreamService bitstreamService = ContentServiceFactory.getInstance().getBitstreamService(); + protected BitstreamFormatService bitstreamFormatService = ContentServiceFactory.getInstance() + .getBitstreamFormatService(); protected BundleService bundleService = ContentServiceFactory.getInstance().getBundleService(); protected CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService(); protected ItemService itemService = ContentServiceFactory.getInstance().getItemService(); protected MetadataFieldService metadataFieldService = ContentServiceFactory.getInstance().getMetadataFieldService(); protected ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService(); + protected BTEBatchImportService bteBatchImportService = DSpaceServicesFactory.getInstance().getServiceManager() + .getServiceByName("org.dspace.app.itemimport" + ".BTEBatchImportService", BTEBatchImportService.class); - public abstract void doProcessing(Context context, Request req, InProgressSubmission wsi); + public abstract void doPreProcessing(Context context, InProgressSubmission wsi); - public abstract void doPostProcessing(Context context, Request obj, InProgressSubmission wsi); + public abstract void doPostProcessing(Context context, InProgressSubmission wsi); } diff --git a/dspace-api/src/main/java/org/dspace/submit/extraction/MetadataExtractor.java b/dspace-api/src/main/java/org/dspace/submit/extraction/MetadataExtractor.java new file mode 100644 index 0000000000..ccaa6e05d1 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/submit/extraction/MetadataExtractor.java @@ -0,0 +1,50 @@ +/** + * 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.submit.extraction; + +import java.util.List; + +import gr.ekt.bte.dataloader.FileDataLoader; +import org.dspace.services.ConfigurationService; + +/** + * @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it) + */ +public class MetadataExtractor { + + private List extensions; + + private FileDataLoader dataLoader; + + private ConfigurationService configurationService; + + public List getExtensions() { + return extensions; + } + + public void setExtensions(List mime) { + this.extensions = mime; + } + + public FileDataLoader getDataLoader() { + return dataLoader; + } + + public void setDataLoader(FileDataLoader dataLoader) { + this.dataLoader = dataLoader; + } + + public ConfigurationService getConfigurationService() { + return configurationService; + } + + public void setConfigurationService(ConfigurationService configurationService) { + this.configurationService = configurationService; + } + +} diff --git a/dspace-api/src/main/java/org/dspace/submit/listener/MetadataListener.java b/dspace-api/src/main/java/org/dspace/submit/listener/MetadataListener.java new file mode 100644 index 0000000000..ddc8c04ae0 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/submit/listener/MetadataListener.java @@ -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 + * + * http://www.dspace.org/license/ + */ +package org.dspace.submit.listener; + +import java.util.Map; + +import gr.ekt.bte.core.DataLoader; +import org.dspace.services.ConfigurationService; + +public class MetadataListener { + + private Map metadata; + + private ConfigurationService configurationService; + + private Map dataloadersMap; + + public ConfigurationService getConfigurationService() { + return configurationService; + } + + public void setConfigurationService(ConfigurationService configurationService) { + this.configurationService = configurationService; + } + + public Map getMetadata() { + return metadata; + } + + public void setMetadata(Map metadata) { + this.metadata = metadata; + } + + public Map getDataloadersMap() { + return dataloadersMap; + } + + public void setDataloadersMap(Map dataloadersMap) { + this.dataloadersMap = dataloadersMap; + } + +} diff --git a/dspace-api/src/main/java/org/dspace/submit/step/AccessStep.java b/dspace-api/src/main/java/org/dspace/submit/step/AccessStep.java index dcff846d56..3cb16908f3 100644 --- a/dspace-api/src/main/java/org/dspace/submit/step/AccessStep.java +++ b/dspace-api/src/main/java/org/dspace/submit/step/AccessStep.java @@ -10,7 +10,6 @@ package org.dspace.submit.step; import org.apache.log4j.Logger; import org.dspace.content.InProgressSubmission; import org.dspace.core.Context; -import org.dspace.services.model.Request; import org.dspace.submit.AbstractProcessingStep; @@ -21,13 +20,13 @@ public class AccessStep extends AbstractProcessingStep { private static Logger log = Logger.getLogger(AccessStep.class); @Override - public void doProcessing(Context context, Request req, InProgressSubmission wsi) { + public void doPreProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } @Override - public void doPostProcessing(Context context, Request obj, InProgressSubmission wsi) { + public void doPostProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } diff --git a/dspace-api/src/main/java/org/dspace/submit/step/CCLicenseStep.java b/dspace-api/src/main/java/org/dspace/submit/step/CCLicenseStep.java index 79d2d47930..1c22849c3d 100644 --- a/dspace-api/src/main/java/org/dspace/submit/step/CCLicenseStep.java +++ b/dspace-api/src/main/java/org/dspace/submit/step/CCLicenseStep.java @@ -12,7 +12,6 @@ import org.dspace.content.InProgressSubmission; import org.dspace.core.Context; import org.dspace.license.factory.LicenseServiceFactory; import org.dspace.license.service.CreativeCommonsService; -import org.dspace.services.model.Request; import org.dspace.submit.AbstractProcessingStep; public class CCLicenseStep extends AbstractProcessingStep { @@ -25,15 +24,15 @@ public class CCLicenseStep extends AbstractProcessingStep { .getCreativeCommonsService(); @Override - public void doProcessing(Context context, Request req, InProgressSubmission wsi) { + public void doPreProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } @Override - public void doPostProcessing(Context context, Request obj, InProgressSubmission wsi) { + public void doPostProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } -} +} \ No newline at end of file diff --git a/dspace-api/src/main/java/org/dspace/submit/step/CompleteStep.java b/dspace-api/src/main/java/org/dspace/submit/step/CompleteStep.java index c7b4351d38..81966fedc9 100644 --- a/dspace-api/src/main/java/org/dspace/submit/step/CompleteStep.java +++ b/dspace-api/src/main/java/org/dspace/submit/step/CompleteStep.java @@ -10,7 +10,6 @@ package org.dspace.submit.step; import org.apache.log4j.Logger; import org.dspace.content.InProgressSubmission; import org.dspace.core.Context; -import org.dspace.services.model.Request; import org.dspace.submit.AbstractProcessingStep; public class CompleteStep extends AbstractProcessingStep { @@ -20,13 +19,13 @@ public class CompleteStep extends AbstractProcessingStep { private static Logger log = Logger.getLogger(CompleteStep.class); @Override - public void doProcessing(Context context, Request req, InProgressSubmission wsi) { + public void doPreProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } @Override - public void doPostProcessing(Context context, Request obj, InProgressSubmission wsi) { + public void doPostProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } diff --git a/dspace-api/src/main/java/org/dspace/submit/step/DescribeStep.java b/dspace-api/src/main/java/org/dspace/submit/step/DescribeStep.java index 38ae4a576e..c1d679eab1 100644 --- a/dspace-api/src/main/java/org/dspace/submit/step/DescribeStep.java +++ b/dspace-api/src/main/java/org/dspace/submit/step/DescribeStep.java @@ -8,30 +8,14 @@ package org.dspace.submit.step; import org.apache.log4j.Logger; -import org.dspace.content.InProgressSubmission; -import org.dspace.core.Context; -import org.dspace.services.model.Request; -import org.dspace.submit.AbstractProcessingStep; - -public class DescribeStep extends AbstractProcessingStep { +/** + * @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it) + */ +public class DescribeStep extends MetadataStep { /** * log4j logger */ private static Logger log = Logger.getLogger(DescribeStep.class); - - @Override - public void doProcessing(Context context, Request req, InProgressSubmission wsi) { - // TODO Auto-generated method stub - - } - - - @Override - public void doPostProcessing(Context context, Request obj, InProgressSubmission wsi) { - // TODO Auto-generated method stub - - } - } diff --git a/dspace-api/src/main/java/org/dspace/submit/step/ExtractionStep.java b/dspace-api/src/main/java/org/dspace/submit/step/ExtractionStep.java new file mode 100644 index 0000000000..70f0cacfef --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/submit/step/ExtractionStep.java @@ -0,0 +1,22 @@ +/** + * 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.submit.step; + +import org.apache.log4j.Logger; + +/** + * @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it) + */ +public class ExtractionStep extends MetadataStep { + /** + * log4j logger + */ + private static Logger log = Logger + .getLogger(ExtractionStep.class); + +} \ No newline at end of file diff --git a/dspace-api/src/main/java/org/dspace/submit/step/InitialQuestionsStep.java b/dspace-api/src/main/java/org/dspace/submit/step/InitialQuestionsStep.java index 3b17ad7b74..e5d9615add 100644 --- a/dspace-api/src/main/java/org/dspace/submit/step/InitialQuestionsStep.java +++ b/dspace-api/src/main/java/org/dspace/submit/step/InitialQuestionsStep.java @@ -9,19 +9,18 @@ package org.dspace.submit.step; import org.dspace.content.InProgressSubmission; import org.dspace.core.Context; -import org.dspace.services.model.Request; import org.dspace.submit.AbstractProcessingStep; public class InitialQuestionsStep extends AbstractProcessingStep { @Override - public void doProcessing(Context context, Request req, InProgressSubmission wsi) { + public void doPreProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } @Override - public void doPostProcessing(Context context, Request obj, InProgressSubmission wsi) { + public void doPostProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } diff --git a/dspace-api/src/main/java/org/dspace/submit/step/LicenseStep.java b/dspace-api/src/main/java/org/dspace/submit/step/LicenseStep.java index 217c7d5a7a..d54dbac79c 100644 --- a/dspace-api/src/main/java/org/dspace/submit/step/LicenseStep.java +++ b/dspace-api/src/main/java/org/dspace/submit/step/LicenseStep.java @@ -10,7 +10,6 @@ package org.dspace.submit.step; import org.apache.log4j.Logger; import org.dspace.content.InProgressSubmission; import org.dspace.core.Context; -import org.dspace.services.model.Request; import org.dspace.submit.AbstractProcessingStep; public class LicenseStep extends AbstractProcessingStep { @@ -21,13 +20,13 @@ public class LicenseStep extends AbstractProcessingStep { private static Logger log = Logger.getLogger(LicenseStep.class); @Override - public void doProcessing(Context context, Request req, InProgressSubmission wsi) { + public void doPreProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } @Override - public void doPostProcessing(Context context, Request obj, InProgressSubmission wsi) { + public void doPostProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } diff --git a/dspace-api/src/main/java/org/dspace/submit/step/MetadataStep.java b/dspace-api/src/main/java/org/dspace/submit/step/MetadataStep.java new file mode 100644 index 0000000000..1c8b411eb5 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/submit/step/MetadataStep.java @@ -0,0 +1,196 @@ +/** + * 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.submit.step; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import gr.ekt.bte.core.DataLoader; +import gr.ekt.bte.core.Record; +import gr.ekt.bte.core.Value; +import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpException; +import org.apache.log4j.Logger; +import org.dspace.authorize.AuthorizeException; +import org.dspace.content.InProgressSubmission; +import org.dspace.content.Item; +import org.dspace.content.MetadataValue; +import org.dspace.core.Context; +import org.dspace.core.Utils; +import org.dspace.services.factory.DSpaceServicesFactory; +import org.dspace.submit.AbstractProcessingStep; +import org.dspace.submit.listener.MetadataListener; +import org.dspace.submit.lookup.SubmissionLookupDataLoader; + +/** + * @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it) + */ +public class MetadataStep extends AbstractProcessingStep { + /** + * log4j logger + */ + private static Logger log = Logger.getLogger(MetadataStep.class); + + protected List listeners = DSpaceServicesFactory.getInstance().getServiceManager() + .getServicesByType(MetadataListener.class); + + protected Map> metadataMap = new HashMap>(); + private Map> results = new HashMap>(); + private Map mappingIdentifier = new HashMap(); + + @Override + public void doPreProcessing(Context context, InProgressSubmission wsi) { + for (MetadataListener listener : listeners) { + for (String metadata : listener.getMetadata().keySet()) { + String[] tokenized = Utils.tokenize(metadata); + List mm = itemService.getMetadata(wsi.getItem(), tokenized[0], tokenized[1], + tokenized[2], Item.ANY); + if (mm != null && !mm.isEmpty()) { + metadataMap.put(metadata, mm); + } else { + metadataMap.put(metadata, new ArrayList()); + } + mappingIdentifier.put(metadata, listener.getMetadata().get(metadata)); + } + } + } + + @Override + public void doPostProcessing(Context context, InProgressSubmission wsi) { + external: + for (String metadata : metadataMap.keySet()) { + String[] tokenized = Utils.tokenize(metadata); + List currents = itemService.getMetadata(wsi.getItem(), tokenized[0], tokenized[1], + tokenized[2], Item.ANY); + if (currents != null && !currents.isEmpty()) { + List olds = metadataMap.get(metadata); + if (olds.isEmpty()) { + process(context, metadata, currents); + continue external; + } + internal: + for (MetadataValue current : currents) { + + boolean found = false; + for (MetadataValue old : olds) { + if (old.getValue().equals(current.getValue())) { + found = true; + } + } + if (!found) { + process(context, metadata, current); + } + } + } + } + + if (!results.isEmpty()) { + for (MetadataListener listener : listeners) { + for (DataLoader dataLoader : listener.getDataloadersMap().values()) { + SubmissionLookupDataLoader submissionLookupDataLoader = (SubmissionLookupDataLoader) dataLoader; + try { + List recordSet = submissionLookupDataLoader.getByIdentifier(context, results); + List resultSet = convertFields(recordSet, bteBatchImportService.getOutputMap()); + enrichItem(context, resultSet, wsi.getItem()); + } catch (HttpException | IOException | SQLException | AuthorizeException e) { + log.error(e.getMessage(), e); + } + } + } + } + } + + protected void enrichItem(Context context, List rset, Item item) throws SQLException, AuthorizeException { + for (Record record : rset) { + for (String field : record.getFields()) { + try { + String[] tfield = Utils.tokenize(field); + List mdvs = itemService + .getMetadata(item, tfield[0], tfield[1], tfield[2], Item.ANY); + if (mdvs == null || mdvs.isEmpty()) { + for (Value value : record.getValues(field)) { + + itemService.addMetadata(context, item, tfield[0], tfield[1], tfield[2], null, + value.getAsString()); + } + } else { + external: + for (Value value : record.getValues(field)) { + boolean found = false; + for (MetadataValue mdv : mdvs) { + if (mdv.getValue().equals(value.getAsString())) { + found = true; + continue external; + } + } + if (!found) { + itemService.addMetadata(context, item, tfield[0], tfield[1], tfield[2], null, + value.getAsString()); + } + } + } + } catch (SQLException e) { + log.error(e.getMessage(), e); + } + } + } + itemService.update(context, item); + + } + + private void process(Context context, String metadata, List currents) { + for (MetadataValue current : currents) { + process(context, metadata, current); + } + } + + private void process(Context context, String metadata, MetadataValue current) { + String key = mappingIdentifier.get(metadata); + Set identifiers = null; + if (!results.containsKey(key)) { + identifiers = new HashSet(); + } else { + identifiers = results.get(key); + } + identifiers.add(current.getValue()); + results.put(key, identifiers); + } + + public List convertFields(List recordSet, Map fieldMap) { + List result = new ArrayList(); + for (Record publication : recordSet) { + for (String fieldName : fieldMap.keySet()) { + String md = null; + if (fieldMap != null) { + md = fieldMap.get(fieldName); + } + + if (StringUtils.isBlank(md)) { + continue; + } else { + md = md.trim(); + } + + if (publication.isMutable()) { + List values = publication.getValues(md); + publication.makeMutable().removeField(md); + publication.makeMutable().addField(fieldName, values); + } + } + + result.add(publication); + } + return result; + } +} diff --git a/dspace-api/src/main/java/org/dspace/submit/step/SampleStep.java b/dspace-api/src/main/java/org/dspace/submit/step/SampleStep.java index ea2ccfc1ca..705422d015 100644 --- a/dspace-api/src/main/java/org/dspace/submit/step/SampleStep.java +++ b/dspace-api/src/main/java/org/dspace/submit/step/SampleStep.java @@ -9,19 +9,18 @@ package org.dspace.submit.step; import org.dspace.content.InProgressSubmission; import org.dspace.core.Context; -import org.dspace.services.model.Request; import org.dspace.submit.AbstractProcessingStep; public class SampleStep extends AbstractProcessingStep { @Override - public void doProcessing(Context context, Request req, InProgressSubmission wsi) { + public void doPreProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } @Override - public void doPostProcessing(Context context, Request obj, InProgressSubmission wsi) { + public void doPostProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } diff --git a/dspace-api/src/main/java/org/dspace/submit/step/SelectCollectionStep.java b/dspace-api/src/main/java/org/dspace/submit/step/SelectCollectionStep.java index 08807234aa..11b9b3e126 100644 --- a/dspace-api/src/main/java/org/dspace/submit/step/SelectCollectionStep.java +++ b/dspace-api/src/main/java/org/dspace/submit/step/SelectCollectionStep.java @@ -10,7 +10,6 @@ package org.dspace.submit.step; import org.apache.log4j.Logger; import org.dspace.content.InProgressSubmission; import org.dspace.core.Context; -import org.dspace.services.model.Request; import org.dspace.submit.AbstractProcessingStep; public class SelectCollectionStep extends AbstractProcessingStep { @@ -18,13 +17,13 @@ public class SelectCollectionStep extends AbstractProcessingStep { private static final Logger log = Logger.getLogger(SelectCollectionStep.class); @Override - public void doProcessing(Context context, Request req, InProgressSubmission wsi) { + public void doPreProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } @Override - public void doPostProcessing(Context context, Request obj, InProgressSubmission wsi) { + public void doPostProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } diff --git a/dspace-api/src/main/java/org/dspace/submit/step/StartSubmissionLookupStep.java b/dspace-api/src/main/java/org/dspace/submit/step/StartSubmissionLookupStep.java index df9498a111..903100d1f6 100644 --- a/dspace-api/src/main/java/org/dspace/submit/step/StartSubmissionLookupStep.java +++ b/dspace-api/src/main/java/org/dspace/submit/step/StartSubmissionLookupStep.java @@ -10,7 +10,6 @@ package org.dspace.submit.step; import org.apache.log4j.Logger; import org.dspace.content.InProgressSubmission; import org.dspace.core.Context; -import org.dspace.services.model.Request; import org.dspace.submit.AbstractProcessingStep; public class StartSubmissionLookupStep extends AbstractProcessingStep { @@ -21,14 +20,14 @@ public class StartSubmissionLookupStep extends AbstractProcessingStep { .getLogger(StartSubmissionLookupStep.class); @Override - public void doProcessing(Context context, Request req, InProgressSubmission wsi) { + public void doPreProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } @Override - public void doPostProcessing(Context context, Request obj, InProgressSubmission wsi) { + public void doPostProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } -} +} \ No newline at end of file diff --git a/dspace-api/src/main/java/org/dspace/submit/step/UploadStep.java b/dspace-api/src/main/java/org/dspace/submit/step/UploadStep.java index d94ce8b5ec..8e528eb0a4 100644 --- a/dspace-api/src/main/java/org/dspace/submit/step/UploadStep.java +++ b/dspace-api/src/main/java/org/dspace/submit/step/UploadStep.java @@ -10,7 +10,6 @@ package org.dspace.submit.step; import org.apache.log4j.Logger; import org.dspace.content.InProgressSubmission; import org.dspace.core.Context; -import org.dspace.services.model.Request; import org.dspace.submit.AbstractProcessingStep; public class UploadStep extends AbstractProcessingStep { @@ -20,13 +19,13 @@ public class UploadStep extends AbstractProcessingStep { private static final Logger log = Logger.getLogger(UploadStep.class); @Override - public void doProcessing(Context context, Request req, InProgressSubmission wsi) { + public void doPreProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } @Override - public void doPostProcessing(Context context, Request obj, InProgressSubmission wsi) { + public void doPostProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } diff --git a/dspace-api/src/main/java/org/dspace/submit/step/VerifyStep.java b/dspace-api/src/main/java/org/dspace/submit/step/VerifyStep.java index fa18b10808..2e9d9caa8a 100644 --- a/dspace-api/src/main/java/org/dspace/submit/step/VerifyStep.java +++ b/dspace-api/src/main/java/org/dspace/submit/step/VerifyStep.java @@ -9,19 +9,18 @@ package org.dspace.submit.step; import org.dspace.content.InProgressSubmission; import org.dspace.core.Context; -import org.dspace.services.model.Request; import org.dspace.submit.AbstractProcessingStep; public class VerifyStep extends AbstractProcessingStep { @Override - public void doProcessing(Context context, Request req, InProgressSubmission wsi) { + public void doPreProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } @Override - public void doPostProcessing(Context context, Request obj, InProgressSubmission wsi) { + public void doPostProcessing(Context context, InProgressSubmission wsi) { // TODO Auto-generated method stub } diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/converter/WorkspaceItemConverter.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/converter/WorkspaceItemConverter.java index 65420b79d5..4b8bcd9700 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/converter/WorkspaceItemConverter.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/converter/WorkspaceItemConverter.java @@ -24,7 +24,6 @@ import org.dspace.app.util.SubmissionStepConfig; import org.dspace.content.Collection; import org.dspace.content.Item; import org.dspace.eperson.EPerson; -import org.dspace.submit.AbstractProcessingStep; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -103,22 +102,20 @@ public class WorkspaceItemConverter Object stepInstance = stepClass.newInstance(); - if (stepInstance instanceof AbstractProcessingStep) { + if (stepInstance instanceof AbstractRestProcessingStep) { // load the interface for this step - AbstractRestProcessingStep stepProcessing = (AbstractRestProcessingStep) stepClass - .newInstance(); + AbstractRestProcessingStep stepProcessing = + (AbstractRestProcessingStep) stepClass.newInstance(); for (ErrorRest error : stepProcessing.validate(submissionService, obj, stepConfig)) { addError(witem.getErrors(), error); } witem.getSections() - .put(sections.getId(), stepProcessing.getData(submissionService, obj, stepConfig)); + .put(sections.getId(), stepProcessing.getData(submissionService, obj, stepConfig)); } else { - throw new Exception("The submission step class specified by '" - + stepConfig.getProcessingClassName() - + "' does not extend the class org.dspace.app.rest.submit" + - ".AbstractRestProcessingStep!" - + " Therefore it cannot be used by the Configurable Submission as the" + - " !"); + log.warn("The submission step class specified by '" + stepConfig.getProcessingClassName() + + "' does not extend the class org.dspace.app.rest.submit.AbstractRestProcessingStep!" + + " Therefore it cannot be used by the Configurable Submission as the " + + "!"); } } catch (Exception e) { diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/model/BaseObjectRest.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/model/BaseObjectRest.java index 0d82fffd54..1fe4174973 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/model/BaseObjectRest.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/model/BaseObjectRest.java @@ -28,6 +28,13 @@ public abstract class BaseObjectRest implements Identifi @JsonInclude(Include.NON_EMPTY) private List errors; + private Boolean status; + + @JsonInclude(Include.NON_NULL) + public Boolean isStatus() { + return status; + } + @Override public T getId() { return id; @@ -48,4 +55,7 @@ public abstract class BaseObjectRest implements Identifi this.errors = errors; } + public void setStatus(Boolean status) { + this.status = status; + } } diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/DSpaceRestRepository.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/DSpaceRestRepository.java index 5f7ad56c3d..050f547296 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/DSpaceRestRepository.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/DSpaceRestRepository.java @@ -7,8 +7,11 @@ */ package org.dspace.app.rest.repository; +import java.io.FileNotFoundException; +import java.io.IOException; import java.io.Serializable; import java.sql.SQLException; + import javax.servlet.http.HttpServletRequest; import org.apache.log4j.Logger; @@ -19,7 +22,6 @@ import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.RestAddressableModel; import org.dspace.app.rest.model.hateoas.DSpaceResource; import org.dspace.app.rest.model.patch.Patch; -import org.dspace.app.rest.model.step.UploadStatusResponse; import org.dspace.app.util.DCInputsReaderException; import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; @@ -172,11 +174,12 @@ public abstract class DSpaceRestRepository U upload(HttpServletRequest request, String apiCategory, String model, + public T upload(HttpServletRequest request, String apiCategory, String model, ID id, String extraField, MultipartFile file) throws Exception { throw new RuntimeException("No implementation found; Method not allowed!"); } @@ -201,4 +204,17 @@ public abstract class DSpaceRestRepository upload(HttpServletRequest request, MultipartFile uploadfile) + throws SQLException, FileNotFoundException, IOException, AuthorizeException { + Context context = obtainContext(); + Iterable entity = upload(context, request, uploadfile); + context.commit(); + return entity; + } + + protected Iterable upload(Context context, HttpServletRequest request, MultipartFile uploadfile) + throws SQLException, FileNotFoundException, IOException, AuthorizeException { + throw new RuntimeException("No implementation found; Method not allowed!"); + } + } diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/WorkspaceItemRestRepository.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/WorkspaceItemRestRepository.java index 9ae4ce80a0..3bff819652 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/WorkspaceItemRestRepository.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/WorkspaceItemRestRepository.java @@ -7,47 +7,60 @@ */ package org.dspace.app.rest.repository; -import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStream; import java.sql.SQLException; +import java.util.ArrayList; import java.util.List; import java.util.UUID; import javax.servlet.http.HttpServletRequest; +import gr.ekt.bte.core.TransformationEngine; +import gr.ekt.bte.core.TransformationSpec; +import gr.ekt.bte.exceptions.BadTransformationSpec; +import gr.ekt.bte.exceptions.MalformedSourceException; +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; import org.dspace.app.rest.converter.WorkspaceItemConverter; import org.dspace.app.rest.exception.PatchBadRequestException; +import org.dspace.app.rest.model.ErrorRest; import org.dspace.app.rest.model.WorkspaceItemRest; import org.dspace.app.rest.model.hateoas.WorkspaceItemResource; import org.dspace.app.rest.model.patch.Operation; import org.dspace.app.rest.model.patch.Patch; -import org.dspace.app.rest.model.step.UploadBitstreamRest; import org.dspace.app.rest.submit.AbstractRestProcessingStep; import org.dspace.app.rest.submit.SubmissionService; +import org.dspace.app.rest.submit.UploadableStep; +import org.dspace.app.rest.utils.Utils; import org.dspace.app.util.SubmissionConfig; import org.dspace.app.util.SubmissionConfigReader; import org.dspace.app.util.SubmissionConfigReaderException; import org.dspace.app.util.SubmissionStepConfig; import org.dspace.authorize.AuthorizeException; -import org.dspace.content.Bitstream; -import org.dspace.content.BitstreamFormat; -import org.dspace.content.Bundle; -import org.dspace.content.Item; +import org.dspace.content.Collection; import org.dspace.content.WorkspaceItem; import org.dspace.content.service.BitstreamFormatService; import org.dspace.content.service.BitstreamService; +import org.dspace.content.service.CollectionService; import org.dspace.content.service.ItemService; import org.dspace.content.service.WorkspaceItemService; import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.EPersonServiceImpl; +import org.dspace.event.Event; import org.dspace.services.ConfigurationService; import org.dspace.submit.AbstractProcessingStep; +import org.dspace.submit.lookup.DSpaceWorkspaceItemOutputGenerator; +import org.dspace.submit.lookup.MultipleSubmissionLookupDataLoader; +import org.dspace.submit.lookup.SubmissionItemDataLoader; +import org.dspace.submit.lookup.SubmissionLookupOutputGenerator; +import org.dspace.submit.lookup.SubmissionLookupService; +import org.dspace.submit.util.ItemSubmissionLookupDTO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -60,7 +73,6 @@ import org.springframework.web.multipart.MultipartFile; * * @author Andrea Bollini (andrea.bollini at 4science.it) */ - @Component(WorkspaceItemRest.CATEGORY + "." + WorkspaceItemRest.NAME) public class WorkspaceItemRestRepository extends DSpaceRestRepository { @@ -87,6 +99,12 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository bundles = itemService.getBundles(item, Constants.CONTENT_BUNDLE_NAME); + WorkspaceItemRest wsi = findOne(id); + WorkspaceItem source = wis.find(context, id); + List errors = new ArrayList(); + SubmissionConfig submissionConfig = + submissionConfigReader.getSubmissionConfigByName(wsi.getSubmissionDefinition().getName()); + for (int i = 0; i < submissionConfig.getNumberOfSteps(); i++) { + SubmissionStepConfig stepConfig = submissionConfig.getStep(i); - try { - InputStream inputStream = new BufferedInputStream(file.getInputStream()); - if (bundles.size() < 1) { - // set bundle's name to ORIGINAL - source = itemService.createSingleBitstream(context, inputStream, item, Constants.CONTENT_BUNDLE_NAME); - } else { - // we have a bundle already, just add bitstream - source = bitstreamService.create(context, bundles.get(0), inputStream); + /* + * First, load the step processing class (using the current + * class loader) + */ + ClassLoader loader = this.getClass().getClassLoader(); + Class stepClass; + try { + stepClass = loader.loadClass(stepConfig.getProcessingClassName()); + + Object stepInstance = stepClass.newInstance(); + if (UploadableStep.class.isAssignableFrom(stepClass)) { + UploadableStep uploadableStep = (UploadableStep) stepInstance; + uploadableStep.doPreProcessing(context, source); + ErrorRest err = + uploadableStep.upload(context, submissionService, stepConfig, source, file, extraField); + uploadableStep.doPostProcessing(context, source); + if (err != null) { + errors.add(err); + } + } + + } catch (Exception e) { + log.error(e.getMessage(), e); } - } catch (Exception e) { - log.error(e.getMessage(), e); - result = new UploadBitstreamRest(); - result.setMessage(e.getMessage()); - result.setStatus(false); - return result; + + } + wsi = converter.convert(source); + + if (errors.isEmpty()) { + wsi.setStatus(true); + } else { + wsi.setStatus(false); + wsi.getErrors().addAll(errors); } - source.setName(context, file.getOriginalFilename()); - // TODO how retrieve this information? - source.setSource(context, extraField); - - // Identify the format - bf = bitstreamFormatService.guessFormat(context, source); - source.setFormat(context, bf); - - // Update to DB - bitstreamService.update(context, source); - itemService.update(context, item); context.commit(); - - result = submissionService.buildUploadBitstream(configurationService, source); - result.setStatus(true); - return result; + return wsi; } //TODO @PreAuthorize("hasPermission(#id, 'WORKSPACEITEM', 'WRITE')") @@ -290,16 +311,16 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository!"); + throw new PatchBadRequestException( + "The submission step class specified by '" + stepConfig.getProcessingClassName() + + "' does not extend the class org.dspace.submit.AbstractProcessingStep!" + + " Therefore it cannot be used by the Configurable Submission as the !"); } } catch (Exception e) { @@ -316,8 +337,154 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository upload(Context context, HttpServletRequest request, MultipartFile uploadfile) + throws SQLException, FileNotFoundException, IOException, AuthorizeException { + File file = Utils.getFile(uploadfile, "upload-loader", "filedataloader"); + List results = new ArrayList<>(); + + try { + String uuid = request.getParameter("collection"); + if (StringUtils.isBlank(uuid)) { + uuid = configurationService.getProperty("submission.default.collection"); + } + + Collection collection = null; + if (StringUtils.isNotBlank(uuid)) { + collection = collectionService.find(context, UUID.fromString(uuid)); + } else { + collection = collectionService.findAll(context, 1, 0).get(0); + } + + SubmissionConfig submissionConfig = + submissionConfigReader.getSubmissionConfigByCollection(collection.getHandle()); + + + List tmpResult = new ArrayList(); + + TransformationEngine transformationEngine1 = submissionLookupService.getPhase1TransformationEngine(); + if (transformationEngine1 != null) { + MultipleSubmissionLookupDataLoader dataLoader = + (MultipleSubmissionLookupDataLoader) transformationEngine1.getDataLoader(); + + List fileDataLoaders = submissionLookupService.getFileProviders(); + for (String fileDataLoader : fileDataLoaders) { + dataLoader.setFile(file.getAbsolutePath(), fileDataLoader); + + try { + SubmissionLookupOutputGenerator outputGenerator = + (SubmissionLookupOutputGenerator) transformationEngine1.getOutputGenerator(); + outputGenerator.setDtoList(new ArrayList()); + log.debug("BTE transformation is about to start!"); + transformationEngine1.transform(new TransformationSpec()); + log.debug("BTE transformation finished!"); + tmpResult.addAll(outputGenerator.getDtoList()); + if (!tmpResult.isEmpty()) { + //exit with the results founded on the first data provided + break; + } + } catch (BadTransformationSpec e1) { + log.error(e1.getMessage(), e1); + } catch (MalformedSourceException e1) { + log.error(e1.getMessage(), e1); + } + } + } + + List result = null; + + //try to ingest workspaceitems + if (!tmpResult.isEmpty()) { + TransformationEngine transformationEngine2 = submissionLookupService.getPhase2TransformationEngine(); + if (transformationEngine2 != null) { + SubmissionItemDataLoader dataLoader = + (SubmissionItemDataLoader) transformationEngine2.getDataLoader(); + dataLoader.setDtoList(tmpResult); + // dataLoader.setProviders() + + DSpaceWorkspaceItemOutputGenerator outputGenerator = + (DSpaceWorkspaceItemOutputGenerator) transformationEngine2.getOutputGenerator(); + outputGenerator.setCollection(collection); + outputGenerator.setContext(context); + outputGenerator.setFormName(submissionConfig.getSubmissionName()); + outputGenerator.setDto(tmpResult.get(0)); + + try { + transformationEngine2.transform(new TransformationSpec()); + result = outputGenerator.getWitems(); + } catch (BadTransformationSpec e1) { + e1.printStackTrace(); + } catch (MalformedSourceException e1) { + e1.printStackTrace(); + } + } + } + + //we have to create the workspaceitem to push the file also if nothing found before + if (result == null) { + WorkspaceItem source = + submissionService.createWorkspaceItem(context, getRequestService().getCurrentRequest()); + result = new ArrayList<>(); + result.add(source); + } + + //perform upload of bitstream if there is exact one result and convert workspaceitem to entity rest + if (result != null && !result.isEmpty()) { + for (WorkspaceItem wi : result) { + + List errors = new ArrayList(); + + //load bitstream into bundle ORIGINAL only if there is one result (approximately this is the + // right behaviour for pdf file but not for other bibliographic format e.g. bibtex) + if (result.size() == 1) { + + for (int i = 0; i < submissionConfig.getNumberOfSteps(); i++) { + SubmissionStepConfig stepConfig = submissionConfig.getStep(i); + + ClassLoader loader = this.getClass().getClassLoader(); + Class stepClass; + try { + stepClass = loader.loadClass(stepConfig.getProcessingClassName()); + + Object stepInstance = stepClass.newInstance(); + if (UploadableStep.class.isAssignableFrom(stepClass)) { + UploadableStep uploadableStep = (UploadableStep) stepInstance; + ErrorRest err = uploadableStep + .upload(context, submissionService, stepConfig, wi, uploadfile, + file.getAbsolutePath()); + if (err != null) { + errors.add(err); + } + } + + } catch (Exception e) { + log.error(e.getMessage(), e); + } + } + } + WorkspaceItemRest wsi = converter.convert(wi); + if (result.size() == 1) { + if (errors.isEmpty()) { + wsi.setStatus(true); + } else { + wsi.setStatus(false); + wsi.getErrors().addAll(errors); + } + } + results.add(wsi); + } + } + } finally { + file.delete(); + } + return results; + } + } \ No newline at end of file diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/submit/AbstractRestProcessingStep.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/submit/AbstractRestProcessingStep.java index 2b938d6093..efc477be97 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/submit/AbstractRestProcessingStep.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/submit/AbstractRestProcessingStep.java @@ -25,7 +25,7 @@ import org.dspace.services.model.Request; * * @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it) */ -public interface AbstractRestProcessingStep { +public interface AbstractRestProcessingStep extends ListenerProcessingStep { public static final String DESCRIBE_STEP_METADATA_OPERATION_ENTRY = "itemmetadata"; public static final String COLLECTION_STEP_OPERATION_ENTRY = "collection"; diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/submit/ListenerProcessingStep.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/submit/ListenerProcessingStep.java new file mode 100644 index 0000000000..72bcc35da8 --- /dev/null +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/submit/ListenerProcessingStep.java @@ -0,0 +1,22 @@ +/** + * 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.submit; + +import org.dspace.content.InProgressSubmission; +import org.dspace.core.Context; + +/** + * @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it) + */ +public interface ListenerProcessingStep { + + public void doPreProcessing(Context context, InProgressSubmission wsi); + + public void doPostProcessing(Context context, InProgressSubmission wsi); + +} diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/submit/UploadableStep.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/submit/UploadableStep.java new file mode 100644 index 0000000000..e416b4cddd --- /dev/null +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/submit/UploadableStep.java @@ -0,0 +1,26 @@ +/** + * 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.submit; + +import java.io.IOException; + +import org.dspace.app.rest.model.ErrorRest; +import org.dspace.app.util.SubmissionStepConfig; +import org.dspace.content.InProgressSubmission; +import org.dspace.core.Context; +import org.springframework.web.multipart.MultipartFile; + +/** + * @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it) + */ +public interface UploadableStep extends ListenerProcessingStep { + + public ErrorRest upload(Context context, SubmissionService submissionService, SubmissionStepConfig stepConfig, + InProgressSubmission wsi, MultipartFile file, String extraField) throws IOException; + +} diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/submit/step/ExtractMetadataStep.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/submit/step/ExtractMetadataStep.java new file mode 100644 index 0000000000..7353a9cf03 --- /dev/null +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/submit/step/ExtractMetadataStep.java @@ -0,0 +1,110 @@ +/** + * 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.submit.step; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import gr.ekt.bte.core.Record; +import gr.ekt.bte.core.RecordSet; +import gr.ekt.bte.core.Value; +import gr.ekt.bte.dataloader.FileDataLoader; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.dspace.app.rest.model.ErrorRest; +import org.dspace.app.rest.repository.WorkspaceItemRestRepository; +import org.dspace.app.rest.submit.SubmissionService; +import org.dspace.app.rest.submit.UploadableStep; +import org.dspace.app.rest.utils.Utils; +import org.dspace.app.util.SubmissionStepConfig; +import org.dspace.content.InProgressSubmission; +import org.dspace.content.Item; +import org.dspace.core.Context; +import org.dspace.services.factory.DSpaceServicesFactory; +import org.dspace.submit.extraction.MetadataExtractor; +import org.dspace.submit.step.ExtractionStep; +import org.springframework.web.multipart.MultipartFile; + +/** + * @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it) + */ +public class ExtractMetadataStep extends ExtractionStep implements UploadableStep { + + private static final Logger log = Logger.getLogger(ExtractMetadataStep.class); + + @Override + public ErrorRest upload(Context context, SubmissionService submissionService, SubmissionStepConfig stepConfig, + InProgressSubmission wsi, MultipartFile multipartFile, String extraField) + throws IOException { + + Item item = wsi.getItem(); + try { + List extractors = + DSpaceServicesFactory.getInstance().getServiceManager().getServicesByType(MetadataExtractor.class); + File file = null; + for (MetadataExtractor extractor : extractors) { + FileDataLoader dataLoader = extractor.getDataLoader(); + RecordSet recordSet = null; + if (extractor.getExtensions() + .contains(FilenameUtils.getExtension(multipartFile.getOriginalFilename()))) { + + if (file == null) { + file = Utils.getFile(multipartFile, "submissionlookup-loader", stepConfig.getId()); + } + + FileDataLoader fdl = (FileDataLoader) dataLoader; + fdl.setFilename(file.getAbsolutePath()); + + + recordSet = convertFields(dataLoader.getRecords(), bteBatchImportService.getOutputMap()); + + enrichItem(context, recordSet.getRecords(), item); + + } + } + } catch (Exception e) { + log.error(e.getMessage(), e); + ErrorRest result = new ErrorRest(); + result.setMessage(e.getMessage()); + result.getPaths().add("/" + WorkspaceItemRestRepository.OPERATION_PATH_SECTIONS + "/" + stepConfig.getId()); + return result; + } + return null; + } + + public RecordSet convertFields(RecordSet recordSet, Map fieldMap) { + RecordSet result = new RecordSet(); + for (Record publication : recordSet.getRecords()) { + for (String fieldName : fieldMap.keySet()) { + String md = null; + if (fieldMap != null) { + md = fieldMap.get(fieldName); + } + + if (StringUtils.isBlank(md)) { + continue; + } else { + md = md.trim(); + } + + if (publication.isMutable()) { + List values = publication.getValues(md); + publication.makeMutable().removeField(md); + publication.makeMutable().addField(fieldName, values); + } + } + + result.addRecord(publication); + } + return result; + } +} diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/submit/step/validation/LicenseValidation.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/submit/step/validation/LicenseValidation.java new file mode 100644 index 0000000000..1ce6cb35de --- /dev/null +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/submit/step/validation/LicenseValidation.java @@ -0,0 +1,60 @@ +/** + * 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.submit.step.validation; + +import java.sql.SQLException; +import java.util.List; + +import org.apache.log4j.Logger; +import org.dspace.app.rest.model.ErrorRest; +import org.dspace.app.rest.repository.WorkspaceItemRestRepository; +import org.dspace.app.rest.submit.SubmissionService; +import org.dspace.app.util.DCInputsReaderException; +import org.dspace.app.util.SubmissionStepConfig; +import org.dspace.content.Bitstream; +import org.dspace.content.WorkspaceItem; +import org.dspace.content.service.BitstreamService; +import org.dspace.core.Constants; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * Execute check on license bundle + * + * @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it) + */ +public class LicenseValidation extends AbstractValidation { + + private static final String ERROR_VALIDATION_LICENSEREQUIRED = "error.validation.license.notgranted"; + + private static final Logger log = Logger.getLogger(LicenseValidation.class); + + @Autowired + private BitstreamService bitstreamService; + + @Override + public List validate(SubmissionService submissionService, WorkspaceItem obj, + SubmissionStepConfig config) throws DCInputsReaderException, SQLException { + + Bitstream bitstream = bitstreamService + .getBitstreamByName(obj.getItem(), Constants.LICENSE_BUNDLE_NAME, Constants.LICENSE_BITSTREAM_NAME); + if (bitstream == null) { + addError(ERROR_VALIDATION_LICENSEREQUIRED, + "/" + WorkspaceItemRestRepository.OPERATION_PATH_SECTIONS + "/" + config.getId()); + } + return getErrors(); + } + + public BitstreamService getBitstreamService() { + return bitstreamService; + } + + public void setBitstreamService(BitstreamService bitstreamService) { + this.bitstreamService = bitstreamService; + } + +} diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/utils/Utils.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/utils/Utils.java index 8de51855f5..404205956f 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/utils/Utils.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/utils/Utils.java @@ -9,6 +9,13 @@ package org.dspace.app.rest.utils; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; import java.util.List; import org.apache.commons.lang3.StringUtils; @@ -23,6 +30,7 @@ import org.dspace.app.rest.model.RestAddressableModel; import org.dspace.app.rest.model.hateoas.DSpaceResource; import org.dspace.app.rest.repository.DSpaceRestRepository; import org.dspace.app.rest.repository.LinkRestRepository; +import org.dspace.core.ConfigurationManager; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; @@ -31,6 +39,7 @@ import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.hateoas.Link; import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; /** * Collection of utility methods @@ -155,4 +164,23 @@ public class Utils { public String getMetadataKey(String schema, String element, String qualifier) { return org.dspace.core.Utils.standardize(schema, element, qualifier, "."); } + + public static File getFile(MultipartFile multipartFile, String prefixTempName, String suffixTempName) + throws IOException, FileNotFoundException { + // TODO after change item-submission into + String tempDir = (ConfigurationManager.getProperty("upload.temp.dir") != null) + ? ConfigurationManager.getProperty("upload.temp.dir") + : System.getProperty("java.io.tmpdir"); + File uploadDir = new File(tempDir); + if (!uploadDir.exists()) { + if (!uploadDir.mkdir()) { + uploadDir = null; + } + } + File file = File.createTempFile(prefixTempName + "-" + suffixTempName, ".temp", uploadDir); + InputStream io = new BufferedInputStream(multipartFile.getInputStream()); + BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file)); + org.dspace.core.Utils.bufferedCopy(io, out); + return file; + } } diff --git a/dspace/config/spring/api/metadata-extractors.xml b/dspace/config/spring/api/metadata-extractors.xml new file mode 100644 index 0000000000..22f28b1816 --- /dev/null +++ b/dspace/config/spring/api/metadata-extractors.xml @@ -0,0 +1,30 @@ + + + + + + + + + bibtex + bib + + + + + + + diff --git a/dspace/config/spring/api/step-processing-listener.xml b/dspace/config/spring/api/step-processing-listener.xml new file mode 100644 index 0000000000..eb016c5133 --- /dev/null +++ b/dspace/config/spring/api/step-processing-listener.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + +