diff --git a/dspace/config/item-submission.xml b/dspace/config/item-submission.xml
index 967ec07355ff..031a761a7321 100644
--- a/dspace/config/item-submission.xml
+++ b/dspace/config/item-submission.xml
@@ -322,7 +322,7 @@
-
+
@@ -354,7 +354,7 @@
-
+
@@ -386,7 +386,7 @@
-
+
@@ -418,7 +418,7 @@
-
+
diff --git a/dspace/config/registries/thesis-types.xml b/dspace/config/registries/thesis-types.xml
index 6741f240de95..3ae374546db4 100644
--- a/dspace/config/registries/thesis-types.xml
+++ b/dspace/config/registries/thesis-types.xml
@@ -22,6 +22,13 @@
http://digital.library.tamu.edu/schemas/thesis/
+
+ thesis
+ degree
+ college
+
+
+
thesis
degree
@@ -50,6 +57,13 @@
Level of education associated with the document. Examples: bachelor's, master's, doctoral, post-doctoral, other.
+
+ thesis
+ degree
+ major
+
+
+
thesis
degree
@@ -57,6 +71,20 @@
Name of the degree associated with the work as it appears within the work. (example: Masters in Operations Research)
+
+ thesis
+ degree
+ program
+
+
+
+
+ thesis
+ degree
+ school
+
+
+
thesis
sequence
diff --git a/dspace/modules/additions/src/main/java/org/dspace/discovery/FullTextContentStreams.java b/dspace/modules/additions/src/main/java/org/dspace/discovery/FullTextContentStreams.java
index 8107607be2d2..9260f1c0b450 100644
--- a/dspace/modules/additions/src/main/java/org/dspace/discovery/FullTextContentStreams.java
+++ b/dspace/modules/additions/src/main/java/org/dspace/discovery/FullTextContentStreams.java
@@ -17,6 +17,8 @@
import java.nio.charset.StandardCharsets;
import java.sql.SQLException;
import java.util.ArrayList;
+// TAMU Customization - Only index text bitstreams that are not restricted
+import java.util.Date;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
@@ -26,6 +28,8 @@
import com.google.common.collect.Iterables;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
+// TAMU Customization - Only index text bitstreams that are not restricted
+import org.apache.commons.lang3.time.DateUtils;
import org.apache.logging.log4j.Logger;
import org.apache.solr.common.util.ContentStreamBase;
import org.dspace.authorize.AuthorizeException;
@@ -94,7 +98,13 @@ private void buildFullTextList(Item parentItem) throws SQLException {
for (ResourcePolicy rp:bundlePolicies) {
if (rp.getdSpaceObject().getID() == fulltextBitstream.getID()) {
- if (rp.getGroup().getName().equalsIgnoreCase("anonymous")) {
+ Date start = rp.getStartDate();
+ Date end = rp.getEndDate();
+ Date now = new Date();
+ if (rp.getGroup().getName().equalsIgnoreCase("anonymous")
+ && (start == null || ((start.before(now) || DateUtils.isSameDay(start, now))
+ && (end == null || (end.after(now) || DateUtils.isSameDay(now, end)))))
+ ) {
isIndexable = true;
}
break;
diff --git a/dspace/modules/server/src/main/java/org/dspace/app/rest/repository/WorkspaceItemRestRepository.java b/dspace/modules/server/src/main/java/org/dspace/app/rest/repository/WorkspaceItemRestRepository.java
new file mode 100644
index 000000000000..f03cc6e15539
--- /dev/null
+++ b/dspace/modules/server/src/main/java/org/dspace/app/rest/repository/WorkspaceItemRestRepository.java
@@ -0,0 +1,395 @@
+/**
+ * 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.repository;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.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.DSpaceBadRequestException;
+import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
+import org.dspace.app.rest.exception.UnprocessableEntityException;
+import org.dspace.app.rest.model.ErrorRest;
+import org.dspace.app.rest.model.WorkspaceItemRest;
+import org.dspace.app.rest.model.patch.Operation;
+import org.dspace.app.rest.model.patch.Patch;
+import org.dspace.app.rest.repository.handler.service.UriListHandlerService;
+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.SubmissionConfigReaderException;
+import org.dspace.app.util.SubmissionStepConfig;
+import org.dspace.authorize.AuthorizeException;
+import org.dspace.authorize.service.AuthorizeService;
+import org.dspace.content.Collection;
+import org.dspace.content.Item;
+import org.dspace.content.MetadataValue;
+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.importer.external.datamodel.ImportRecord;
+import org.dspace.importer.external.exception.FileMultipleOccurencesException;
+import org.dspace.importer.external.metadatamapping.MetadatumDTO;
+import org.dspace.importer.external.service.ImportService;
+import org.dspace.services.ConfigurationService;
+import org.dspace.submit.factory.SubmissionServiceFactory;
+import org.dspace.submit.service.SubmissionConfigService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
+
+
+/**
+ * This is the repository responsible to manage WorkspaceItem Rest object
+ *
+ * @author Andrea Bollini (andrea.bollini at 4science.it)
+ * @author Pasquale Cavallo (pasquale.cavallo at 4science.it)
+ */
+@Component(WorkspaceItemRest.CATEGORY + "." + WorkspaceItemRest.NAME)
+public class WorkspaceItemRestRepository extends DSpaceRestRepository
+ implements ReloadableEntityObjectRepository {
+
+ public static final String OPERATION_PATH_SECTIONS = "sections";
+
+ private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(WorkspaceItemRestRepository.class);
+
+ @Autowired
+ WorkspaceItemService wis;
+
+ @Autowired
+ ItemService itemService;
+
+ @Autowired
+ BitstreamService bitstreamService;
+
+ @Autowired
+ BitstreamFormatService bitstreamFormatService;
+
+ @Autowired
+ ConfigurationService configurationService;
+
+ @Autowired
+ WorkspaceItemConverter workspaceItemConverter;
+
+ @Autowired
+ SubmissionService submissionService;
+
+ @Autowired
+ EPersonServiceImpl epersonService;
+
+ @Autowired
+ CollectionService collectionService;
+
+ @Autowired
+ AuthorizeService authorizeService;
+
+ @Autowired
+ ImportService importService;
+
+ @Autowired
+ private UriListHandlerService uriListHandlerService;
+
+ private SubmissionConfigService submissionConfigService;
+
+ public WorkspaceItemRestRepository() throws SubmissionConfigReaderException {
+ submissionConfigService = SubmissionServiceFactory.getInstance().getSubmissionConfigService();
+ }
+
+ @PreAuthorize("hasPermission(#id, 'WORKSPACEITEM', 'READ')")
+ @Override
+ public WorkspaceItemRest findOne(Context context, Integer id) {
+ WorkspaceItem witem = null;
+ try {
+ witem = wis.find(context, id);
+ } catch (SQLException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ if (witem == null) {
+ return null;
+ }
+ return converter.toRest(witem, utils.obtainProjection());
+ }
+
+ @PreAuthorize("hasAuthority('ADMIN')")
+ @Override
+ public Page findAll(Context context, Pageable pageable) {
+ try {
+ long total = wis.countTotal(context);
+ List witems = wis.findAll(context, pageable.getPageSize(),
+ Math.toIntExact(pageable.getOffset()));
+ return converter.toRestPage(witems, pageable, total, utils.obtainProjection());
+ } catch (SQLException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ @PreAuthorize("hasPermission(#submitterID, 'EPERSON', 'READ')")
+ @SearchRestMethod(name = "findBySubmitter")
+ public Page findBySubmitter(@Parameter(value = "uuid", required = true) UUID submitterID,
+ Pageable pageable) {
+ try {
+ Context context = obtainContext();
+ EPerson ep = epersonService.find(context, submitterID);
+ long total = wis.countByEPerson(context, ep);
+ List witems = wis.findByEPerson(context, ep, pageable.getPageSize(),
+ Math.toIntExact(pageable.getOffset()));
+ return converter.toRestPage(witems, pageable, total, utils.obtainProjection());
+ } catch (SQLException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ protected WorkspaceItemRest createAndReturn(Context context) throws SQLException, AuthorizeException {
+ WorkspaceItem source = submissionService.createWorkspaceItem(context, getRequestService().getCurrentRequest());
+ return converter.toRest(source, utils.obtainProjection());
+ }
+
+ @Override
+ public Class getDomainClass() {
+ return WorkspaceItemRest.class;
+ }
+
+ @PreAuthorize("hasPermission(#id, 'WORKSPACEITEM', 'WRITE')")
+ @Override
+ public WorkspaceItemRest upload(HttpServletRequest request, String apiCategory, String model, Integer id,
+ MultipartFile file) throws SQLException {
+
+ Context context = obtainContext();
+ WorkspaceItemRest wsi = findOne(context, id);
+ WorkspaceItem source = wis.find(context, id);
+ List errors = submissionService.uploadFileToInprogressSubmission(context, request, wsi, source,
+ file);
+ wsi = converter.toRest(source, utils.obtainProjection());
+
+ if (!errors.isEmpty()) {
+ wsi.getErrors().addAll(errors);
+ }
+
+ context.commit();
+ return wsi;
+ }
+
+ @PreAuthorize("hasPermission(#id, 'WORKSPACEITEM', 'WRITE')")
+ @Override
+ public void patch(Context context, HttpServletRequest request, String apiCategory, String model, Integer id,
+ Patch patch) throws SQLException, AuthorizeException {
+ List operations = patch.getOperations();
+ WorkspaceItemRest wsi = findOne(context, id);
+ WorkspaceItem source = wis.find(context, id);
+ for (Operation op : operations) {
+ //the value in the position 0 is a null value
+ String[] path = op.getPath().substring(1).split("/", 3);
+ if (OPERATION_PATH_SECTIONS.equals(path[0])) {
+ String section = path[1];
+ submissionService.evaluatePatchToInprogressSubmission(context, request, source, wsi, section, op);
+ } else {
+ throw new DSpaceBadRequestException(
+ "Patch path operation need to starts with '" + OPERATION_PATH_SECTIONS + "'");
+ }
+ }
+ wis.update(context, source);
+ }
+
+ @PreAuthorize("hasPermission(#id, 'WORKSPACEITEM', 'DELETE')")
+ @Override
+ protected void delete(Context context, Integer id) throws AuthorizeException {
+ WorkspaceItem witem = null;
+ try {
+ witem = wis.find(context, id);
+ wis.deleteAll(context, witem);
+ context.addEvent(new Event(Event.DELETE, Constants.ITEM, witem.getItem().getID(), null,
+ itemService.getIdentifiers(context, witem.getItem())));
+ } catch (SQLException | IOException e) {
+ log.error(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public Iterable upload(Context context, HttpServletRequest request,
+ List uploadfiles)
+ throws SQLException, FileNotFoundException, IOException, AuthorizeException {
+ List results = new ArrayList<>();
+
+ String uuid = request.getParameter("owningCollection");
+ 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.findAuthorizedOptimized(context, Constants.ADD).get(0);
+ }
+
+ SubmissionConfig submissionConfig =
+ submissionConfigService.getSubmissionConfigByCollection(collection.getHandle());
+ List result = null;
+ List records = new ArrayList<>();
+ try {
+ for (MultipartFile mpFile : uploadfiles) {
+ File file = Utils.getFile(mpFile, "upload-loader", "filedataloader");
+ try {
+ ImportRecord record = importService.getRecord(file, mpFile.getOriginalFilename());
+ if (record != null) {
+ records.add(record);
+ break;
+ }
+ } catch (Exception e) {
+ log.error("Error processing data", e);
+ throw e;
+ } finally {
+ file.delete();
+ }
+ }
+ } catch (FileMultipleOccurencesException e) {
+ throw new UnprocessableEntityException("Too many entries in file");
+ } catch (Exception e) {
+ log.error("Error importing metadata", e);
+ }
+ WorkspaceItem source = submissionService.
+ createWorkspaceItem(context, getRequestService().getCurrentRequest());
+ merge(context, records, source);
+ result = new ArrayList<>();
+ result.add(source);
+
+ //perform upload of bitstream if there is exact one result and convert workspaceitem to entity rest
+ if (!result.isEmpty()) {
+ for (WorkspaceItem wi : result) {
+ List errors = new ArrayList();
+ wi.setMultipleFiles(uploadfiles.size() > 1);
+ //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();
+ // TAMU Customization - proxy license step - respect exclusivity of uploadable step
+ if (UploadableStep.class.isAssignableFrom(stepClass)
+ && !((UploadableStep) stepInstance).isExclusiveMatchingStepId()) {
+ // if (UploadableStep.class.isAssignableFrom(stepClass)) {
+ UploadableStep uploadableStep = (UploadableStep) stepInstance;
+ for (MultipartFile mpFile : uploadfiles) {
+ ErrorRest err = uploadableStep.upload(context,
+ submissionService, stepConfig, wi, mpFile);
+ if (err != null) {
+ errors.add(err);
+ }
+ }
+ }
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ }
+ }
+ WorkspaceItemRest wsi = converter.toRest(wi, utils.obtainProjection());
+ if (result.size() == 1) {
+ if (!errors.isEmpty()) {
+ wsi.getErrors().addAll(errors);
+ }
+ }
+ results.add(wsi);
+ }
+ }
+ return results;
+ }
+
+ @Override
+ protected WorkspaceItemRest createAndReturn(Context context, List stringList)
+ throws AuthorizeException, SQLException, RepositoryMethodNotImplementedException {
+
+ HttpServletRequest req = getRequestService().getCurrentRequest().getHttpServletRequest();
+ WorkspaceItem workspaceItem = uriListHandlerService.handle(context, req, stringList, WorkspaceItem.class);
+ return converter.toRest(workspaceItem, utils.obtainProjection());
+ }
+
+ /**
+ * This is a search method that will return the WorkspaceItemRest object found through the UUID of an item. It'll
+ * find the Item through the given UUID and try to resolve the WorkspaceItem relevant for that item and return it.
+ * It'll return a 401/403 if the current user isn't allowed to view the WorkspaceItem.
+ * It'll return a 204 if nothing was found
+ * @param itemUuid The UUID for the Item to be used
+ * @param pageable The pageable if present
+ * @return The resulting WorkspaceItem object
+ */
+ @SearchRestMethod(name = "item")
+ public WorkspaceItemRest findByItemUuid(@Parameter(value = "uuid", required = true) UUID itemUuid,
+ Pageable pageable) {
+ try {
+ Context context = obtainContext();
+ Item item = itemService.find(context, itemUuid);
+ WorkspaceItem workspaceItem = wis.findByItem(context, item);
+ if (workspaceItem == null) {
+ return null;
+ }
+ if (!authorizeService.authorizeActionBoolean(context, workspaceItem.getItem(), Constants.READ)) {
+ throw new AccessDeniedException("The current user does not have rights to view the WorkflowItem");
+ }
+ return converter.toRest(workspaceItem, utils.obtainProjection());
+ } catch (SQLException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public WorkspaceItem findDomainObjectByPk(Context context, Integer id) throws SQLException {
+ return wis.find(context, id);
+ }
+
+ @Override
+ public Class getPKClass() {
+ return Integer.class;
+ }
+
+ private void merge(Context context, List records, WorkspaceItem item) throws SQLException {
+ for (MetadataValue metadataValue : itemService.getMetadata(
+ item.getItem(), Item.ANY, Item.ANY, Item.ANY, Item.ANY)) {
+ itemService.clearMetadata(context, item.getItem(),
+ metadataValue.getMetadataField().getMetadataSchema().getNamespace(),
+ metadataValue.getMetadataField().getElement(),
+ metadataValue.getMetadataField().getQualifier(),
+ metadataValue.getLanguage());
+ }
+ for (ImportRecord record : records) {
+ if (record != null && record.getValueList() != null) {
+ for (MetadatumDTO metadataValue : record.getValueList()) {
+ itemService.addMetadata(context, item.getItem(), metadataValue.getSchema(),
+ metadataValue.getElement(), metadataValue.getQualifier(), null,
+ metadataValue.getValue());
+ }
+ }
+ }
+ }
+}
diff --git a/dspace/modules/server/src/main/java/org/dspace/app/rest/submit/factory/impl/LicenseAddPatchOperation.java b/dspace/modules/server/src/main/java/org/dspace/app/rest/submit/factory/impl/LicenseAddPatchOperation.java
index 74834e5d6d59..3c716e05bea1 100644
--- a/dspace/modules/server/src/main/java/org/dspace/app/rest/submit/factory/impl/LicenseAddPatchOperation.java
+++ b/dspace/modules/server/src/main/java/org/dspace/app/rest/submit/factory/impl/LicenseAddPatchOperation.java
@@ -10,9 +10,9 @@
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.BooleanUtils;
+import org.dspace.app.rest.utils.ProxyLicenseUtils;
import org.dspace.content.InProgressSubmission;
import org.dspace.content.Item;
-import org.dspace.content.ProxyLicenseUtils;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/dspace/modules/server/src/main/java/org/dspace/app/rest/submit/factory/impl/LicenseRemovePatchOperation.java b/dspace/modules/server/src/main/java/org/dspace/app/rest/submit/factory/impl/LicenseRemovePatchOperation.java
index e7f7c4049d38..2130364e1580 100644
--- a/dspace/modules/server/src/main/java/org/dspace/app/rest/submit/factory/impl/LicenseRemovePatchOperation.java
+++ b/dspace/modules/server/src/main/java/org/dspace/app/rest/submit/factory/impl/LicenseRemovePatchOperation.java
@@ -9,9 +9,9 @@
import javax.servlet.http.HttpServletRequest;
+import org.dspace.app.rest.utils.ProxyLicenseUtils;
import org.dspace.content.InProgressSubmission;
import org.dspace.content.Item;
-import org.dspace.content.ProxyLicenseUtils;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/dspace/modules/server/src/main/java/org/dspace/app/rest/submit/factory/impl/LicenseSelectedAddPatchOperation.java b/dspace/modules/server/src/main/java/org/dspace/app/rest/submit/factory/impl/LicenseSelectedAddPatchOperation.java
index 69bb3a067145..afd7d893f9ab 100644
--- a/dspace/modules/server/src/main/java/org/dspace/app/rest/submit/factory/impl/LicenseSelectedAddPatchOperation.java
+++ b/dspace/modules/server/src/main/java/org/dspace/app/rest/submit/factory/impl/LicenseSelectedAddPatchOperation.java
@@ -8,19 +8,15 @@
package org.dspace.app.rest.submit.factory.impl;
import java.io.File;
-import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
-import org.dspace.content.Bitstream;
-import org.dspace.content.Bundle;
+import org.dspace.app.rest.utils.ProxyLicenseUtils;
import org.dspace.content.InProgressSubmission;
import org.dspace.content.Item;
import org.dspace.content.LicenseUtils;
-import org.dspace.content.ProxyLicenseUtils;
import org.dspace.content.service.BundleService;
import org.dspace.content.service.ItemService;
-import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.core.service.LicenseService;
import org.dspace.eperson.EPerson;
@@ -109,21 +105,6 @@ void add(Context context, HttpServletRequest currentRequest, InProgressSubmissio
: licenseService.getLicenseText(licensePath);
if (StringUtils.isNotBlank(licenseText)) {
- if (selected.equalsIgnoreCase("proxy")) {
- List licenseBundles = itemService.getBundles(item, Constants.LICENSE_BUNDLE_NAME);
- if (licenseBundles.size() > 0) {
- Bundle licenseBundle = licenseBundles.get(0);
- for (Bitstream bitstream: licenseBundle.getBitstreams()) {
- if (Constants.LICENSE_BITSTREAM_NAME.equals(bitstream.getName())) {
- bundleService.removeBitstream(context, licenseBundle, bitstream);
- break;
- }
- }
- }
- } else {
- itemService.removeDSpaceLicense(context, item);
- }
-
ProxyLicenseUtils.addLicense(context, item, selected, licenseText);
} else {
throw new RuntimeException(String.format("Unable to find license file at %s", licenseFilename));
diff --git a/dspace/modules/server/src/main/java/org/dspace/app/rest/submit/step/ProxyLicenseStep.java b/dspace/modules/server/src/main/java/org/dspace/app/rest/submit/step/ProxyLicenseStep.java
index ef16d534d886..107cd90bd0d9 100644
--- a/dspace/modules/server/src/main/java/org/dspace/app/rest/submit/step/ProxyLicenseStep.java
+++ b/dspace/modules/server/src/main/java/org/dspace/app/rest/submit/step/ProxyLicenseStep.java
@@ -1,7 +1,5 @@
package org.dspace.app.rest.submit.step;
-import java.io.BufferedInputStream;
-import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
@@ -19,10 +17,9 @@
import org.dspace.app.rest.submit.UploadableStep;
import org.dspace.app.rest.submit.factory.PatchOperationFactory;
import org.dspace.app.rest.submit.factory.impl.PatchOperation;
-import org.dspace.app.rest.utils.Utils;
+import org.dspace.app.rest.utils.ProxyLicenseUtils;
import org.dspace.app.util.SubmissionStepConfig;
import org.dspace.content.Bitstream;
-import org.dspace.content.BitstreamFormat;
import org.dspace.content.Bundle;
import org.dspace.content.InProgressSubmission;
import org.dspace.content.Item;
@@ -36,8 +33,6 @@ public class ProxyLicenseStep extends LicenseStep implements UploadableStep {
private static final String LICENSE_STEP_SELECTED_OPERATION_ENTRY = "selected";
- private static final String PROXY_LICENSE_NAME = "PERMISSION";
-
private static final String DCTERMS_RIGHTSDATE = "dcterms.accessRights";
private static final String DCTERMS_ALTERNATIVE = "dcterms.alternative";
@@ -53,16 +48,16 @@ public DataLicense getData(SubmissionService submissionService, InProgressSubmis
DataLicense result = new DataLicense();
- List bundles = itemService.getBundles(obj.getItem(), Constants.LICENSE_BUNDLE_NAME);
-
Bitstream licenseBitstream = null;
Bitstream proxyBitstream = null;
- for (Bundle bundle : bundles) {
- for (Bitstream bitstream : bundle.getBitstreams()) {
+ List licenseBundles = itemService.getBundles(obj.getItem(), Constants.LICENSE_BUNDLE_NAME);
+
+ if (licenseBundles.size() > 0) {
+ for (Bitstream bitstream : licenseBundles.get(0).getBitstreams()) {
if (bitstream.getName().equals(Constants.LICENSE_BITSTREAM_NAME)) {
licenseBitstream = bitstream;
- } else if (bitstream.getName().startsWith(PROXY_LICENSE_NAME)) {
+ } else if (bitstream.getName().startsWith(ProxyLicenseUtils.PROXY_LICENSE_NAME)) {
proxyBitstream = bitstream;
}
}
@@ -116,57 +111,14 @@ public ErrorRest upload(Context context, SubmissionService submissionService, Su
InProgressSubmission wsi, MultipartFile file) {
Item item = wsi.getItem();
- List licenseBundles = null;
- Bundle licenseBundle = null;
- Bitstream proxyBitstream = null;
-
- try (InputStream in = new BufferedInputStream(file.getInputStream())) {
-
- licenseBundles = itemService.getBundles(item, Constants.LICENSE_BUNDLE_NAME);
-
- if (licenseBundles.size() > 0) {
- licenseBundle = licenseBundles.get(0);
- for (Bitstream bitstream: licenseBundle.getBitstreams()) {
- if (bitstream.getName().startsWith(PROXY_LICENSE_NAME)) {
- bundleService.removeBitstream(context, licenseBundle, bitstream);
- break;
- }
- }
- } else {
- licenseBundle = bundleService.create(context, item, Constants.LICENSE_BUNDLE_NAME);
- }
-
- proxyBitstream = bitstreamService.create(context, licenseBundle, in);
-
- String filename = Utils.getFileName(file);
- String[] parts = filename.split("\\.");
- String permissionLicenseName = parts.length == 1
- ? String.join(".", PROXY_LICENSE_NAME, "license")
- : String.join(".", PROXY_LICENSE_NAME, parts[parts.length - 1]);
-
- proxyBitstream.setName(context, permissionLicenseName);
-
- proxyBitstream.setSource(context, file.getOriginalFilename());
- proxyBitstream.setDescription(context, "Proxy license");
-
- BitstreamFormat bf = bitstreamFormatService.guessFormat(context, proxyBitstream);
-
- proxyBitstream.setFormat(context, bf);
-
- bitstreamService.update(context, proxyBitstream);
-
+ try {
+ ProxyLicenseUtils.addProxyLicense(context, item, file);
} catch (Exception e) {
log.error(e.getMessage(), e);
ErrorRest result = new ErrorRest();
result.setMessage(e.getMessage());
- if (licenseBundles != null && licenseBundles.size() > 0) {
- result.getPaths().add(
- "/" + WorkspaceItemRestRepository.OPERATION_PATH_SECTIONS + "/" + stepConfig.getId() + "/files/" +
- licenseBundles.get(0).getBitstreams().size());
- } else {
- result.getPaths()
- .add("/" + WorkspaceItemRestRepository.OPERATION_PATH_SECTIONS + "/" + stepConfig.getId());
- }
+ result.getPaths()
+ .add("/" + WorkspaceItemRestRepository.OPERATION_PATH_SECTIONS + "/" + stepConfig.getId());
return result;
}
diff --git a/dspace/modules/additions/src/main/java/org/dspace/content/ProxyLicenseUtils.java b/dspace/modules/server/src/main/java/org/dspace/app/rest/utils/ProxyLicenseUtils.java
similarity index 59%
rename from dspace/modules/additions/src/main/java/org/dspace/content/ProxyLicenseUtils.java
rename to dspace/modules/server/src/main/java/org/dspace/app/rest/utils/ProxyLicenseUtils.java
index a39952683b94..7429c6f896d3 100644
--- a/dspace/modules/additions/src/main/java/org/dspace/content/ProxyLicenseUtils.java
+++ b/dspace/modules/server/src/main/java/org/dspace/app/rest/utils/ProxyLicenseUtils.java
@@ -5,14 +5,21 @@
*
* http://www.dspace.org/license/
*/
-package org.dspace.content;
+package org.dspace.app.rest.utils;
+import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.sql.SQLException;
import java.util.List;
import org.dspace.authorize.AuthorizeException;
+import org.dspace.content.Bitstream;
+import org.dspace.content.BitstreamFormat;
+import org.dspace.content.Bundle;
+import org.dspace.content.DCDate;
+import org.dspace.content.Item;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.BitstreamFormatService;
import org.dspace.content.service.BitstreamService;
@@ -20,6 +27,7 @@
import org.dspace.content.service.ItemService;
import org.dspace.core.Constants;
import org.dspace.core.Context;
+import org.springframework.web.multipart.MultipartFile;
/**
* TAMU Customization - Proxy license utilility for decoupling license selection from accepting licence
@@ -31,23 +39,72 @@ public class ProxyLicenseUtils {
private static final BundleService bundleService = ContentServiceFactory.getInstance().getBundleService();
private static final ItemService itemService = ContentServiceFactory.getInstance().getItemService();
+ public static final String PROXY_LICENSE_NAME = "PERMISSION";
+
/**
* Default constructor
*/
private ProxyLicenseUtils() { }
+ /**
+ * Store a copy of the proxy license as the user uploaded for the item.
+ *
+ * @param context the dspace context
+ * @param item the item object of the license
+ * @param file the multipart file upload
+ * @throws SQLException if database error
+ * @throws IOException if IO error
+ * @throws AuthorizeException if authorization error
+ */
+ public static void addProxyLicense(Context context, Item item, MultipartFile file)
+ throws SQLException, IOException, AuthorizeException {
+
+ InputStream is = new BufferedInputStream(file.getInputStream());
+
+ List licenseBundles = itemService.getBundles(item, Constants.LICENSE_BUNDLE_NAME);
+ Bundle licenseBundle = licenseBundles.size() > 0
+ ? licenseBundles.get(0)
+ : bundleService.create(context, item, Constants.LICENSE_BUNDLE_NAME);
+
+ // remove existing proxy license bitstream
+ for (Bitstream bitstream: licenseBundle.getBitstreams()) {
+ if (bitstream.getName().startsWith(PROXY_LICENSE_NAME)) {
+ bundleService.removeBitstream(context, licenseBundle, bitstream);
+ }
+ }
+
+ Bitstream bitstream = bitstreamService.create(context, licenseBundle, is);
+
+ String filename = Utils.getFileName(file);
+ String[] parts = filename.split("\\.");
+ String proxyLicenseName = parts.length == 1
+ ? String.join(".", PROXY_LICENSE_NAME, "license")
+ : String.join(".", PROXY_LICENSE_NAME, parts[parts.length - 1]);
+
+ bitstream.setName(context, proxyLicenseName);
+
+ bitstream.setSource(context, file.getOriginalFilename());
+ bitstream.setDescription(context, "Proxy license");
+
+ BitstreamFormat bf = bitstreamFormatService.guessFormat(context, bitstream);
+
+ bitstream.setFormat(context, bf);
+
+ bitstreamService.update(context, bitstream);
+ }
+
/**
* Store a copy of the license as the user selected for the item.
*
* @param context the dspace context
* @param item the item object of the license
- * @param selection the license the user selected
+ * @param selected the license the user selected
* @param licenseText the license text
* @throws SQLException if database error
* @throws IOException if IO error
* @throws AuthorizeException if authorization error
*/
- public static void addLicense(Context context, Item item, String selection, String licenseText)
+ public static void addLicense(Context context, Item item, String selected, String licenseText)
throws SQLException, IOException, AuthorizeException {
// Store text as a bitstream
@@ -59,6 +116,22 @@ public static void addLicense(Context context, Item item, String selection, Stri
? licenseBundles.get(0)
: bundleService.create(context, item, Constants.LICENSE_BUNDLE_NAME);
+ // remove existing license bitstream
+ for (Bitstream bitstream: licenseBundle.getBitstreams()) {
+ if (Constants.LICENSE_BITSTREAM_NAME.equals(bitstream.getName())) {
+ bundleService.removeBitstream(context, licenseBundle, bitstream);
+ }
+ }
+
+ // if proxy license not selected, remove proxy license
+ if (!selected.equalsIgnoreCase("proxy")) {
+ for (Bitstream bitstream: licenseBundle.getBitstreams()) {
+ if (bitstream.getName().startsWith(PROXY_LICENSE_NAME)) {
+ bundleService.removeBitstream(context, licenseBundle, bitstream);
+ }
+ }
+ }
+
Bitstream bitstream = bitstreamService.create(context, licenseBundle, is);
// Now set the format and name of the bitstream
@@ -68,10 +141,10 @@ public static void addLicense(Context context, Item item, String selection, Stri
// Find the License format
BitstreamFormat bf = bitstreamFormatService.findByShortDescription(context,
"License");
- bitstream.setFormat(bf);
+ bitstream.setFormat(context, bf);
bitstreamService
- .setMetadataSingleValue(context, bitstream, "dcterms", "alternative", null, null, selection);
+ .setMetadataSingleValue(context, bitstream, "dcterms", "alternative", null, null, selected);
bitstreamService.update(context, bitstream);
}