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); }