From 6f5f4da745e9f0655c445c1a3fea0251033ebe15 Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Mon, 21 Oct 2019 15:29:11 -0400 Subject: [PATCH 01/20] DS-3533 Add projections --- .../rest/AuthenticationRestController.java | 15 +- .../CollectionHarvestSettingsController.java | 11 +- .../app/rest/DiscoveryRestController.java | 15 +- .../app/rest/HarvesterMetadataController.java | 8 +- .../app/rest/IdentifierRestController.java | 6 +- ...mOwningCollectionUpdateRestController.java | 6 +- .../dspace/app/rest/ItemUploadController.java | 6 +- .../rest/MappedCollectionRestController.java | 13 +- .../app/rest/MappedItemRestController.java | 6 +- .../rest/RelationshipTypeRestController.java | 11 +- .../app/rest/RestResourceController.java | 129 ++++----- .../app/rest/RootRestResourceController.java | 12 +- .../app/rest/StatisticsRestController.java | 14 +- .../app/rest/UUIDLookupRestController.java | 7 +- .../converter/AInprogressItemConverter.java | 27 +- .../AuthorityEntryRestConverter.java | 7 +- .../converter/AuthorityRestConverter.java | 7 +- .../rest/converter/BitstreamConverter.java | 26 +- .../converter/BitstreamFormatConverter.java | 7 +- .../rest/converter/BrowseIndexConverter.java | 7 +- .../rest/converter/ClaimedTaskConverter.java | 17 +- .../rest/converter/CollectionConverter.java | 19 +- .../rest/converter/CommunityConverter.java | 27 +- .../app/rest/converter/ConverterService.java | 189 +++++++++++++ .../app/rest/converter/DSpaceConverter.java | 9 +- .../rest/converter/DSpaceObjectConverter.java | 18 +- .../app/rest/converter/EPersonConverter.java | 24 +- .../rest/converter/EntityTypeConverter.java | 17 +- .../GenericDSpaceObjectConverter.java | 61 ----- .../app/rest/converter/GroupConverter.java | 12 +- .../HarvestedCollectionConverter.java | 15 +- .../converter/IndexableObjectConverter.java | 5 +- .../app/rest/converter/ItemConverter.java | 56 ++-- .../app/rest/converter/MetadataConverter.java | 4 +- .../converter/MetadataFieldConverter.java | 16 +- .../converter/MetadataSchemaConverter.java | 10 +- .../converter/MetadataValueConverter.java | 8 +- .../app/rest/converter/PoolTaskConverter.java | 22 +- .../rest/converter/RelationshipConverter.java | 19 +- .../converter/RelationshipTypeConverter.java | 20 +- .../converter/ResourcePolicyConverter.java | 7 +- .../app/rest/converter/SiteConverter.java | 10 +- .../SubmissionDefinitionConverter.java | 15 +- .../converter/SubmissionFormConverter.java | 7 +- .../converter/SubmissionSectionConverter.java | 10 +- .../rest/converter/WorkflowItemConverter.java | 6 +- .../converter/WorkspaceItemConverter.java | 8 +- .../link/DSpaceResourceHalLinkFactory.java | 9 +- .../rest/model/AuthenticationStatusRest.java | 4 +- .../app/rest/model/AuthorityEntryRest.java | 2 +- .../dspace/app/rest/model/AuthorityRest.java | 15 +- .../dspace/app/rest/model/BaseObjectRest.java | 2 +- .../app/rest/model/BrowseIndexRest.java | 16 +- .../dspace/app/rest/model/CollectionRest.java | 9 +- .../rest/model/HarvestedCollectionRest.java | 2 +- .../org/dspace/app/rest/model/LinkRest.java | 4 +- .../org/dspace/app/rest/model/LinksRest.java | 2 +- .../model/MappedCollectionRestWrapper.java | 2 +- .../app/rest/model/MappedItemRestWrapper.java | 2 +- .../model/RelationshipTypeRestWrapper.java | 2 +- .../app/rest/model/RestAddressableModel.java | 18 +- .../org/dspace/app/rest/model/RootRest.java | 2 +- .../app/rest/model/SearchFacetEntryRest.java | 2 +- .../app/rest/model/SearchFacetValueRest.java | 2 +- .../app/rest/model/SearchResultEntryRest.java | 2 +- .../hateoas/AuthenticationStatusResource.java | 4 +- .../app/rest/model/hateoas/AuthnResource.java | 6 +- .../rest/model/hateoas/AuthorityResource.java | 4 +- .../hateoas/BitstreamFormatResource.java | 4 +- .../rest/model/hateoas/BitstreamResource.java | 4 +- .../model/hateoas/BrowseIndexResource.java | 4 +- .../model/hateoas/ClaimedTaskResource.java | 4 +- .../model/hateoas/CollectionResource.java | 4 +- .../rest/model/hateoas/CommunityResource.java | 6 +- .../rest/model/hateoas/DSpaceResource.java | 183 +------------ .../rest/model/hateoas/EPersonResource.java | 4 +- .../model/hateoas/EntityTypeResource.java | 4 +- .../app/rest/model/hateoas/GroupResource.java | 4 +- .../app/rest/model/hateoas/HALResource.java | 20 +- .../hateoas/HarvestedCollectionResource.java | 7 +- .../hateoas/HarvesterMetadataResource.java | 6 +- .../app/rest/model/hateoas/ItemResource.java | 4 +- .../MappedCollectionResourceWrapper.java | 19 +- .../hateoas/MappedItemResourceWrapper.java | 2 +- .../model/hateoas/MetadataFieldResource.java | 6 +- .../model/hateoas/MetadataSchemaResource.java | 6 +- .../rest/model/hateoas/PoolTaskResource.java | 4 +- .../model/hateoas/RelationshipResource.java | 4 +- .../hateoas/RelationshipTypeResource.java | 4 +- .../RelationshipTypeResourceWrapper.java | 1 - .../model/hateoas/ResourcePolicyResource.java | 4 +- .../model/hateoas/SearchEventResource.java | 4 +- .../hateoas/SearchResultEntryResource.java | 5 +- .../app/rest/model/hateoas/SiteResource.java | 6 +- .../hateoas/SubmissionDefinitionResource.java | 6 +- .../model/hateoas/SubmissionFormResource.java | 6 +- .../hateoas/SubmissionSectionResource.java | 6 +- .../hateoas/SubmissionUploadResource.java | 6 +- .../rest/model/hateoas/ViewEventResource.java | 4 +- .../model/hateoas/WorkflowItemResource.java | 4 +- .../model/hateoas/WorkspaceItemResource.java | 4 +- .../rest/projection/AbstractProjection.java | 40 +++ .../rest/projection/DefaultProjection.java | 18 ++ .../app/rest/projection/ListProjection.java | 28 ++ .../app/rest/projection/Projection.java | 59 ++++ .../AuthorityEntryLinkRepository.java | 9 +- .../AuthorityEntryValueLinkRepository.java | 9 +- .../repository/AuthorityRestRepository.java | 7 - .../BitstreamFormatRestRepository.java | 20 +- .../repository/BitstreamRestRepository.java | 16 +- .../repository/BrowseEntryLinkRepository.java | 31 +-- .../repository/BrowseIndexRestRepository.java | 18 +- .../repository/BrowseItemLinkRepository.java | 12 +- .../repository/ClaimedTaskRestRepository.java | 17 +- .../repository/CollectionRestRepository.java | 36 +-- .../repository/CommunityRestRepository.java | 37 +-- .../DSpaceObjectRestRepository.java | 10 +- .../rest/repository/DSpaceRestRepository.java | 19 +- .../repository/EPersonRestRepository.java | 27 +- .../repository/EntityTypeRestRepository.java | 14 +- .../rest/repository/GroupRestRepository.java | 20 +- .../HarvestedCollectionRestRepository.java | 2 +- .../rest/repository/ItemRestRepository.java | 23 +- .../repository/LicenseRestLinkRepository.java | 12 +- .../rest/repository/LinkRestRepository.java | 10 +- .../MetadataFieldRestRepository.java | 20 +- .../MetadataSchemaRestRepository.java | 18 +- .../repository/PoolTaskRestRepository.java | 17 +- .../RelationshipRestRepository.java | 34 +-- .../RelationshipTypeRestRepository.java | 17 +- .../ResourcePolicyRestRepository.java | 14 +- .../rest/repository/SiteRestRepository.java | 19 +- .../SubmissionDefinitionRestRepository.java | 23 +- .../SubmissionFormRestRepository.java | 18 +- .../SubmissionPanelRestRepository.java | 18 +- .../SubmissionUploadRestRepository.java | 8 +- .../WorkflowItemRestRepository.java | 23 +- .../WorkspaceItemRestRepository.java | 26 +- .../app/rest/submit/SubmissionService.java | 18 +- .../dspace/app/rest/utils/AuthorityUtils.java | 14 +- .../java/org/dspace/app/rest/utils/Utils.java | 251 ++++++++++++++++-- .../rest/BitstreamFormatRestRepositoryIT.java | 22 +- .../app/rest/CollectionRestRepositoryIT.java | 8 +- .../app/rest/CommunityRestRepositoryIT.java | 9 +- .../rest/MetadataSchemaRestRepositoryIT.java | 6 +- 145 files changed, 1225 insertions(+), 1293 deletions(-) create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java delete mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/GenericDSpaceObjectConverter.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/AbstractProjection.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/DefaultProjection.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/ListProjection.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/Projection.java diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/AuthenticationRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/AuthenticationRestController.java index 281494c081..f123b17656 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/AuthenticationRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/AuthenticationRestController.java @@ -11,6 +11,7 @@ import java.sql.SQLException; import java.util.Arrays; import javax.servlet.http.HttpServletRequest; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.converter.EPersonConverter; import org.dspace.app.rest.link.HalLinkService; import org.dspace.app.rest.model.AuthenticationStatusRest; @@ -49,6 +50,9 @@ public class AuthenticationRestController implements InitializingBean { @Autowired DiscoverableEndpointsService discoverableEndpointsService; + @Autowired + private ConverterService converter; + @Autowired private EPersonConverter ePersonConverter; @@ -65,9 +69,8 @@ public class AuthenticationRestController implements InitializingBean { } @RequestMapping(method = RequestMethod.GET) - public AuthnResource authn() throws SQLException { - AuthnResource authnResource = new AuthnResource(new AuthnRest(), utils); - halLinkService.addLinks(authnResource); + public AuthnResource authn() { + AuthnResource authnResource = converter.toResource(new AuthnRest()); return authnResource; } @@ -79,10 +82,8 @@ public class AuthenticationRestController implements InitializingBean { ePersonRest = ePersonConverter.fromModelWithGroups(context, context.getCurrentUser()); } - AuthenticationStatusResource authenticationStatusResource = new AuthenticationStatusResource( - new AuthenticationStatusRest(ePersonRest), utils); - - halLinkService.addLinks(authenticationStatusResource); + AuthenticationStatusResource authenticationStatusResource = converter.toResource( + new AuthenticationStatusRest(ePersonRest)); return authenticationStatusResource; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/CollectionHarvestSettingsController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/CollectionHarvestSettingsController.java index 274c393d9b..856804808c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/CollectionHarvestSettingsController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/CollectionHarvestSettingsController.java @@ -12,6 +12,7 @@ import java.util.UUID; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.converter.HarvestedCollectionConverter; import org.dspace.app.rest.link.HalLinkService; import org.dspace.app.rest.model.HarvestedCollectionRest; @@ -48,6 +49,9 @@ public class CollectionHarvestSettingsController { @Autowired CollectionService collectionService; + @Autowired + ConverterService converter; + @Autowired HarvestedCollectionService harvestedCollectionService; @@ -80,9 +84,7 @@ public class CollectionHarvestSettingsController { } HarvestedCollectionRest harvestedCollectionRest = harvestedCollectionRestRepository.findOne(collection); - HarvestedCollectionResource resource = new HarvestedCollectionResource(harvestedCollectionRest); - - halLinkService.addLinks(resource); + HarvestedCollectionResource resource = converter.toResource(harvestedCollectionRest); return resource; } @@ -114,8 +116,7 @@ public class CollectionHarvestSettingsController { // Return a harvestedCollectionResource only if a new harvestedCollection was created if (harvestedCollectionRest != null) { - harvestedCollectionResource = new HarvestedCollectionResource(harvestedCollectionRest); - halLinkService.addLinks(harvestedCollectionResource); + harvestedCollectionResource = converter.toResource(harvestedCollectionRest); } context.commit(); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/DiscoveryRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/DiscoveryRestController.java index 6b37d40fa7..1e3aaacac1 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/DiscoveryRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/DiscoveryRestController.java @@ -14,6 +14,7 @@ import java.util.Objects; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.link.HalLinkService; import org.dspace.app.rest.model.FacetConfigurationRest; import org.dspace.app.rest.model.FacetResultsRest; @@ -61,6 +62,9 @@ public class DiscoveryRestController implements InitializingBean { @Autowired private HalLinkService halLinkService; + @Autowired + private ConverterService converter; + @Override public void afterPropertiesSet() throws Exception { discoverableEndpointsService @@ -74,8 +78,7 @@ public class DiscoveryRestController implements InitializingBean { throws Exception { SearchSupportRest searchSupportRest = discoveryRestRepository.getSearchSupport(); - SearchSupportResource searchSupportResource = new SearchSupportResource(searchSupportRest); - halLinkService.addLinks(searchSupportResource); + SearchSupportResource searchSupportResource = converter.toResource(searchSupportRest); return searchSupportResource; } @@ -91,9 +94,7 @@ public class DiscoveryRestController implements InitializingBean { SearchConfigurationRest searchConfigurationRest = discoveryRestRepository .getSearchConfiguration(dsoScope, configuration); - SearchConfigurationResource searchConfigurationResource = new SearchConfigurationResource( - searchConfigurationRest); - halLinkService.addLinks(searchConfigurationResource); + SearchConfigurationResource searchConfigurationResource = converter.toResource(searchConfigurationRest); return searchConfigurationResource; } @@ -164,7 +165,7 @@ public class DiscoveryRestController implements InitializingBean { FacetConfigurationRest facetConfigurationRest = discoveryRestRepository .getFacetsConfiguration(dsoScope, configuration); - FacetConfigurationResource facetConfigurationResource = new FacetConfigurationResource(facetConfigurationRest); + FacetConfigurationResource facetConfigurationResource = converter.toResource(facetConfigurationRest); halLinkService.addLinks(facetConfigurationResource, pageable); return facetConfigurationResource; @@ -192,7 +193,7 @@ public class DiscoveryRestController implements InitializingBean { FacetResultsRest facetResultsRest = discoveryRestRepository .getFacetObjects(facetName, prefix, query, dsoType, dsoScope, configuration, searchFilters, page); - FacetResultsResource facetResultsResource = new FacetResultsResource(facetResultsRest); + FacetResultsResource facetResultsResource = converter.toResource(facetResultsRest); halLinkService.addLinks(facetResultsResource, page); return facetResultsResource; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/HarvesterMetadataController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/HarvesterMetadataController.java index 121f886fff..de23aac866 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/HarvesterMetadataController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/HarvesterMetadataController.java @@ -12,6 +12,7 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.link.HalLinkService; import org.dspace.app.rest.model.HarvesterMetadataRest; import org.dspace.app.rest.model.hateoas.HarvesterMetadataResource; @@ -38,6 +39,9 @@ public class HarvesterMetadataController { @Autowired private HalLinkService halLinkService; + @Autowired + private ConverterService converter; + /** * GET endpoint that returns all available metadata formats * @param request The request object @@ -52,9 +56,7 @@ public class HarvesterMetadataController { HarvesterMetadataRest data = new HarvesterMetadataRest(); data.setConfigs(configs); - HarvesterMetadataResource resource = new HarvesterMetadataResource(data, utils); - halLinkService.addLinks(resource); - + HarvesterMetadataResource resource = converter.toResource(data); return resource; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/IdentifierRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/IdentifierRestController.java index 3c7570fac7..bb84a0c9e1 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/IdentifierRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/IdentifierRestController.java @@ -19,7 +19,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.atteo.evo.inflector.English; -import org.dspace.app.rest.converter.GenericDSpaceObjectConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.DSpaceObjectRest; import org.dspace.app.rest.utils.ContextUtil; import org.dspace.content.DSpaceObject; @@ -53,7 +53,7 @@ public class IdentifierRestController implements InitializingBean { Logger.getLogger(IdentifierRestController.class); @Autowired - private GenericDSpaceObjectConverter converter; + private ConverterService converter; @Autowired private DiscoverableEndpointsService discoverableEndpointsService; @@ -84,7 +84,7 @@ public class IdentifierRestController implements InitializingBean { try { dso = identifierService.resolve(context, id); if (dso != null) { - DSpaceObjectRest dsor = converter.convert(dso); + DSpaceObjectRest dsor = converter.toRest(dso); URI link = linkTo(dsor.getController(), dsor.getCategory(), English.plural(dsor.getType())) .slash(dsor.getId()).toUri(); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemOwningCollectionUpdateRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemOwningCollectionUpdateRestController.java index c5ccca34f0..3ba8fa4b06 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemOwningCollectionUpdateRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemOwningCollectionUpdateRestController.java @@ -16,7 +16,7 @@ import java.util.UUID; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.dspace.app.rest.converter.CollectionConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.CollectionRest; @@ -60,7 +60,7 @@ public class ItemOwningCollectionUpdateRestController { AuthorizeService authorizeService; @Autowired - CollectionConverter converter; + ConverterService converter; @Autowired Utils utils; @@ -97,7 +97,7 @@ public class ItemOwningCollectionUpdateRestController { if (targetCollection == null) { return null; } - return converter.fromModel(targetCollection); + return converter.toRest(targetCollection); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemUploadController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemUploadController.java index f119e8e102..8c290058c8 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemUploadController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemUploadController.java @@ -17,7 +17,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.dspace.app.rest.converter.BitstreamConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.converter.MetadataConverter; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.BitstreamRest; @@ -58,7 +58,7 @@ public class ItemUploadController { private BitstreamService bitstreamService; @Autowired - private BitstreamConverter bitstreamConverter; + private ConverterService converter; @Autowired private MetadataConverter metadataConverter; @@ -109,7 +109,7 @@ public class ItemUploadController { log.error(message, e); throw new RuntimeException(message, e); } - return new BitstreamResource(bitstreamConverter.fromModel(bitstream), utils); + return converter.toResource(converter.toRest(bitstream)); } /** diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/MappedCollectionRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/MappedCollectionRestController.java index 791e85a59b..a921a8ec36 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/MappedCollectionRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/MappedCollectionRestController.java @@ -18,7 +18,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; -import org.dspace.app.rest.converter.CollectionConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.MethodNotAllowedException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.link.HalLinkService; @@ -57,7 +57,7 @@ public class MappedCollectionRestController { private ItemService itemService; @Autowired - private CollectionConverter collectionConverter; + private ConverterService converter; @Autowired private CollectionService collectionService; @@ -100,18 +100,15 @@ public class MappedCollectionRestController { List mappingCollectionRest = new LinkedList<>(); for (Collection collection : collections) { if (collection.getID() != owningCollectionUuid) { - mappingCollectionRest.add(collectionConverter.fromModel(collection)); + mappingCollectionRest.add(converter.toRest(collection)); } } MappedCollectionRestWrapper mappingCollectionRestWrapper = new MappedCollectionRestWrapper(); mappingCollectionRestWrapper.setMappedCollectionRestList(mappingCollectionRest); mappingCollectionRestWrapper.setItem(item); - MappedCollectionResourceWrapper mappingCollectionResourceWrapper = new MappedCollectionResourceWrapper( - mappingCollectionRestWrapper, utils, pageable); - - - halLinkService.addLinks(mappingCollectionResourceWrapper); + MappedCollectionResourceWrapper mappingCollectionResourceWrapper = + converter.toResource(mappingCollectionRestWrapper); return mappingCollectionResourceWrapper; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/MappedItemRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/MappedItemRestController.java index 984f5c7ad7..9ccbeebd2f 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/MappedItemRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/MappedItemRestController.java @@ -15,7 +15,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; -import org.dspace.app.rest.converter.ItemConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.link.HalLinkService; import org.dspace.app.rest.model.ItemRest; import org.dspace.app.rest.model.MappedItemRestWrapper; @@ -53,7 +53,7 @@ public class MappedItemRestController { private ItemService itemService; @Autowired - private ItemConverter itemConverter; + private ConverterService converter; @Autowired Utils utils; @@ -95,7 +95,7 @@ public class MappedItemRestController { while (itemIterator.hasNext()) { Item item = itemIterator.next(); if (item.getOwningCollection().getID() != uuid) { - mappedItemRestList.add(itemConverter.fromModel(item)); + mappedItemRestList.add(converter.toRest(item)); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RelationshipTypeRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RelationshipTypeRestController.java index 303fe6c7e9..d71085f285 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RelationshipTypeRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RelationshipTypeRestController.java @@ -13,7 +13,7 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.dspace.app.rest.converter.RelationshipTypeConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.link.HalLinkService; import org.dspace.app.rest.model.RelationshipTypeRest; import org.dspace.app.rest.model.RelationshipTypeRestWrapper; @@ -48,7 +48,7 @@ public class RelationshipTypeRestController { private EntityTypeService entityTypeService; @Autowired - private RelationshipTypeConverter relationshipTypeConverter; + private ConverterService converter; @Autowired private Utils utils; @@ -76,7 +76,7 @@ public class RelationshipTypeRestController { List relationshipTypeRests = new LinkedList<>(); for (RelationshipType relationshipType : list) { - relationshipTypeRests.add(relationshipTypeConverter.fromModel(relationshipType)); + relationshipTypeRests.add(converter.toRest(relationshipType)); } @@ -85,9 +85,8 @@ public class RelationshipTypeRestController { relationshipTypeRestWrapper.setEntityTypeLabel(entityType.getLabel()); relationshipTypeRestWrapper.setRelationshipTypeRestList(relationshipTypeRests); - RelationshipTypeResourceWrapper relationshipTypeResourceWrapper = new RelationshipTypeResourceWrapper( - relationshipTypeRestWrapper, utils); - halLinkService.addLinks(relationshipTypeResourceWrapper); + RelationshipTypeResourceWrapper relationshipTypeResourceWrapper = + converter.toResource(relationshipTypeRestWrapper); return relationshipTypeResourceWrapper; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java index 15349aec9c..ee83bca3af 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java @@ -19,17 +19,16 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.UUID; - import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; - import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Logger; import org.atteo.evo.inflector.English; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.converter.JsonPatchConverter; import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.PaginationException; @@ -64,7 +63,6 @@ import org.springframework.data.rest.webmvc.ResourceNotFoundException; import org.springframework.data.web.PagedResourcesAssembler; import org.springframework.hateoas.Link; import org.springframework.hateoas.PagedResources; -import org.springframework.hateoas.Resource; import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.Resources; import org.springframework.hateoas.UriTemplate; @@ -130,6 +128,9 @@ public class RestResourceController implements InitializingBean { @Autowired HalLinkService linkService; + @Autowired + ConverterService converter; + @Override public void afterPropertiesSet() { List links = new ArrayList(); @@ -250,9 +251,7 @@ public class RestResourceController implements InitializingBean { if (modelObject == null) { throw new ResourceNotFoundException(apiCategory + "." + model + " with id: " + id + " not found"); } - DSpaceResource result = repository.wrapResource(modelObject); - linkService.addLinks(result); - return result; + return converter.toResource(modelObject); } /** @@ -458,8 +457,7 @@ public class RestResourceController implements InitializingBean { if (modelObject == null) { return ControllerUtils.toEmptyResponse(HttpStatus.CREATED); } - DSpaceResource result = repository.wrapResource(modelObject); - linkService.addLinks(result); + DSpaceResource result = converter.toResource(modelObject); //TODO manage HTTPHeader return ControllerUtils.toResponseEntity(HttpStatus.CREATED, null, result); } @@ -491,8 +489,7 @@ public class RestResourceController implements InitializingBean { if (modelObject == null) { return ControllerUtils.toEmptyResponse(HttpStatus.CREATED); } - DSpaceResource result = repository.wrapResource(modelObject); - linkService.addLinks(result); + DSpaceResource result = converter.toResource(modelObject); //TODO manage HTTPHeader return ControllerUtils.toResponseEntity(HttpStatus.CREATED, null, result); } @@ -530,8 +527,7 @@ public class RestResourceController implements InitializingBean { } if (modelObject != null) { - DSpaceResource result = repository.wrapResource(modelObject); - linkService.addLinks(result); + DSpaceResource result = converter.toResource(modelObject); return ControllerUtils.toResponseEntity(HttpStatus.CREATED, null, result); } else { return ControllerUtils.toEmptyResponse(HttpStatus.NO_CONTENT); @@ -622,8 +618,7 @@ public class RestResourceController implements InitializingBean { log.error(e.getMessage(), e); return ControllerUtils.toEmptyResponse(HttpStatus.INTERNAL_SERVER_ERROR); } - DSpaceResource result = repository.wrapResource(modelObject); - linkService.addLinks(result); + DSpaceResource result = converter.toResource(modelObject); return ControllerUtils.toResponseEntity(HttpStatus.CREATED, null, result); } @@ -660,8 +655,7 @@ public class RestResourceController implements InitializingBean { List resources = new ArrayList<>(); for (T modelObject : content) { - DSpaceResource result = repository.wrapResource(modelObject); - linkService.addLinks(result); + DSpaceResource result = converter.toResource(modelObject); resources.add(result); } return ControllerUtils.toResponseEntity(HttpStatus.OK, null, Resources.wrap(resources)); @@ -740,8 +734,7 @@ public class RestResourceController implements InitializingBean { log.error(e.getMessage(), e); throw e; } - DSpaceResource result = repository.wrapResource(modelObject); - linkService.addLinks(result); + DSpaceResource result = converter.toResource(modelObject); //TODO manage HTTPHeader return ControllerUtils.toResponseEntity(HttpStatus.OK, null, result); @@ -772,11 +765,10 @@ public class RestResourceController implements InitializingBean { DSpaceRestRepository repository = utils.getResourceRepository(apiCategory, model); Class domainClass = repository.getDomainClass(); - LinkRest linkRest = utils.getLinkRest(rel, domainClass); + LinkRest linkRest = utils.getClassLevelLinkRest(rel, domainClass); if (linkRest != null) { LinkRestRepository linkRepository = utils.getLinkResourceRepository(apiCategory, model, linkRest.name()); - Method linkMethod = repositoryUtils.getLinkMethod("getResource", linkRepository); - + Method linkMethod = utils.requireMethod(linkRepository.getClass(), "getResource"); try { Object object = linkMethod.invoke(linkRepository, request, id, relid, page, projection); Link link = linkTo(this.getClass(), apiCategory, model).slash(id).slash(rel).slash(relid).withSelfRel(); @@ -784,8 +776,7 @@ public class RestResourceController implements InitializingBean { List result = new ArrayList(); result.add(object); PageImpl pageResult = new PageImpl(result, page, 1); - Page halResources = pageResult.map(linkRepository::wrapResource); - halResources.forEach(linkService::addLinks); + Page halResources = pageResult.map(restObject -> converter.toResource(restObject)); return assembler.toResource(halResources, link); } catch (InvocationTargetException e) { // This catch has been made to resolve the issue that caused AuthorizeDenied exceptions for the methods @@ -827,48 +818,39 @@ public class RestResourceController implements InitializingBean { DSpaceRestRepository repository = utils.getResourceRepository(apiCategory, model); Class domainClass = repository.getDomainClass(); - LinkRest linkRest = utils.getLinkRest(subpath, domainClass); + LinkRest linkRest = utils.getClassLevelLinkRest(subpath, domainClass); PagedResources result; if (linkRest != null) { LinkRestRepository linkRepository = utils.getLinkResourceRepository(apiCategory, model, linkRest.name()); - Method linkMethod = repositoryUtils.getLinkMethod(linkRest.method(), linkRepository); + Method linkMethod = utils.requireMethod(linkRepository.getClass(), linkRest.method()); + try { + if (Page.class.isAssignableFrom(linkMethod.getReturnType())) { + Page pageResult = (Page) linkMethod + .invoke(linkRepository, request, uuid, page, projection); - if (linkMethod == null) { - // TODO custom exception - throw new RuntimeException( - "Method for relation " + subpath + " not found: " + linkRest.name() + ":" + linkRest.method()); - } else { - try { - if (Page.class.isAssignableFrom(linkMethod.getReturnType())) { - Page pageResult = (Page) linkMethod - .invoke(linkRepository, request, uuid, page, projection); - - Link link = null; - String querystring = request.getQueryString(); - if (querystring != null && querystring.length() > 0) { - link = linkTo(this.getClass(), apiCategory, model).slash(uuid) - .slash(subpath + '?' + querystring).withSelfRel(); - } else { - link = linkTo(this.getClass(), apiCategory, model).slash(uuid).slash(subpath).withSelfRel(); - } - - Page halResources = pageResult.map(linkRepository::wrapResource); - halResources.forEach(linkService::addLinks); - - return assembler.toResource(halResources, link); + Link link = null; + String querystring = request.getQueryString(); + if (querystring != null && querystring.length() > 0) { + link = linkTo(this.getClass(), apiCategory, model).slash(uuid) + .slash(subpath + '?' + querystring).withSelfRel(); } else { - RestModel object = (RestModel) linkMethod.invoke(linkRepository, request, uuid, page, - projection); - Link link = linkTo(this.getClass(), apiCategory, model).slash(uuid).slash(subpath) - .withSelfRel(); - HALResource tmpresult = linkRepository.wrapResource(object); - tmpresult.add(link); - return tmpresult; + link = linkTo(this.getClass(), apiCategory, model).slash(uuid).slash(subpath).withSelfRel(); } - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - throw new RuntimeException(e.getMessage(), e); + + Page halResources = pageResult.map(object -> converter.toResource(object)); + return assembler.toResource(halResources, link); + } else { + RestModel object = (RestModel) linkMethod.invoke(linkRepository, request, uuid, page, + projection); + Link link = linkTo(this.getClass(), apiCategory, model).slash(uuid).slash(subpath) + .withSelfRel(); + HALResource tmpresult = converter.toResource(object); + tmpresult.add(link); + return tmpresult; } + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new RuntimeException(e.getMessage(), e); } } RestAddressableModel modelObject = repository.findOne(uuid); @@ -877,8 +859,7 @@ public class RestResourceController implements InitializingBean { throw new ResourceNotFoundException(apiCategory + "." + model + " with id: " + uuid + " not found"); } - DSpaceResource resource = repository.wrapResource(modelObject, subpath); - linkService.addLinks(resource); + DSpaceResource resource = converter.toResource(modelObject); String rel = null; @@ -919,16 +900,7 @@ public class RestResourceController implements InitializingBean { .getResourceRepository(fullList.get(0).getCategory(), fullList.get(0).getType()); PageImpl pageResult = new PageImpl(fullList.subList(start, end), page, fullList.size()); - result = assembler.toResource(pageResult.map(resourceRepository::wrapResource)); - - for (Resource subObj : result) { - if (subObj.getContent() instanceof HALResource) { - linkService.addLinks((HALResource) subObj.getContent()); - } - } - return result; - - + return assembler.toResource(pageResult.map(converter::toResource)); } else { if (resource.getEmbeddedResources().get(rel) == null) { response.setStatus(HttpServletResponse.SC_NO_CONTENT); @@ -964,8 +936,7 @@ public class RestResourceController implements InitializingBean { Page> resources; try { - resources = repository.findAll(page).map(repository::wrapResource); - resources.forEach(linkService::addLinks); + resources = repository.findAll(page).map(converter::toResource); } catch (PaginationException pe) { resources = new PageImpl>(new ArrayList>(), page, pe.getTotal()); } catch (RepositoryMethodNotImplementedException mne) { @@ -1044,18 +1015,15 @@ public class RestResourceController implements InitializingBean { if (searchResult == null) { resources = new PageImpl(new ArrayList(), pageable, 0); } else { - resources = ((Page) searchResult).map(repository::wrapResource); + resources = ((Page) searchResult).map(converter::toResource); } - resources.forEach(linkService::addLinks); result = assembler.toResource(resources, link); } else { if (searchResult == null) { response.setStatus(HttpServletResponse.SC_NO_CONTENT); return null; } - DSpaceResource dsResource = repository.wrapResource((T) searchResult); - linkService.addLinks(dsResource); - result = dsResource; + return converter.toResource((T) searchResult); } return result; } @@ -1204,9 +1172,7 @@ public class RestResourceController implements InitializingBean { if (modelObject == null) { throw new ResourceNotFoundException(apiCategory + "." + model + " with id: " + id + " not found"); } - DSpaceResource result = repository.wrapResource(modelObject); - linkService.addLinks(result); - return result; + return converter.toResource(modelObject); } /** @@ -1229,9 +1195,6 @@ public class RestResourceController implements InitializingBean { if (modelObject == null) { throw new ResourceNotFoundException(apiCategory + "." + model + " with id: " + id + " not found"); } - DSpaceResource result = repository.wrapResource(modelObject); - linkService.addLinks(result); - return result; - + return converter.toResource(modelObject); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RootRestResourceController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RootRestResourceController.java index 0f8d770b37..7cb1854af8 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RootRestResourceController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RootRestResourceController.java @@ -9,8 +9,8 @@ package org.dspace.app.rest; import javax.servlet.http.HttpServletRequest; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.link.HalLinkService; -import org.dspace.app.rest.model.RootRest; import org.dspace.app.rest.model.hateoas.RootResource; import org.dspace.app.rest.repository.RootRestRepository; import org.springframework.beans.factory.annotation.Autowired; @@ -39,13 +39,11 @@ public class RootRestResourceController { @Autowired RootRestRepository rootRestRepository; + @Autowired + ConverterService converter; + @RequestMapping(method = RequestMethod.GET) public RootResource listDefinedEndpoint(HttpServletRequest request) { - - RootRest rootRest = rootRestRepository.getRoot(); - RootResource rootResource = new RootResource(rootRest); - halLinkService.addLinks(rootResource); - - return rootResource; + return converter.toResource(rootRestRepository.getRoot()); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/StatisticsRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/StatisticsRestController.java index 6b55879158..26447a7c9b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/StatisticsRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/StatisticsRestController.java @@ -10,6 +10,7 @@ package org.dspace.app.rest; import java.util.Arrays; import java.util.UUID; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException; import org.dspace.app.rest.link.HalLinkService; import org.dspace.app.rest.model.RestAddressableModel; @@ -47,6 +48,9 @@ public class StatisticsRestController implements InitializingBean { @Autowired private HalLinkService halLinkService; + @Autowired + private ConverterService converter; + @Autowired private StatisticsRestRepository statisticsRestRepository; @@ -65,12 +69,10 @@ public class StatisticsRestController implements InitializingBean { @RequestMapping(method = RequestMethod.GET) public StatisticsSupportResource getStatisticsSupport() throws Exception { - StatisticsSupportRest statisticsSupportRest = statisticsRestRepository.getStatisticsSupport(); - StatisticsSupportResource statisticsSupportResource = new StatisticsSupportResource(statisticsSupportRest); - halLinkService.addLinks(statisticsSupportResource); - return statisticsSupportResource; + return converter.toResource(statisticsSupportRest); } + @RequestMapping(method = RequestMethod.GET, value = "/viewevents/{uuid}") public PagedResources getViewEvent(@PathVariable(name = "uuid") UUID uuid) throws Exception { throw new RepositoryMethodNotImplementedException("No implementation found; Method not allowed!", ""); @@ -93,13 +95,13 @@ public class StatisticsRestController implements InitializingBean { @RequestMapping(method = RequestMethod.POST, value = "/viewevents") public ResponseEntity postViewEvent() throws Exception { - ViewEventResource result = new ViewEventResource(viewEventRestRepository.createViewEvent(), utils); + ViewEventResource result = converter.toResource(viewEventRestRepository.createViewEvent()); return ControllerUtils.toResponseEntity(HttpStatus.CREATED, null, result); } @RequestMapping(method = RequestMethod.POST, value = "/searchevents") public ResponseEntity postSearchEvent() throws Exception { - SearchEventResource result = new SearchEventResource(searchEventRestRepository.createSearchEvent(), utils); + SearchEventResource result = converter.toResource(searchEventRestRepository.createSearchEvent()); return ControllerUtils.toResponseEntity(HttpStatus.CREATED, null, result); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/UUIDLookupRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/UUIDLookupRestController.java index 75d7fb5094..280a91a41f 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/UUIDLookupRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/UUIDLookupRestController.java @@ -14,12 +14,11 @@ import java.net.URI; import java.sql.SQLException; import java.util.Arrays; import java.util.UUID; - import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; -import org.dspace.app.rest.converter.GenericDSpaceObjectConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.DSpaceObjectRest; import org.dspace.app.rest.utils.ContextUtil; import org.dspace.content.DSpaceObject; @@ -64,7 +63,7 @@ public class UUIDLookupRestController implements InitializingBean { private DiscoverableEndpointsService discoverableEndpointsService; @Autowired - private GenericDSpaceObjectConverter converter; + private ConverterService converter; @Override public void afterPropertiesSet() throws Exception { @@ -92,7 +91,7 @@ public class UUIDLookupRestController implements InitializingBean { .getDSpaceObjectServices()) { DSpaceObject dso = dSpaceObjectService.find(context, uuid); if (dso != null) { - DSpaceObjectRest dsor = converter.convert(dso); + DSpaceObjectRest dsor = converter.toRest(dso); URI link = linkTo(dsor.getController(), dsor.getCategory(), dsor.getTypePlural()) .slash(dsor.getId()).toUri(); response.setStatus(HttpServletResponse.SC_FOUND); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AInprogressItemConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AInprogressItemConverter.java index 973769f138..59e1d0db58 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AInprogressItemConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AInprogressItemConverter.java @@ -47,22 +47,13 @@ public abstract class AInprogressItemConverter { @Override - public AuthorityEntryRest fromModel(Choice choice) { + public AuthorityEntryRest convert(Choice choice) { AuthorityEntryRest entry = new AuthorityEntryRest(); entry.setValue(choice.value); entry.setDisplay(choice.label); @@ -35,7 +34,7 @@ public class AuthorityEntryRestConverter implements DSpaceConverter getModelClass() { + return Choice.class; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AuthorityRestConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AuthorityRestConverter.java index b07f4d49e7..64c332e283 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AuthorityRestConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AuthorityRestConverter.java @@ -7,7 +7,6 @@ */ package org.dspace.app.rest.converter; -import org.apache.commons.lang3.NotImplementedException; import org.dspace.app.rest.model.AuthorityRest; import org.dspace.app.rest.utils.AuthorityUtils; import org.dspace.content.authority.ChoiceAuthority; @@ -26,7 +25,7 @@ import org.springframework.stereotype.Component; public class AuthorityRestConverter implements DSpaceConverter { @Override - public AuthorityRest fromModel(ChoiceAuthority step) { + public AuthorityRest convert(ChoiceAuthority step) { AuthorityRest authorityRest = new AuthorityRest(); authorityRest.setHierarchical(step.isHierarchical()); authorityRest.setScrollable(step.isScrollable()); @@ -35,7 +34,7 @@ public class AuthorityRestConverter implements DSpaceConverter getModelClass() { + return ChoiceAuthority.class; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BitstreamConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BitstreamConverter.java index 5f507d7380..d8b8802778 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BitstreamConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BitstreamConverter.java @@ -10,7 +10,6 @@ package org.dspace.app.rest.converter; import java.sql.SQLException; import java.util.List; -import org.dspace.app.rest.model.BitstreamFormatRest; import org.dspace.app.rest.model.BitstreamRest; import org.dspace.app.rest.model.CheckSumRest; import org.dspace.content.Bitstream; @@ -27,17 +26,13 @@ import org.springframework.stereotype.Component; @Component public class BitstreamConverter extends DSpaceObjectConverter { - @Autowired(required = true) - BitstreamFormatConverter bfConverter; + + @Autowired + ConverterService converter; @Override - public org.dspace.content.Bitstream toModel(org.dspace.app.rest.model.BitstreamRest obj) { - return super.toModel(obj); - } - - @Override - public BitstreamRest fromModel(org.dspace.content.Bitstream obj) { - BitstreamRest b = super.fromModel(obj); + public BitstreamRest convert(org.dspace.content.Bitstream obj) { + BitstreamRest b = super.convert(obj); b.setSequenceId(obj.getSequenceID()); List bundles = null; try { @@ -53,14 +48,11 @@ public class BitstreamConverter checksum.setCheckSumAlgorithm(obj.getChecksumAlgorithm()); checksum.setValue(obj.getChecksum()); b.setCheckSum(checksum); - BitstreamFormatRest format = null; try { - format = bfConverter.fromModel(obj.getFormat(null)); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + b.setFormat(converter.toRest(obj.getFormat(null))); + } catch (SQLException e) { + throw new RuntimeException(e); } - b.setFormat(format); b.setSizeBytes(obj.getSizeBytes()); return b; } @@ -71,7 +63,7 @@ public class BitstreamConverter } @Override - protected Class getModelClass() { + public Class getModelClass() { return Bitstream.class; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BitstreamFormatConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BitstreamFormatConverter.java index 07a79f0a8b..023008dbd4 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BitstreamFormatConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BitstreamFormatConverter.java @@ -26,7 +26,7 @@ public class BitstreamFormatConverter implements DSpaceConverter getModelClass() { + return BitstreamFormat.class; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BrowseIndexConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BrowseIndexConverter.java index b49fcab0cb..3e70e79c6e 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BrowseIndexConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BrowseIndexConverter.java @@ -24,8 +24,9 @@ import org.springframework.stereotype.Component; */ @Component public class BrowseIndexConverter implements DSpaceConverter { + @Override - public BrowseIndexRest fromModel(BrowseIndex obj) { + public BrowseIndexRest convert(BrowseIndex obj) { BrowseIndexRest bir = new BrowseIndexRest(); bir.setId(obj.getName()); bir.setOrder(obj.getDefaultOrder()); @@ -53,7 +54,7 @@ public class BrowseIndexConverter implements DSpaceConverter getModelClass() { + return BrowseIndex.class; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ClaimedTaskConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ClaimedTaskConverter.java index d448455286..125969ed86 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ClaimedTaskConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ClaimedTaskConverter.java @@ -25,27 +25,24 @@ public class ClaimedTaskConverter implements IndexableObjectConverter { @Autowired - private WorkflowItemConverter workflowItemConverter; - - @Autowired - private EPersonConverter epersonConverter; + private ConverterService converter; @Override - public ClaimedTaskRest fromModel(ClaimedTask obj) { + public ClaimedTaskRest convert(ClaimedTask obj) { ClaimedTaskRest taskRest = new ClaimedTaskRest(); XmlWorkflowItem witem = obj.getWorkflowItem(); taskRest.setId(obj.getID()); - taskRest.setWorkflowitem(workflowItemConverter.convert(witem)); + taskRest.setWorkflowitem(converter.toRest(witem)); taskRest.setAction(obj.getActionID()); taskRest.setStep(obj.getStepID()); - taskRest.setOwner(epersonConverter.convert(obj.getOwner())); + taskRest.setOwner(converter.toRest(obj.getOwner())); return taskRest; } @Override - public ClaimedTask toModel(ClaimedTaskRest obj) { - return null; + public Class getModelClass() { + return ClaimedTask.class; } @Override @@ -53,4 +50,4 @@ public class ClaimedTaskConverter return object instanceof ClaimedTask; } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/CollectionConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/CollectionConverter.java index b51b0ff56d..c84d27de60 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/CollectionConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/CollectionConverter.java @@ -44,27 +44,20 @@ public class CollectionConverter private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(CollectionConverter.class); @Autowired - private BitstreamConverter bitstreamConverter; + private ConverterService converter; @Autowired private CollectionService collectionService; @Autowired private RequestService requestService; @Autowired private AuthorizeService authorizeService; - @Autowired - private ResourcePolicyConverter resourcePolicyConverter; @Override - public org.dspace.content.Collection toModel(org.dspace.app.rest.model.CollectionRest obj) { - return (org.dspace.content.Collection) super.toModel(obj); - } - - @Override - public CollectionRest fromModel(org.dspace.content.Collection obj) { - CollectionRest col = (CollectionRest) super.fromModel(obj); + public CollectionRest convert(org.dspace.content.Collection obj) { + CollectionRest col = super.convert(obj); Bitstream logo = obj.getLogo(); if (logo != null) { - col.setLogo(bitstreamConverter.convert(logo)); + col.setLogo(converter.toRest(logo)); } col.setDefaultAccessConditions(getDefaultBitstreamPoliciesForCollection(obj.getID())); @@ -95,7 +88,7 @@ public class CollectionConverter List results = new ArrayList(); for (ResourcePolicy pp : defaultCollectionPolicies) { - ResourcePolicyRest accessCondition = resourcePolicyConverter.convert(pp); + ResourcePolicyRest accessCondition = converter.toRest(pp); if (accessCondition != null) { results.add(accessCondition); } @@ -109,7 +102,7 @@ public class CollectionConverter } @Override - protected Class getModelClass() { + public Class getModelClass() { return org.dspace.content.Collection.class; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/CommunityConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/CommunityConverter.java index 09634e30bd..854d5807b2 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/CommunityConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/CommunityConverter.java @@ -31,38 +31,29 @@ public class CommunityConverter implements IndexableObjectConverter { @Autowired - private BitstreamConverter bitstreamConverter; - - @Autowired - private CollectionConverter collectionConverter; + private ConverterService converter; @Override - public org.dspace.content.Community toModel(org.dspace.app.rest.model.CommunityRest obj) { - return (org.dspace.content.Community) super.toModel(obj); - } - - @Override - public CommunityRest fromModel(org.dspace.content.Community obj) { - CommunityRest com = (CommunityRest) super.fromModel(obj); + public CommunityRest convert(org.dspace.content.Community obj) { + CommunityRest com = super.convert(obj); Bitstream logo = obj.getLogo(); if (logo != null) { - com.setLogo(bitstreamConverter.convert(logo)); + com.setLogo(converter.toRest(logo)); } List collections = obj.getCollections(); - List collectionsRest = new ArrayList(); + List collectionsRest = new ArrayList<>(); if (collections != null) { for (Collection col : collections) { - CollectionRest colrest = collectionConverter.fromModel(col); - collectionsRest.add(colrest); + collectionsRest.add(converter.toRest(col)); } } com.setCollections(collectionsRest); List subCommunities = obj.getSubcommunities(); - List communityRest = new ArrayList(); + List communityRest = new ArrayList<>(); if (subCommunities != null) { for (Community scom : subCommunities) { - CommunityRest scomrest = this.fromModel(scom); + CommunityRest scomrest = this.convert(scom); communityRest.add(scomrest); } } @@ -77,7 +68,7 @@ public class CommunityConverter } @Override - protected Class getModelClass() { + public Class getModelClass() { return org.dspace.content.Community.class; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java new file mode 100644 index 0000000000..bf0b92b550 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java @@ -0,0 +1,189 @@ +/** + * 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.converter; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import javax.annotation.Nullable; +import javax.annotation.PostConstruct; + +import org.apache.log4j.Logger; +import org.dspace.app.rest.link.HalLinkService; +import org.dspace.app.rest.model.RestAddressableModel; +import org.dspace.app.rest.model.RestModel; +import org.dspace.app.rest.model.hateoas.DSpaceResource; +import org.dspace.app.rest.model.hateoas.HALResource; +import org.dspace.app.rest.projection.Projection; +import org.dspace.app.rest.utils.Utils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; +import org.springframework.core.type.filter.AssignableTypeFilter; +import org.springframework.hateoas.Resource; +import org.springframework.stereotype.Component; + +/** + * Service to convert domain objects from the service layer to rest and resource form on the way out of DSpace. + */ +@Component +public class ConverterService { + + private static final Logger log = Logger.getLogger(ConverterService.class); + + private final Map projectionMap = new HashMap<>(); + + private final Map converterMap = new HashMap<>(); + + private final Map, Constructor> resourceConstructors = new HashMap<>(); + + @Autowired + private Utils utils; + + @Autowired + private HalLinkService halLinkService; + + @Autowired + private List converters; + + @Autowired + private List projections; + + @PostConstruct + private void initialize() { + for (Projection projection : projections) { + projectionMap.put(projection.getName(), projection); + } + projectionMap.put(Projection.DEFAULT.getName(), Projection.DEFAULT); + + for (DSpaceConverter converter : converters) { + converterMap.put(converter.getModelClass(), converter); + } + + ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false); + provider.addIncludeFilter(new AssignableTypeFilter(Resource.class)); + Set beanDefinitions = provider.findCandidateComponents( + HALResource.class.getPackage().getName().replaceAll("\\.", "/")); + for (BeanDefinition beanDefinition : beanDefinitions) { + String resourceClassName = beanDefinition.getBeanClassName(); + String resourceClassSimpleName = resourceClassName.substring(resourceClassName.lastIndexOf(".") + 1); + String restClassSimpleName = resourceClassSimpleName + .replaceAll("ResourceWrapper$", "RestWrapper") + .replaceAll("Resource$", "Rest"); + String restClassName = RestModel.class.getPackage().getName() + "." + restClassSimpleName; + try { + Class restClass = + (Class) Class.forName(restClassName); + Class> resourceClass = + (Class>) Class.forName(resourceClassName); + Constructor compatibleConstructor = null; + for (Constructor constructor : resourceClass.getDeclaredConstructors()) { + if (constructor.getParameterCount() == 2 && constructor.getParameterTypes()[1] == Utils.class) { + compatibleConstructor = constructor; + break; // found preferred constructor + } else if (constructor.getParameterCount() == 1) { + compatibleConstructor = constructor; + } + } + if (compatibleConstructor != null) { + resourceConstructors.put(restClass, compatibleConstructor); + } else { + logSkipping(resourceClassName, "compatible constructor not found"); + } + } catch (ClassNotFoundException e) { + logSkipping(resourceClassName, "rest class not found: " + restClassName); + } + } + } + + private void logSkipping(String resourceClassName, String reason) { + log.warn("Skipping registration of resource class " + resourceClassName + "; " + reason); + } + + private Projection requireProjection(String projectionName) { + if (!projectionMap.containsKey(projectionName)) { + throw new IllegalArgumentException("No such projection: " + projectionName); + } + return projectionMap.get(projectionName); + } + + public T toRest(Object modelObject) { + return toRest(modelObject, null); + } + + public R toRest(M modelObject, @Nullable String projectionName) { + Projection projection = projectionName == null ? Projection.DEFAULT : requireProjection(projectionName); + M transformedModel = projection.transformModel(modelObject); + DSpaceConverter converter = requireConverter(modelObject.getClass()); + R restObject = converter.convert(transformedModel); + if (restObject instanceof RestAddressableModel) { + RestAddressableModel ram = projection.transformRest((RestAddressableModel) restObject); + ram.setProjection(projection); + return (R) ram; + } + return restObject; + } + + public DSpaceConverter getConverter(Class sourceClass) { + return (DSpaceConverter) requireConverter(sourceClass); + } + + private DSpaceConverter requireConverter(Class sourceClass) { + if (converterMap.containsKey(sourceClass)) { + return converterMap.get(sourceClass); + } + for (Class converterSourceClass : converterMap.keySet()) { + if (converterSourceClass.isAssignableFrom(sourceClass)) { + return converterMap.get(converterSourceClass); + } + } + throw new IllegalArgumentException("No converter found to get rest class from " + sourceClass); + } + + public T toResource(RestModel restObject, @Nullable String projectionName) { + if (restObject instanceof RestAddressableModel) { + ((RestAddressableModel) restObject).setProjection(requireProjection(projectionName)); + } + return toResource(restObject); + } + + public T toResource(RestModel restObject) { + T halResource = getResource(restObject); + if (restObject instanceof RestAddressableModel) { + utils.embedOrLinkClassLevelRels(halResource); + halLinkService.addLinks(halResource); + Projection projection = ((RestAddressableModel) restObject).getProjection(); + return projection.transformResource(halResource); + } else { + halLinkService.addLinks(halResource); + } + return halResource; + } + + private T getResource(RestModel restObject) { + Constructor constructor = resourceConstructors.get(restObject.getClass()); + try { + if (constructor == null) { + constructor = DSpaceResource.class.getDeclaredConstructor(); + } + if (constructor.getParameterCount() == 2) { + return (T) constructor.newInstance(restObject, utils); + } else { + return (T) constructor.newInstance(restObject); + } + } catch (InstantiationException + | IllegalAccessException + | InvocationTargetException + | NoSuchMethodException e) { + throw new RuntimeException(e); + } + } +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceConverter.java index d195f1ab8d..17cecb33a6 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceConverter.java @@ -10,12 +10,5 @@ package org.dspace.app.rest.converter; import org.springframework.core.convert.converter.Converter; public interface DSpaceConverter extends Converter { - @Override - public default R convert(M source) { - return fromModel(source); - } - - public abstract R fromModel(M obj); - - public abstract M toModel(R obj); + Class getModelClass(); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceObjectConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceObjectConverter.java index 42b57983e3..e8e11ecd50 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceObjectConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceObjectConverter.java @@ -21,11 +21,11 @@ import org.springframework.beans.factory.annotation.Autowired; public abstract class DSpaceObjectConverter implements DSpaceConverter { - @Autowired(required = true) + @Autowired private MetadataConverter metadataConverter; @Override - public R fromModel(M obj) { + public R convert(M obj) { R resource = newInstance(); resource.setHandle(obj.getHandle()); if (obj.getID() != null) { @@ -36,17 +36,5 @@ public abstract class DSpaceObjectConverter getModelClass(); - -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EPersonConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EPersonConverter.java index 0e39d3a7fb..d902d86b2a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EPersonConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EPersonConverter.java @@ -30,17 +30,17 @@ import org.springframework.stereotype.Component; @Component public class EPersonConverter extends DSpaceObjectConverter { - @Autowired(required = true) - private GroupConverter epersonGroupConverter; + @Autowired + private ConverterService converter; - @Autowired(required = true) + @Autowired private GroupService groupService; private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(EPersonConverter.class); @Override - public EPersonRest fromModel(EPerson obj) { - EPersonRest eperson = super.fromModel(obj); + public EPersonRest convert(EPerson obj) { + EPersonRest eperson = super.convert(obj); eperson.setLastActive(obj.getLastActive()); eperson.setNetid(obj.getNetid()); eperson.setCanLogIn(obj.canLogIn()); @@ -52,30 +52,24 @@ public class EPersonConverter extends DSpaceObjectConverter groups = new ArrayList(); + List groups = new ArrayList<>(); for (Group g : groupService.allMemberGroups(context, ePerson)) { - groups.add(epersonGroupConverter.convert(g)); + groups.add(converter.toRest(g)); } eperson.setGroups(groups); return eperson; } - @Override - public EPerson toModel(EPersonRest obj) { - // TODO Auto-generated method stub - return null; - } - @Override protected EPersonRest newInstance() { return new EPersonRest(); } @Override - protected Class getModelClass() { + public Class getModelClass() { return EPerson.class; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EntityTypeConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EntityTypeConverter.java index ae2ef646c5..e56e627de2 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EntityTypeConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EntityTypeConverter.java @@ -24,23 +24,16 @@ public class EntityTypeConverter implements DSpaceConverter getModelClass() { + return EntityType.class; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/GenericDSpaceObjectConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/GenericDSpaceObjectConverter.java deleted file mode 100644 index c5443a0395..0000000000 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/GenericDSpaceObjectConverter.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * 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.converter; - -import java.util.List; - -import org.apache.log4j.Logger; -import org.dspace.app.rest.model.DSpaceObjectRest; -import org.dspace.content.DSpaceObject; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -/** - * This is the converter from/to an unknown DSpaceObject in the DSpace API data model and the - * REST data model - * - * @author Andrea Bollini (andrea.bollini at 4science.it) - */ -@Component -public class GenericDSpaceObjectConverter - extends DSpaceObjectConverter { - - @Autowired - private List converters; - - private static final Logger log = Logger.getLogger(GenericDSpaceObjectConverter.class); - - /** - * Convert a DSpaceObject in its REST representation using a suitable converter - */ - @Override - public DSpaceObjectRest fromModel(org.dspace.content.DSpaceObject dspaceObject) { - for (DSpaceObjectConverter converter : converters) { - if (converter.supportsModel(dspaceObject)) { - return converter.fromModel(dspaceObject); - } - } - return null; - } - - @Override - public org.dspace.content.DSpaceObject toModel(DSpaceObjectRest obj) { - return null; - } - - @Override - protected DSpaceObjectRest newInstance() { - return null; - } - - @Override - protected Class getModelClass() { - return DSpaceObject.class; - } - -} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/GroupConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/GroupConverter.java index bb7c1c64c8..378868a3bb 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/GroupConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/GroupConverter.java @@ -27,8 +27,8 @@ public class GroupConverter extends DSpaceObjectConverter groups = new ArrayList(); for (Group g : obj.getMemberGroups()) { @@ -39,19 +39,13 @@ public class GroupConverter extends DSpaceObjectConverter getModelClass() { + public Class getModelClass() { return Group.class; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/HarvestedCollectionConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/HarvestedCollectionConverter.java index e3176d7563..60f818da34 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/HarvestedCollectionConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/HarvestedCollectionConverter.java @@ -18,7 +18,6 @@ import org.dspace.content.Collection; import org.dspace.harvest.HarvestedCollection; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import sun.reflect.generics.reflectiveObjects.NotImplementedException; /** * This is the converter from/to the HarvestedCollection in the DSpace API data model and the REST data model @@ -29,10 +28,10 @@ import sun.reflect.generics.reflectiveObjects.NotImplementedException; public class HarvestedCollectionConverter implements DSpaceConverter { @Autowired - private CollectionConverter collectionConverter; + private ConverterService converter; @Override - public HarvestedCollectionRest fromModel(HarvestedCollection obj) { + public HarvestedCollectionRest convert(HarvestedCollection obj) { HarvestedCollectionRest harvestedCollectionRest = new HarvestedCollectionRest(); if (obj != null) { @@ -40,7 +39,7 @@ public class HarvestedCollectionConverter implements DSpaceConverter> metadata_configs) { - HarvestedCollectionRest harvestedCollectionRest = this.fromModel(obj); + HarvestedCollectionRest harvestedCollectionRest = this.convert(obj); // Add collectionRest to the empty HarvestedCollectionRest so that we can use its uuid later in the linkFactory if (obj == null) { - harvestedCollectionRest.setCollection(collectionConverter.fromModel(collection)); + harvestedCollectionRest.setCollection(converter.toRest(collection)); } HarvesterMetadataRest harvesterMetadataRest = new HarvesterMetadataRest(); @@ -76,7 +75,7 @@ public class HarvestedCollectionConverter implements DSpaceConverter getModelClass() { + return HarvestedCollection.class; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/IndexableObjectConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/IndexableObjectConverter.java index e7887bb9c1..b4e789ab1f 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/IndexableObjectConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/IndexableObjectConverter.java @@ -26,6 +26,5 @@ public interface IndexableObjectConverter implements IndexableObjectConverter { - @Autowired(required = true) - private CollectionConverter collectionConverter; - @Autowired(required = true) - private BitstreamConverter bitstreamConverter; + @Autowired + private ConverterService converter; + @Autowired + private MetadataConverter metadataConverter; @Autowired private RequestService requestService; @Autowired private RelationshipService relationshipService; @Autowired - private RelationshipConverter relationshipConverter; - @Autowired private ItemService itemService; - @Autowired - private MetadataConverter metadataConverter; private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(ItemConverter.class); @Override - public ItemRest fromModel(org.dspace.content.Item obj) { - ItemRest item = super.fromModel(obj); + public ItemRest convert(org.dspace.content.Item obj) { + ItemRest item = super.convert(obj); item.setInArchive(obj.isArchived()); item.setDiscoverable(obj.isDiscoverable()); item.setWithdrawn(obj.isWithdrawn()); item.setLastModified(obj.getLastModified()); - try { - Collection c = obj.getOwningCollection(); - if (c != null) { - item.setOwningCollection(collectionConverter.fromModel(c)); - } - } catch (Exception e) { - log.error("Error setting owning collection for item" + item.getHandle(), e); + Collection owningCollection = obj.getOwningCollection(); + if (owningCollection != null) { + item.setOwningCollection(converter.toRest(owningCollection)); } - try { - Collection c = obj.getTemplateItemOf(); - if (c != null) { - item.setTemplateItemOf(collectionConverter.fromModel(c)); - } - } catch (Exception e) { - log.error("Error setting template item of for item " + item.getHandle(), e); + Collection templateItemOf = obj.getTemplateItemOf(); + if (templateItemOf != null) { + item.setTemplateItemOf(converter.toRest(templateItemOf)); } - List bitstreams = new ArrayList(); + List bitstreams = new ArrayList<>(); for (Bundle bun : obj.getBundles()) { for (Bitstream bit : bun.getBitstreams()) { - BitstreamRest bitrest = bitstreamConverter.fromModel(bit); - bitstreams.add(bitrest); + bitstreams.add(converter.toRest(bit)); } } item.setBitstreams(bitstreams); @@ -108,33 +95,24 @@ public class ItemConverter } List relationshipRestList = new LinkedList<>(); for (Relationship relationship : relationships) { - RelationshipRest relationshipRest = relationshipConverter.fromModel(relationship); + RelationshipRest relationshipRest = converter.toRest(relationship); relationshipRestList.add(relationshipRest); } item.setRelationships(relationshipRestList); - List fullList = new LinkedList<>(); - fullList = itemService.getMetadata(obj, Item.ANY, Item.ANY, Item.ANY, Item.ANY, true); - + List fullList = itemService.getMetadata(obj, Item.ANY, Item.ANY, Item.ANY, Item.ANY, true); item.setMetadata(metadataConverter.convert(fullList)); - return item; } - @Override - public org.dspace.content.Item toModel(ItemRest obj) { - // TODO Auto-generated method stub - return null; - } - @Override protected ItemRest newInstance() { return new ItemRest(); } @Override - protected Class getModelClass() { + public Class getModelClass() { return Item.class; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataConverter.java index 51710f45af..57b332cdd2 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataConverter.java @@ -39,7 +39,7 @@ public class MetadataConverter implements Converter, Metadat private ContentServiceFactory contentServiceFactory; @Autowired - private MetadataValueConverter valueConverter; + private ConverterService converter; /** * Gets a rest representation of the given list of domain metadata values. @@ -58,7 +58,7 @@ public class MetadataConverter implements Converter, Metadat set = new TreeSet<>(Comparator.comparingInt(MetadataValueRest::getPlace)); mapOfSortedSets.put(key, set); } - set.add(valueConverter.convert(metadataValue)); + set.add(converter.toRest(metadataValue)); } MetadataRest metadataRest = new MetadataRest(); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataFieldConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataFieldConverter.java index 89703f98bb..8522f4d8d3 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataFieldConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataFieldConverter.java @@ -8,6 +8,7 @@ package org.dspace.app.rest.converter; import org.dspace.app.rest.model.MetadataFieldRest; +import org.dspace.content.MetadataField; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -19,23 +20,22 @@ import org.springframework.stereotype.Component; */ @Component public class MetadataFieldConverter implements DSpaceConverter { - @Autowired(required = true) - private MetadataSchemaConverter metadataSchemaConverter; + @Autowired + private ConverterService converter; @Override - public MetadataFieldRest fromModel(org.dspace.content.MetadataField obj) { + public MetadataFieldRest convert(org.dspace.content.MetadataField obj) { MetadataFieldRest field = new MetadataFieldRest(); field.setId(obj.getID()); field.setElement(obj.getElement()); field.setQualifier(obj.getQualifier()); field.setScopeNote(obj.getScopeNote()); - field.setSchema(metadataSchemaConverter.convert(obj.getMetadataSchema())); + field.setSchema(converter.toRest(obj.getMetadataSchema())); return field; } @Override - public org.dspace.content.MetadataField toModel(MetadataFieldRest obj) { - // TODO Auto-generated method stub - return null; + public Class getModelClass() { + return MetadataField.class; } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataSchemaConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataSchemaConverter.java index a0847612ca..b1b059bffc 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataSchemaConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataSchemaConverter.java @@ -8,6 +8,7 @@ package org.dspace.app.rest.converter; import org.dspace.app.rest.model.MetadataSchemaRest; +import org.dspace.content.MetadataSchema; import org.springframework.stereotype.Component; /** @@ -19,7 +20,7 @@ import org.springframework.stereotype.Component; @Component public class MetadataSchemaConverter implements DSpaceConverter { @Override - public MetadataSchemaRest fromModel(org.dspace.content.MetadataSchema obj) { + public MetadataSchemaRest convert(org.dspace.content.MetadataSchema obj) { MetadataSchemaRest schema = new MetadataSchemaRest(); schema.setId(obj.getID()); schema.setNamespace(obj.getNamespace()); @@ -28,8 +29,7 @@ public class MetadataSchemaConverter implements DSpaceConverter getModelClass() { + return MetadataSchema.class; } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataValueConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataValueConverter.java index 1095e1870a..f04a59125a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataValueConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataValueConverter.java @@ -9,14 +9,13 @@ package org.dspace.app.rest.converter; import org.dspace.app.rest.model.MetadataValueRest; import org.dspace.content.MetadataValue; -import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component; /** * Converter to translate between domain {@link MetadataValue}s and {@link MetadataValueRest} representations. */ @Component -public class MetadataValueConverter implements Converter { +public class MetadataValueConverter implements DSpaceConverter { /** * Gets a rest representation of the given domain metadata value. @@ -34,4 +33,9 @@ public class MetadataValueConverter implements Converter getModelClass() { + return MetadataValue.class; + } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/PoolTaskConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/PoolTaskConverter.java index 34299c1b0a..ad4e9cf638 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/PoolTaskConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/PoolTaskConverter.java @@ -25,26 +25,20 @@ public class PoolTaskConverter implements IndexableObjectConverter { @Autowired - private WorkflowItemConverter workflowItemConverter; - - @Autowired - private EPersonConverter epersonConverter; - - @Autowired - private GroupConverter groupConverter; + private ConverterService converter; @Override - public PoolTaskRest fromModel(PoolTask obj) { + public PoolTaskRest convert(PoolTask obj) { PoolTaskRest taskRest = new PoolTaskRest(); XmlWorkflowItem witem = obj.getWorkflowItem(); taskRest.setId(obj.getID()); - taskRest.setWorkflowitem(workflowItemConverter.convert(witem)); + taskRest.setWorkflowitem(converter.toRest(witem)); if (obj.getEperson() != null) { - taskRest.setEperson(epersonConverter.convert(obj.getEperson())); + taskRest.setEperson(converter.toRest(obj.getEperson())); } if (obj.getGroup() != null) { - taskRest.setGroup(groupConverter.convert(obj.getGroup())); + taskRest.setGroup(converter.toRest(obj.getGroup())); } taskRest.setAction(obj.getActionID()); taskRest.setStep(obj.getStepID()); @@ -52,8 +46,8 @@ public class PoolTaskConverter } @Override - public PoolTask toModel(PoolTaskRest obj) { - return null; + public Class getModelClass() { + return PoolTask.class; } @Override @@ -61,4 +55,4 @@ public class PoolTaskConverter return object instanceof PoolTask; } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/RelationshipConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/RelationshipConverter.java index 8462d50b6d..93b1583dab 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/RelationshipConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/RelationshipConverter.java @@ -11,7 +11,6 @@ import org.dspace.app.rest.model.RelationshipRest; import org.dspace.content.Relationship; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import sun.reflect.generics.reflectiveObjects.NotImplementedException; /** * This converter is responsible for transforming the model representation of an Relationship to the REST @@ -21,8 +20,7 @@ import sun.reflect.generics.reflectiveObjects.NotImplementedException; public class RelationshipConverter implements DSpaceConverter { @Autowired - private RelationshipTypeConverter relationshipTypeConverter; - + private ConverterService converter; /** * This method converts the Relationship model object that is passed along in the params to the @@ -30,11 +28,11 @@ public class RelationshipConverter implements DSpaceConverter getModelClass() { + return Relationship.class; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/RelationshipTypeConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/RelationshipTypeConverter.java index 4ac98ee762..e792475279 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/RelationshipTypeConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/RelationshipTypeConverter.java @@ -20,7 +20,7 @@ import org.springframework.stereotype.Component; public class RelationshipTypeConverter implements DSpaceConverter { @Autowired - private EntityTypeConverter entityTypeConverter; + private ConverterService converter; /** * This method converts the RelationshipType model object that is passed along in the params to the @@ -28,7 +28,7 @@ public class RelationshipTypeConverter implements DSpaceConverter getModelClass() { + return RelationshipType.class; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ResourcePolicyConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ResourcePolicyConverter.java index 1b67d3b9fc..1632954fe3 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ResourcePolicyConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ResourcePolicyConverter.java @@ -26,7 +26,7 @@ public class ResourcePolicyConverter implements DSpaceConverter getModelClass() { + return ResourcePolicy.class; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SiteConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SiteConverter.java index 48af0551d8..230de07d02 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SiteConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SiteConverter.java @@ -20,14 +20,10 @@ import org.springframework.stereotype.Component; @Component public class SiteConverter extends DSpaceObjectConverter { - @Override - public org.dspace.content.Site toModel(org.dspace.app.rest.model.SiteRest obj) { - return (org.dspace.content.Site) super.toModel(obj); - } @Override - public SiteRest fromModel(org.dspace.content.Site obj) { - return (SiteRest) super.fromModel(obj); + public SiteRest convert(org.dspace.content.Site obj) { + return super.convert(obj); } @Override @@ -36,7 +32,7 @@ public class SiteConverter } @Override - protected Class getModelClass() { + public Class getModelClass() { return Site.class; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionDefinitionConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionDefinitionConverter.java index cc9c8ddd73..e162ec25c3 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionDefinitionConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionDefinitionConverter.java @@ -13,7 +13,6 @@ import java.util.List; import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; -import org.apache.commons.lang3.NotImplementedException; import org.apache.logging.log4j.Logger; import org.dspace.app.rest.model.CollectionRest; import org.dspace.app.rest.model.SubmissionDefinitionRest; @@ -47,17 +46,17 @@ public class SubmissionDefinitionConverter implements DSpaceConverter panels = new LinkedList(); for (int idx = 0; idx < obj.getNumberOfSteps(); idx++) { SubmissionStepConfig step = obj.getStep(idx); - SubmissionSectionRest sp = panelConverter.convert(step); + SubmissionSectionRest sp = converter.toRest(step); panels.add(sp); } @@ -68,8 +67,8 @@ public class SubmissionDefinitionConverter implements DSpaceConverter collections = panelConverter.getSubmissionConfigReader() .getCollectionsBySubmissionConfig(context, obj.getSubmissionName()); - List collectionsRest = collections.stream().map( - (collection) -> collectionConverter.convert(collection)).collect(Collectors.toList()); + DSpaceConverter cc = converter.getConverter(Collection.class); + List collectionsRest = collections.stream().map(cc::convert).collect(Collectors.toList()); sd.setCollections(collectionsRest); } catch (SQLException | IllegalStateException | SubmissionConfigReaderException e) { log.error(e.getMessage(), e); @@ -79,7 +78,7 @@ public class SubmissionDefinitionConverter implements DSpaceConverter getModelClass() { + return SubmissionConfig.class; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionFormConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionFormConverter.java index 485d68f770..55ae27c7a5 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionFormConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionFormConverter.java @@ -11,7 +11,6 @@ import java.util.ArrayList; import java.util.LinkedList; import java.util.List; -import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.StringUtils; import org.dspace.app.rest.model.ScopeEnum; import org.dspace.app.rest.model.SubmissionFormFieldRest; @@ -51,7 +50,7 @@ public class SubmissionFormConverter implements DSpaceConverter getModelClass() { + return DCInputSet.class; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionSectionConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionSectionConverter.java index 43dd014d27..e8bd41923a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionSectionConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionSectionConverter.java @@ -30,7 +30,7 @@ public class SubmissionSectionConverter implements DSpaceConverter getModelClass() { + return SubmissionStepConfig.class; + } + public SubmissionConfigReader getSubmissionConfigReader() throws SubmissionConfigReaderException { if (submissionConfigReader == null) { submissionConfigReader = new SubmissionConfigReader(); } return submissionConfigReader; } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/WorkflowItemConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/WorkflowItemConverter.java index ece24ece35..84c527e054 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/WorkflowItemConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/WorkflowItemConverter.java @@ -29,15 +29,15 @@ public class WorkflowItemConverter } @Override - public WorkflowItemRest fromModel(XmlWorkflowItem obj) { + public WorkflowItemRest convert(XmlWorkflowItem obj) { WorkflowItemRest witem = new WorkflowItemRest(); fillFromModel(obj, witem); return witem; } @Override - public XmlWorkflowItem toModel(WorkflowItemRest obj) { - return null; + public Class getModelClass() { + return XmlWorkflowItem.class; } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/WorkspaceItemConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/WorkspaceItemConverter.java index 88ba5522af..e617f70362 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/WorkspaceItemConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/WorkspaceItemConverter.java @@ -28,18 +28,22 @@ public class WorkspaceItemConverter } @Override - public WorkspaceItemRest fromModel(org.dspace.content.WorkspaceItem obj) { + public WorkspaceItemRest convert(org.dspace.content.WorkspaceItem obj) { WorkspaceItemRest witem = new WorkspaceItemRest(); fillFromModel(obj, witem); return witem; } - @Override public org.dspace.content.WorkspaceItem toModel(WorkspaceItemRest obj) { return null; } + @Override + public Class getModelClass() { + return WorkspaceItem.class; + } + @Override public boolean supportsModel(IndexableObject object) { return object instanceof WorkspaceItem; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/link/DSpaceResourceHalLinkFactory.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/link/DSpaceResourceHalLinkFactory.java index a9fd316d75..4dba5aa318 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/link/DSpaceResourceHalLinkFactory.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/link/DSpaceResourceHalLinkFactory.java @@ -65,7 +65,14 @@ public class DSpaceResourceHalLinkFactory extends HalLinkFactory { } } - @LinkRest(linkClass = EPersonRest.class, name = "eperson", optional = true) + @LinkRest(linkClass = EPersonRest.class, name = "eperson", linkOptional = true) @JsonIgnore public EPersonRest getEPersonRest() { return ePersonRest; @@ -81,4 +81,4 @@ public class AuthenticationStatusRest extends BaseObjectRest { public void setOkay(boolean okay) { this.okay = okay; } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AuthorityEntryRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AuthorityEntryRest.java index 32215ca333..9fcc01d972 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AuthorityEntryRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AuthorityEntryRest.java @@ -17,7 +17,7 @@ import org.dspace.app.rest.RestResourceController; * * @author Andrea Bollini (andrea.bollini at 4science.it) */ -public class AuthorityEntryRest implements RestAddressableModel { +public class AuthorityEntryRest extends RestAddressableModel { public static final String NAME = "authorityEntry"; private String id; private String display; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AuthorityRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AuthorityRest.java index ddb327c741..c0bc7172c7 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AuthorityRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AuthorityRest.java @@ -15,8 +15,19 @@ import org.dspace.app.rest.RestResourceController; * @author Andrea Bollini (andrea.bollini at 4science.it) */ @LinksRest(links = { - @LinkRest(name = AuthorityRest.ENTRIES, linkClass = AuthorityEntryRest.class, method = "query", optional = true), - @LinkRest(name = AuthorityRest.ENTRY, linkClass = AuthorityEntryRest.class, method = "getResource", optional = true) + @LinkRest(name = AuthorityRest.ENTRIES, + linkClass = AuthorityEntryRest.class, + method = "query", + embedOptional = true, + linkOptional = true + ), + @LinkRest( + name = AuthorityRest.ENTRY, + linkClass = AuthorityEntryRest.class, + method = "getResource", + embedOptional = true, + linkOptional = true + ) }) public class AuthorityRest extends BaseObjectRest { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BaseObjectRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BaseObjectRest.java index 0d82fffd54..6afc04ecd1 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BaseObjectRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BaseObjectRest.java @@ -21,7 +21,7 @@ import org.springframework.hateoas.Identifiable; * @param the class of the resource identifier * @author Andrea Bollini (andrea.bollini at 4science.it) */ -public abstract class BaseObjectRest implements Identifiable, RestAddressableModel { +public abstract class BaseObjectRest extends RestAddressableModel implements Identifiable { protected T id; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BrowseIndexRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BrowseIndexRest.java index 0398b6ab86..76fbcbea25 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BrowseIndexRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BrowseIndexRest.java @@ -19,9 +19,19 @@ import org.dspace.app.rest.RestResourceController; * @author Andrea Bollini (andrea.bollini at 4science.it) */ @LinksRest(links = { - @LinkRest(name = BrowseIndexRest.ITEMS, linkClass = ItemRest.class, method = "listBrowseItems"), - @LinkRest(name = BrowseIndexRest.ENTRIES, linkClass = BrowseEntryRest.class, method = "listBrowseEntries", - optional = true) + @LinkRest( + name = BrowseIndexRest.ITEMS, + linkClass = ItemRest.class, + method = "listBrowseItems", + embedOptional = true + ), + @LinkRest( + name = BrowseIndexRest.ENTRIES, + linkClass = BrowseEntryRest.class, + method = "listBrowseEntries", + embedOptional = true, + linkOptional = true + ) }) public class BrowseIndexRest extends BaseObjectRest { private static final long serialVersionUID = -4870333170249999559L; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/CollectionRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/CollectionRest.java index eca097952d..be77497516 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/CollectionRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/CollectionRest.java @@ -18,8 +18,13 @@ import com.fasterxml.jackson.annotation.JsonProperty; * @author Andrea Bollini (andrea.bollini at 4science.it) */ @LinksRest(links = { - @LinkRest(name = CollectionRest.LICENSE, linkClass = LicenseRest.class, method = "getLicenseCollection", optional - = true) + @LinkRest( + name = CollectionRest.LICENSE, + linkClass = LicenseRest.class, + method = "getLicenseCollection", + embedOptional = true, + linkOptional = true + ) }) public class CollectionRest extends DSpaceObjectRest { public static final String NAME = "collection"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/HarvestedCollectionRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/HarvestedCollectionRest.java index 0b6049e4e1..7fab11e806 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/HarvestedCollectionRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/HarvestedCollectionRest.java @@ -156,7 +156,7 @@ public class HarvestedCollectionRest extends BaseObjectRest { this.lastHarvested = lastHarvested; } - @LinkRest(linkClass = HarvesterMetadataRest.class, name = "harvestermetadata", optional = true) + @LinkRest(linkClass = HarvesterMetadataRest.class, name = "harvestermetadata", linkOptional = true) @JsonIgnore public HarvesterMetadataRest getMetadataConfigs() { return metadata_configs; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/LinkRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/LinkRest.java index e8f5b4a781..5d703197ed 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/LinkRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/LinkRest.java @@ -28,5 +28,7 @@ public @interface LinkRest { Class linkClass(); - boolean optional() default false; + boolean embedOptional() default false; + + boolean linkOptional() default false; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/LinksRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/LinksRest.java index ef28edcc84..e9d5bd53e4 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/LinksRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/LinksRest.java @@ -22,5 +22,5 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Documented public @interface LinksRest { - LinkRest[] links(); + LinkRest[] links() default {}; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MappedCollectionRestWrapper.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MappedCollectionRestWrapper.java index d9476dbf1e..328f5d1712 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MappedCollectionRestWrapper.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MappedCollectionRestWrapper.java @@ -16,7 +16,7 @@ import org.dspace.content.Item; /** * The REST object that will define a list of CollectionRest objects to be returned by the REST api */ -public class MappedCollectionRestWrapper implements RestAddressableModel { +public class MappedCollectionRestWrapper extends RestAddressableModel { @JsonIgnore private List mappedCollectionRestList; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MappedItemRestWrapper.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MappedItemRestWrapper.java index 9e0a106551..460c95f149 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MappedItemRestWrapper.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MappedItemRestWrapper.java @@ -16,7 +16,7 @@ import org.dspace.app.rest.MappedItemRestController; /** * The REST object that will define a list of ItemRest objects to be returned by the REST api */ -public class MappedItemRestWrapper implements RestAddressableModel { +public class MappedItemRestWrapper extends RestAddressableModel { @JsonIgnore private List mappedItemRestList; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RelationshipTypeRestWrapper.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RelationshipTypeRestWrapper.java index 4a3ffbb6ab..a86ee53f05 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RelationshipTypeRestWrapper.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RelationshipTypeRestWrapper.java @@ -18,7 +18,7 @@ import org.dspace.app.rest.RelationshipTypeRestController; * RelationshipTypeRest objects * The other methods are generic getters and setters */ -public class RelationshipTypeRestWrapper implements RestAddressableModel { +public class RelationshipTypeRestWrapper extends RestAddressableModel { @JsonIgnore private List relationshipTypeRestList; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RestAddressableModel.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RestAddressableModel.java index 07856f2cb8..e9ae3bd545 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RestAddressableModel.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RestAddressableModel.java @@ -8,17 +8,29 @@ package org.dspace.app.rest.model; import com.fasterxml.jackson.annotation.JsonIgnore; +import org.dspace.app.rest.projection.Projection; /** * A directly addressable REST resource * * @author Andrea Bollini (andrea.bollini at 4science.it) */ -public interface RestAddressableModel extends RestModel { +public abstract class RestAddressableModel implements RestModel { + + private Projection projection = Projection.DEFAULT; @JsonIgnore - public String getCategory(); + public abstract String getCategory(); @JsonIgnore - public Class getController(); + public abstract Class getController(); + + @JsonIgnore + public Projection getProjection() { + return projection; + } + + public void setProjection(Projection projection) { + this.projection = projection; + } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RootRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RootRest.java index 397fdc9be0..bb20ef9e43 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RootRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RootRest.java @@ -14,7 +14,7 @@ import org.dspace.app.rest.RootRestResourceController; /** * The purpose of this class is to show the representation of information on the home/root page of the REST API */ -public class RootRest implements RestAddressableModel { +public class RootRest extends RestAddressableModel { public static final String NAME = "root"; public static final String CATEGORY = RestModel.ROOT; private String dspaceURL; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchFacetEntryRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchFacetEntryRest.java index e4d73e6f9d..513b4ad54a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchFacetEntryRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchFacetEntryRest.java @@ -18,7 +18,7 @@ import org.dspace.discovery.configuration.DiscoverySearchFilterFacet; /** * This class' purpose is to create a container for the information used in the SearchFacetEntryResource */ -public class SearchFacetEntryRest implements RestAddressableModel { +public class SearchFacetEntryRest extends RestAddressableModel { public static final String NAME = "discover"; public static final String CATEGORY = RestModel.DISCOVER; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchFacetValueRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchFacetValueRest.java index abdf3ade03..3a04a207fc 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchFacetValueRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchFacetValueRest.java @@ -13,7 +13,7 @@ import org.dspace.app.rest.DiscoveryRestController; /** * This class' purpose is to create a container for the information used in the SearchFacetValueResource */ -public class SearchFacetValueRest implements RestAddressableModel { +public class SearchFacetValueRest extends RestAddressableModel { public static final String NAME = "discover"; public static final String CATEGORY = RestModel.DISCOVER; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchResultEntryRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchResultEntryRest.java index 59826816e0..60bb5b3db4 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchResultEntryRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchResultEntryRest.java @@ -18,7 +18,7 @@ import org.dspace.app.rest.DiscoveryRestController; /** * This class' purpose is to create a container for the information in the SearchResultEntryResource */ -public class SearchResultEntryRest implements RestAddressableModel { +public class SearchResultEntryRest extends RestAddressableModel { public static final String NAME = "discover"; public static final String CATEGORY = RestModel.DISCOVER; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/AuthenticationStatusResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/AuthenticationStatusResource.java index 5d64200fc2..8abb35e97a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/AuthenticationStatusResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/AuthenticationStatusResource.java @@ -19,7 +19,7 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(AuthenticationStatusRest.NAME) public class AuthenticationStatusResource extends DSpaceResource { - public AuthenticationStatusResource(AuthenticationStatusRest data, Utils utils, String... rels) { - super(data, utils, rels); + public AuthenticationStatusResource(AuthenticationStatusRest data, Utils utils) { + super(data, utils); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/AuthnResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/AuthnResource.java index 9b255b6648..5688919b82 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/AuthnResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/AuthnResource.java @@ -7,8 +7,6 @@ */ package org.dspace.app.rest.model.hateoas; -import java.sql.SQLException; - import org.dspace.app.rest.model.AuthnRest; import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource; import org.dspace.app.rest.utils.Utils; @@ -22,7 +20,7 @@ import org.dspace.app.rest.utils.Utils; @RelNameDSpaceResource(AuthnRest.NAME) public class AuthnResource extends DSpaceResource { - public AuthnResource(AuthnRest data, Utils utils, String... rels) throws SQLException { - super(data, utils, rels); + public AuthnResource(AuthnRest data, Utils utils) { + super(data, utils); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/AuthorityResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/AuthorityResource.java index cda88f70a1..0e153097b4 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/AuthorityResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/AuthorityResource.java @@ -19,8 +19,8 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(AuthorityRest.NAME) public class AuthorityResource extends DSpaceResource { - public AuthorityResource(AuthorityRest sd, Utils utils, String... rels) { - super(sd, utils, rels); + public AuthorityResource(AuthorityRest sd, Utils utils) { + super(sd, utils); if (sd.hasIdentifier()) { add(utils.linkToSubResource(sd, AuthorityRest.ENTRY)); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/BitstreamFormatResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/BitstreamFormatResource.java index a291d13350..1b83479998 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/BitstreamFormatResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/BitstreamFormatResource.java @@ -19,7 +19,7 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(BitstreamFormatRest.NAME) public class BitstreamFormatResource extends DSpaceResource { - public BitstreamFormatResource(BitstreamFormatRest bf, Utils utils, String... rels) { - super(bf, utils, rels); + public BitstreamFormatResource(BitstreamFormatRest bf, Utils utils) { + super(bf, utils); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/BitstreamResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/BitstreamResource.java index 91ba363c6c..0ed14545c1 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/BitstreamResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/BitstreamResource.java @@ -19,8 +19,8 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(BitstreamRest.NAME) public class BitstreamResource extends DSpaceResource { - public BitstreamResource(BitstreamRest bs, Utils utils, String... rels) { - super(bs, utils, rels); + public BitstreamResource(BitstreamRest bs, Utils utils) { + super(bs, utils); add(utils.linkToSubResource(bs, "content")); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/BrowseIndexResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/BrowseIndexResource.java index 407c21a5b9..f6c821595f 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/BrowseIndexResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/BrowseIndexResource.java @@ -19,8 +19,8 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(BrowseIndexRest.NAME) public class BrowseIndexResource extends DSpaceResource { - public BrowseIndexResource(BrowseIndexRest bix, Utils utils, String... rels) { - super(bix, utils, rels); + public BrowseIndexResource(BrowseIndexRest bix, Utils utils) { + super(bix, utils); // TODO: the following code will force the embedding of items and // entries in the browseIndex we need to find a way to populate the rels // array from the request/projection right now it is always null diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/ClaimedTaskResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/ClaimedTaskResource.java index 688965446c..96a2759646 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/ClaimedTaskResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/ClaimedTaskResource.java @@ -19,7 +19,7 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(ClaimedTaskRest.NAME) public class ClaimedTaskResource extends DSpaceResource { - public ClaimedTaskResource(ClaimedTaskRest witem, Utils utils, String... rels) { - super(witem, utils, rels); + public ClaimedTaskResource(ClaimedTaskRest witem, Utils utils) { + super(witem, utils); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/CollectionResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/CollectionResource.java index 6fd98facbd..db2be4739a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/CollectionResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/CollectionResource.java @@ -19,8 +19,8 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(CollectionRest.NAME) public class CollectionResource extends DSpaceResource { - public CollectionResource(CollectionRest collection, Utils utils, String... rels) { - super(collection, utils, rels); + public CollectionResource(CollectionRest collection, Utils utils) { + super(collection, utils); add(utils.linkToSubResource(collection, CollectionRest.LICENSE)); add(utils.linkToSubResource(collection, CollectionRest.HARVEST)); add(utils.linkToSubResource(collection, "mappedItems")); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/CommunityResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/CommunityResource.java index 138f123fea..a774074644 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/CommunityResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/CommunityResource.java @@ -20,7 +20,7 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(CommunityRest.NAME) public class CommunityResource extends DSpaceResource { - public CommunityResource(CommunityRest community, Utils utils, String... rels) { - super(community, utils, rels); + public CommunityResource(CommunityRest community, Utils utils) { + super(community, utils); } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/DSpaceResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/DSpaceResource.java index ef06f1360f..dd8fae9b95 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/DSpaceResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/DSpaceResource.java @@ -7,29 +7,9 @@ */ package org.dspace.app.rest.model.hateoas; -import java.beans.IntrospectionException; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.io.Serializable; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.List; - import com.fasterxml.jackson.annotation.JsonUnwrapped; -import org.apache.commons.lang3.StringUtils; -import org.dspace.app.rest.model.BaseObjectRest; -import org.dspace.app.rest.model.LinkRest; -import org.dspace.app.rest.model.LinksRest; import org.dspace.app.rest.model.RestAddressableModel; -import org.dspace.app.rest.repository.DSpaceRestRepository; -import org.dspace.app.rest.repository.LinkRestRepository; import org.dspace.app.rest.utils.Utils; -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.PageRequest; -import org.springframework.hateoas.Link; /** * A base class for DSpace Rest HAL Resource. The HAL Resource wraps the REST @@ -39,169 +19,14 @@ import org.springframework.hateoas.Link; * * @author Andrea Bollini (andrea.bollini at 4science.it) */ -public abstract class DSpaceResource extends HALResource { +public class DSpaceResource extends HALResource { - public DSpaceResource(T data, Utils utils, String... rels) { + public DSpaceResource(T data, Utils utils) { super(data); - - if (data != null) { - try { - LinksRest links = data.getClass().getDeclaredAnnotation(LinksRest.class); - if (links != null && rels != null) { - List relsList = Arrays.asList(rels); - for (LinkRest linkAnnotation : links.links()) { - if (!relsList.contains(linkAnnotation.name())) { - continue; - } - String name = linkAnnotation.name(); - Link linkToSubResource = utils.linkToSubResource(data, name); - String apiCategory = data.getCategory(); - String model = data.getType(); - LinkRestRepository linkRepository = utils - .getLinkResourceRepository(apiCategory, model, linkAnnotation.name()); - - if (!linkRepository.isEmbeddableRelation(data, linkAnnotation.name())) { - continue; - } - try { - Method[] methods = linkRepository.getClass().getMethods(); - boolean found = false; - for (Method m : methods) { - if (StringUtils.equals(m.getName(), linkAnnotation.method())) { - // TODO add support for single linked object other than for collections - Page pageResult = (Page) m - .invoke(linkRepository, null, ((BaseObjectRest) data).getId(), null, null); - EmbeddedPage ep = new EmbeddedPage(linkToSubResource.getHref(), pageResult, - null, name); - embedded.put(name, ep); - found = true; - } - } - // TODO custom exception - if (!found) { - throw new RuntimeException( - "Method for relation " + linkAnnotation.name() + " not found: " + linkAnnotation - .method()); - } - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - } - - for (PropertyDescriptor pd : Introspector.getBeanInfo(data.getClass()).getPropertyDescriptors()) { - Method readMethod = pd.getReadMethod(); - String name = pd.getName(); - if (readMethod != null && !"class".equals(name)) { - LinkRest linkAnnotation = AnnotationUtils.findAnnotation(readMethod, LinkRest.class); - - if (linkAnnotation != null) { - if (StringUtils.isNotBlank(linkAnnotation.name())) { - name = linkAnnotation.name(); - } - Link linkToSubResource = utils.linkToSubResource(data, name); - // no method is specified to retrieve the linked object(s) so check if it is already here - if (StringUtils.isBlank(linkAnnotation.method())) { - Object linkedObject = readMethod.invoke(data); - Object wrapObject = linkedObject; - if (linkedObject instanceof RestAddressableModel) { - RestAddressableModel linkedRM = (RestAddressableModel) linkedObject; - wrapObject = utils.getResourceRepository(linkedRM.getCategory(), linkedRM.getType()) - .wrapResource(linkedRM); - - } else { - if (linkedObject instanceof List) { - List linkedRMList = (List) - linkedObject; - if (linkedRMList.size() > 0) { - - DSpaceRestRepository resourceRepository = utils - .getResourceRepository(linkedRMList.get(0).getCategory(), - linkedRMList.get(0).getType()); - // force pagination also of embedded resource - // This will force pagination with size 20 for embedded collections as well - int pageSize = 20; - PageImpl page = new PageImpl( - linkedRMList.subList(0, - linkedRMList - .size() > pageSize ? pageSize : linkedRMList - .size()), - new PageRequest(0, pageSize), linkedRMList.size()); -// PageImpl page = new PageImpl(linkedRMList); - wrapObject = new EmbeddedPage(linkToSubResource.getHref(), - page.map(resourceRepository::wrapResource), - linkedRMList, name); - } else { - PageImpl page = new PageImpl(linkedRMList); - wrapObject = new EmbeddedPage(linkToSubResource.getHref(), page, - linkedRMList, name); - } - } - } - - embedded.put(name, wrapObject); - } else { - // call the link repository - try { - String apiCategory = data.getCategory(); - String model = data.getType(); - LinkRestRepository linkRepository = utils - .getLinkResourceRepository(apiCategory, model, linkAnnotation.name()); - Method[] methods = linkRepository.getClass().getMethods(); - boolean found = false; - for (Method m : methods) { - if (StringUtils.equals(m.getName(), linkAnnotation.method())) { - if (Page.class.isAssignableFrom(m.getReturnType())) { - Page pageResult = (Page) m - .invoke(linkRepository, null, ((BaseObjectRest) data).getId(), null, - null); - EmbeddedPage ep = new EmbeddedPage(linkToSubResource.getHref(), - pageResult, null, name); - embedded.put(name, ep); - } else { - RestAddressableModel object = (RestAddressableModel) m - .invoke(linkRepository, null, ((BaseObjectRest) data).getId(), null, - null); - HALResource ep = linkRepository - .wrapResource(object, linkToSubResource.getHref()); - embedded.put(name, ep); - } - - found = true; - } - } - // TODO custom exception - if (!found) { - throw new RuntimeException("Method for relation " + linkAnnotation - .name() + " not found: " + linkAnnotation.method()); - } - } catch (IllegalAccessException | IllegalArgumentException | - InvocationTargetException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - } else if (RestAddressableModel.class.isAssignableFrom(readMethod.getReturnType())) { - RestAddressableModel linkedObject = (RestAddressableModel) readMethod.invoke(data); - if (linkedObject != null) { - embedded.put(name, - utils.getResourceRepository(linkedObject.getCategory(), - linkedObject.getType()) - .wrapResource(linkedObject)); - } else { - embedded.put(name, null); - } - } - } - } - } catch (IntrospectionException | IllegalArgumentException | IllegalAccessException - | InvocationTargetException e) { - throw new RuntimeException(e.getMessage(), e); - } - } + utils.embedMethodLevelRels(this); } - //Trick to make Java Understand that our content extends RestModel + //Trick to make Java understand that our content extends RestAddressableModel @JsonUnwrapped @Override public T getContent() { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/EPersonResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/EPersonResource.java index bc738d4482..e0e89578ce 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/EPersonResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/EPersonResource.java @@ -19,7 +19,7 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(EPersonRest.NAME) public class EPersonResource extends DSpaceResource { - public EPersonResource(EPersonRest eperson, Utils utils, String... rels) { - super(eperson, utils, rels); + public EPersonResource(EPersonRest eperson, Utils utils) { + super(eperson, utils); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/EntityTypeResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/EntityTypeResource.java index 9dae4eee15..e62c67c11f 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/EntityTypeResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/EntityTypeResource.java @@ -17,7 +17,7 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(EntityTypeRest.NAME) public class EntityTypeResource extends DSpaceResource { - public EntityTypeResource(EntityTypeRest data, Utils utils, String... rels) { - super(data, utils, rels); + public EntityTypeResource(EntityTypeRest data, Utils utils) { + super(data, utils); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/GroupResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/GroupResource.java index f85905c611..51bc42dd76 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/GroupResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/GroupResource.java @@ -19,7 +19,7 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(GroupRest.NAME) public class GroupResource extends DSpaceResource { - public GroupResource(GroupRest group, Utils utils, String... rels) { - super(group, utils, rels); + public GroupResource(GroupRest group, Utils utils) { + super(group, utils); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/HALResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/HALResource.java index 207aa2713b..eb10b13ac2 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/HALResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/HALResource.java @@ -7,13 +7,13 @@ */ package org.dspace.app.rest.model.hateoas; -import java.util.Collection; import java.util.HashMap; import java.util.Map; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonUnwrapped; +import org.springframework.hateoas.Link; import org.springframework.hateoas.Resource; /** @@ -37,18 +37,18 @@ public abstract class HALResource extends Resource { return embedded; } - public void embedResource(String relationship, HALResource resource) { - embedded.put(relationship, resource); - } - public void embedResource(String relationship, EmbeddedPage embeddedPage) { - embedded.put(relationship, embeddedPage); - } - public void embedResource(String relationship, Collection resource) { - embedded.put(relationship, resource); + public void embedResource(String rel, Object object) { + embedded.put(rel, object); } public void setPageHeader(EmbeddedPageHeader page) { this.pageHeader = page; } -} \ No newline at end of file + @Override + public void add(Link link) { + if (!hasLink(link.getRel())) { + super.add(link); + } + } +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/HarvestedCollectionResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/HarvestedCollectionResource.java index 56abe66e04..aad3d2750a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/HarvestedCollectionResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/HarvestedCollectionResource.java @@ -10,7 +10,6 @@ package org.dspace.app.rest.model.hateoas; import org.dspace.app.rest.model.HarvestedCollectionRest; import org.dspace.app.rest.model.HarvesterMetadataRest; import org.dspace.app.rest.utils.Utils; -import org.springframework.beans.factory.annotation.Autowired; /** * HarvestedCollection Rest HAL Resource. The HAL Resource wraps the REST Resource @@ -20,11 +19,11 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class HarvestedCollectionResource extends HALResource { - @Autowired private Utils utils; - public HarvestedCollectionResource(HarvestedCollectionRest data) { + public HarvestedCollectionResource(HarvestedCollectionRest data, Utils utils) { super(data); + this.utils = utils; embedResource("harvestermetadata", data.getMetadataConfigs()); } @@ -36,4 +35,4 @@ public class HarvestedCollectionResource extends HALResource { - public HarvesterMetadataResource(HarvesterMetadataRest data, Utils utils, String... rels) { - super(data, utils, rels); + public HarvesterMetadataResource(HarvesterMetadataRest data, Utils utils) { + super(data, utils); } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/ItemResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/ItemResource.java index f47e749113..e7d8294d0d 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/ItemResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/ItemResource.java @@ -19,8 +19,8 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(ItemRest.NAME) public class ItemResource extends DSpaceResource { - public ItemResource(ItemRest item, Utils utils, String... rels) { - super(item, utils, rels); + public ItemResource(ItemRest item, Utils utils) { + super(item, utils); add(utils.linkToSubResource(item, "mappedCollections")); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/MappedCollectionResourceWrapper.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/MappedCollectionResourceWrapper.java index 8901583170..6764564225 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/MappedCollectionResourceWrapper.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/MappedCollectionResourceWrapper.java @@ -14,7 +14,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import org.dspace.app.rest.model.CollectionRest; import org.dspace.app.rest.model.MappedCollectionRestWrapper; import org.dspace.app.rest.utils.Utils; -import org.springframework.data.domain.Pageable; /** * This class will act as a HALResource object for the MappedCollectionRestWrapper data object and will transform @@ -25,25 +24,15 @@ public class MappedCollectionResourceWrapper extends HALResource collectionResources = new LinkedList<>(); - public MappedCollectionResourceWrapper(MappedCollectionRestWrapper content, Utils utils, Pageable pageable, - String... rels) { + public MappedCollectionResourceWrapper(MappedCollectionRestWrapper content, Utils utils) { super(content); - addEmbeds(content, utils, pageable); + addEmbeds(content, utils); } - private void addEmbeds(final MappedCollectionRestWrapper data, final Utils utils, Pageable pageable) { - + private void addEmbeds(final MappedCollectionRestWrapper data, final Utils utils) { for (CollectionRest collectionRest : data.getMappedCollectionRestList()) { - collectionResources.add(new CollectionResource(collectionRest, utils)); } - - embedResource("mappedCollections", collectionResources); - } - - public List getCollectionResources() { - return collectionResources; - } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/MappedItemResourceWrapper.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/MappedItemResourceWrapper.java index aad7233d84..484a68a38e 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/MappedItemResourceWrapper.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/MappedItemResourceWrapper.java @@ -30,7 +30,7 @@ public class MappedItemResourceWrapper extends HALResource { - public MetadataFieldResource(MetadataFieldRest ms, Utils utils, String... rels) { - super(ms, utils, rels); + public MetadataFieldResource(MetadataFieldRest ms, Utils utils) { + super(ms, utils); } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/MetadataSchemaResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/MetadataSchemaResource.java index a7ebe42ad7..3db8a233f8 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/MetadataSchemaResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/MetadataSchemaResource.java @@ -19,7 +19,7 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(MetadataSchemaRest.NAME) public class MetadataSchemaResource extends DSpaceResource { - public MetadataSchemaResource(MetadataSchemaRest ms, Utils utils, String... rels) { - super(ms, utils, rels); + public MetadataSchemaResource(MetadataSchemaRest ms, Utils utils) { + super(ms, utils); } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/PoolTaskResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/PoolTaskResource.java index 0c0d06b400..021501f8ed 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/PoolTaskResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/PoolTaskResource.java @@ -19,7 +19,7 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(PoolTaskRest.NAME) public class PoolTaskResource extends DSpaceResource { - public PoolTaskResource(PoolTaskRest witem, Utils utils, String... rels) { - super(witem, utils, rels); + public PoolTaskResource(PoolTaskRest witem, Utils utils) { + super(witem, utils); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/RelationshipResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/RelationshipResource.java index 8bebdac35d..f35316f3ba 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/RelationshipResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/RelationshipResource.java @@ -17,8 +17,8 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(RelationshipRest.NAME) public class RelationshipResource extends DSpaceResource { - public RelationshipResource(RelationshipRest data, Utils utils, String... rels) { - super(data, utils, rels); + public RelationshipResource(RelationshipRest data, Utils utils) { + super(data, utils); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/RelationshipTypeResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/RelationshipTypeResource.java index 8230eab549..8347554fa2 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/RelationshipTypeResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/RelationshipTypeResource.java @@ -17,7 +17,7 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(RelationshipTypeRest.NAME) public class RelationshipTypeResource extends DSpaceResource { - public RelationshipTypeResource(RelationshipTypeRest data, Utils utils, String... rels) { - super(data, utils, rels); + public RelationshipTypeResource(RelationshipTypeRest data, Utils utils) { + super(data, utils); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/RelationshipTypeResourceWrapper.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/RelationshipTypeResourceWrapper.java index 6045946634..57f722d3ca 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/RelationshipTypeResourceWrapper.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/RelationshipTypeResourceWrapper.java @@ -24,7 +24,6 @@ public class RelationshipTypeResourceWrapper extends HALResource { - public ResourcePolicyResource(ResourcePolicyRest eperson, Utils utils, String... rels) { - super(eperson, utils, rels); + public ResourcePolicyResource(ResourcePolicyRest eperson, Utils utils) { + super(eperson, utils); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SearchEventResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SearchEventResource.java index 626658bf57..0ef78cf279 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SearchEventResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SearchEventResource.java @@ -13,7 +13,7 @@ import org.dspace.app.rest.utils.Utils; @RelNameDSpaceResource(SearchEventRest.NAME) public class SearchEventResource extends DSpaceResource { - public SearchEventResource(SearchEventRest data, Utils utils, String... rels) { - super(data, utils, rels); + public SearchEventResource(SearchEventRest data, Utils utils) { + super(data, utils); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SearchResultEntryResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SearchResultEntryResource.java index 75dfabdd2b..550a97a730 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SearchResultEntryResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SearchResultEntryResource.java @@ -9,7 +9,6 @@ package org.dspace.app.rest.model.hateoas; import org.dspace.app.rest.model.RestAddressableModel; import org.dspace.app.rest.model.SearchResultEntryRest; -import org.dspace.app.rest.repository.DSpaceRestRepository; import org.dspace.app.rest.utils.Utils; /** @@ -30,9 +29,7 @@ public class SearchResultEntryResource extends HALResource { - public SiteResource(SiteRest site, Utils utils, String... rels) { - super(site, utils, rels); + public SiteResource(SiteRest site, Utils utils) { + super(site, utils); } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionDefinitionResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionDefinitionResource.java index a773597f85..6cf425203b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionDefinitionResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionDefinitionResource.java @@ -19,7 +19,7 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(SubmissionDefinitionRest.NAME) public class SubmissionDefinitionResource extends DSpaceResource { - public SubmissionDefinitionResource(SubmissionDefinitionRest sd, Utils utils, String... rels) { - super(sd, utils, rels); + public SubmissionDefinitionResource(SubmissionDefinitionRest sd, Utils utils) { + super(sd, utils); } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionFormResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionFormResource.java index b615793451..466113d375 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionFormResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionFormResource.java @@ -19,7 +19,7 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(SubmissionFormRest.NAME) public class SubmissionFormResource extends DSpaceResource { - public SubmissionFormResource(SubmissionFormRest sd, Utils utils, String... rels) { - super(sd, utils, rels); + public SubmissionFormResource(SubmissionFormRest sd, Utils utils) { + super(sd, utils); } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionSectionResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionSectionResource.java index e04314d2e1..84338f6472 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionSectionResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionSectionResource.java @@ -20,7 +20,7 @@ import org.dspace.app.rest.utils.Utils; @RelNameDSpaceResource(SubmissionSectionRest.NAME) public class SubmissionSectionResource extends DSpaceResource { - public SubmissionSectionResource(SubmissionSectionRest sd, Utils utils, String... rels) { - super(sd, utils, rels); + public SubmissionSectionResource(SubmissionSectionRest sd, Utils utils) { + super(sd, utils); } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionUploadResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionUploadResource.java index a3f9edaa5e..2c3af6fd43 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionUploadResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionUploadResource.java @@ -19,7 +19,7 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(SubmissionUploadRest.NAME) public class SubmissionUploadResource extends DSpaceResource { - public SubmissionUploadResource(SubmissionUploadRest sd, Utils utils, String... rels) { - super(sd, utils, rels); + public SubmissionUploadResource(SubmissionUploadRest sd, Utils utils) { + super(sd, utils); } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/ViewEventResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/ViewEventResource.java index b25b112b3f..8fbacac28a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/ViewEventResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/ViewEventResource.java @@ -13,7 +13,7 @@ import org.dspace.app.rest.utils.Utils; @RelNameDSpaceResource(ViewEventRest.NAME) public class ViewEventResource extends DSpaceResource { - public ViewEventResource(ViewEventRest data, Utils utils, String... rels) { - super(data, utils, rels); + public ViewEventResource(ViewEventRest data, Utils utils) { + super(data, utils); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/WorkflowItemResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/WorkflowItemResource.java index 99a9533cd3..d41e00d3f4 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/WorkflowItemResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/WorkflowItemResource.java @@ -19,7 +19,7 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(WorkflowItemRest.NAME) public class WorkflowItemResource extends DSpaceResource { - public WorkflowItemResource(WorkflowItemRest witem, Utils utils, String... rels) { - super(witem, utils, rels); + public WorkflowItemResource(WorkflowItemRest witem, Utils utils) { + super(witem, utils); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/WorkspaceItemResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/WorkspaceItemResource.java index 5ac0d605eb..7a3cff8cfb 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/WorkspaceItemResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/WorkspaceItemResource.java @@ -19,7 +19,7 @@ import org.dspace.app.rest.utils.Utils; */ @RelNameDSpaceResource(WorkspaceItemRest.NAME) public class WorkspaceItemResource extends DSpaceResource { - public WorkspaceItemResource(WorkspaceItemRest witem, Utils utils, String... rels) { - super(witem, utils, rels); + public WorkspaceItemResource(WorkspaceItemRest witem, Utils utils) { + super(witem, utils); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/AbstractProjection.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/AbstractProjection.java new file mode 100644 index 0000000000..783c70fb86 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/AbstractProjection.java @@ -0,0 +1,40 @@ +/** + * 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.projection; + +import org.dspace.app.rest.model.LinkRest; +import org.dspace.app.rest.model.RestModel; +import org.dspace.app.rest.model.hateoas.HALResource; + +public abstract class AbstractProjection implements Projection { + + @Override + public T transformModel(T modelObject) { + return modelObject; + } + + @Override + public T transformRest(T restObject) { + return restObject; + } + + @Override + public T transformResource(T halResource) { + return halResource; + } + + @Override + public boolean allowOptionalEmbed(HALResource halResource, LinkRest linkRest) { + return true; + } + + @Override + public boolean allowOptionalLink(HALResource halResource, LinkRest linkRest) { + return true; + } +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/DefaultProjection.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/DefaultProjection.java new file mode 100644 index 0000000000..f4d0f267a0 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/DefaultProjection.java @@ -0,0 +1,18 @@ +/** + * 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.projection; + +public class DefaultProjection extends AbstractProjection { + + public final static String NAME = "default"; + + @Override + public String getName() { + return NAME; + } +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/ListProjection.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/ListProjection.java new file mode 100644 index 0000000000..54ad4c8bf5 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/ListProjection.java @@ -0,0 +1,28 @@ +/** + * 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.projection; + +import org.dspace.app.rest.model.LinkRest; +import org.dspace.app.rest.model.hateoas.HALResource; +import org.springframework.stereotype.Component; + +@Component +public class ListProjection extends AbstractProjection { + + public final static String NAME = "list"; + + @Override + public String getName() { + return NAME; + } + + @Override + public boolean allowOptionalEmbed(HALResource halResource, LinkRest linkRest) { + return false; + } +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/Projection.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/Projection.java new file mode 100644 index 0000000000..7a3c2abf7a --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/Projection.java @@ -0,0 +1,59 @@ +/** + * 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.projection; + +import org.dspace.app.rest.model.LinkRest; +import org.dspace.app.rest.model.RestModel; +import org.dspace.app.rest.model.hateoas.HALResource; + +public interface Projection { + + /** + * The default projection. + */ + Projection DEFAULT = new DefaultProjection(); + + /** + * Gets the projection name. + * + * @return the name, which is a unique alphanumeric string. + */ + String getName(); + + T transformModel(T modelObject); + + T transformRest(T restObject); + + T transformResource(T halResource); + + /** + * Tells whether this projection permits the embedding of a particular optionally-embeddable related resource. + * + * Optionally-embeddable related resources, discovered through {@link LinkRest} annotations, are normally + * automatically embedded. This method gives the projection an opportunity to opt out of some or all such embeds, + * by returning {@code false}. + * + * @param halResource the resource from which the embed may or may not be made. + * @param linkRest the LinkRest annotation through which the related resource was discovered on the rest object. + * @return true if allowed, false otherwise. + */ + boolean allowOptionalEmbed(HALResource halResource, LinkRest linkRest); + + /** + * Tells whether this projection permits the linking of a particular optionally-linkable related resource. + * + * Optionally-linkable related resources, discovered through {@link LinkRest} annotations, are normally + * automatically linked. This method gives the projection an opportunity to opt out of some or all such links, + * by returning {@code false}. + * + * @param halResource the resource from which the embed may or may not be made. + * @param linkRest the LinkRest annotation through which the related resource was discovered on the rest object. + * @return true if allowed, false otherwise. + */ + boolean allowOptionalLink(HALResource halResource, LinkRest linkRest); +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityEntryLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityEntryLinkRepository.java index e7f3f2f017..953eb5b21f 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityEntryLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityEntryLinkRepository.java @@ -16,8 +16,6 @@ import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; import org.dspace.app.rest.model.AuthorityEntryRest; import org.dspace.app.rest.model.AuthorityRest; -import org.dspace.app.rest.model.hateoas.AuthorityEntryResource; -import org.dspace.app.rest.model.hateoas.HALResource; import org.dspace.app.rest.utils.AuthorityUtils; import org.dspace.content.Collection; import org.dspace.content.authority.Choice; @@ -39,7 +37,7 @@ import org.springframework.stereotype.Component; */ @Component(AuthorityRest.CATEGORY + "." + AuthorityRest.NAME + "." + AuthorityRest.ENTRIES) public class AuthorityEntryLinkRepository extends AbstractDSpaceRestRepository - implements LinkRestRepository { + implements LinkRestRepository { @Autowired private ChoiceAuthorityService cas; @@ -50,11 +48,6 @@ public class AuthorityEntryLinkRepository extends AbstractDSpaceRestRepository @Autowired private AuthorityUtils authorityUtils; - @Override - public HALResource wrapResource(AuthorityEntryRest model, String... rels) { - return new AuthorityEntryResource(model); - } - @PreAuthorize("hasAuthority('AUTHENTICATED')") public Page query(HttpServletRequest request, String name, Pageable pageable, String projection) { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityEntryValueLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityEntryValueLinkRepository.java index 4409f46c76..7d2df54164 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityEntryValueLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityEntryValueLinkRepository.java @@ -11,8 +11,6 @@ import javax.servlet.http.HttpServletRequest; import org.dspace.app.rest.model.AuthorityEntryRest; import org.dspace.app.rest.model.AuthorityRest; -import org.dspace.app.rest.model.hateoas.AuthorityEntryResource; -import org.dspace.app.rest.model.hateoas.HALResource; import org.dspace.app.rest.utils.AuthorityUtils; import org.dspace.content.authority.Choice; import org.dspace.content.authority.ChoiceAuthority; @@ -31,7 +29,7 @@ import org.springframework.stereotype.Component; */ @Component(AuthorityRest.CATEGORY + "." + AuthorityRest.NAME + "." + AuthorityRest.ENTRY) public class AuthorityEntryValueLinkRepository extends AbstractDSpaceRestRepository - implements LinkRestRepository { + implements LinkRestRepository { @Autowired private ChoiceAuthorityService cas; @@ -39,11 +37,6 @@ public class AuthorityEntryValueLinkRepository extends AbstractDSpaceRestReposit @Autowired private AuthorityUtils authorityUtils; - @Override - public HALResource wrapResource(AuthorityEntryRest model, String... rels) { - return new AuthorityEntryResource(model); - } - @PreAuthorize("hasAuthority('AUTHENTICATED')") public AuthorityEntryRest getResource(HttpServletRequest request, String name, String relId, Pageable pageable, String projection) { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityRestRepository.java index 64dcf10468..a1fc542cdb 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityRestRepository.java @@ -12,7 +12,6 @@ import java.util.List; import java.util.Set; import org.dspace.app.rest.model.AuthorityRest; -import org.dspace.app.rest.model.hateoas.AuthorityResource; import org.dspace.app.rest.utils.AuthorityUtils; import org.dspace.content.authority.ChoiceAuthority; import org.dspace.content.authority.service.ChoiceAuthorityService; @@ -63,10 +62,4 @@ public class AuthorityRestRepository extends DSpaceRestRepository getDomainClass() { return AuthorityRest.class; } - - @Override - public AuthorityResource wrapResource(AuthorityRest model, String... rels) { - return new AuthorityResource(model, utils, rels); - } - } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java index f93e768943..44ebf996f4 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java @@ -15,11 +15,10 @@ import javax.servlet.http.HttpServletRequest; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import org.dspace.app.rest.converter.BitstreamFormatConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.BitstreamFormatRest; -import org.dspace.app.rest.model.hateoas.BitstreamFormatResource; import org.dspace.authorize.AuthorizeException; import org.dspace.content.BitstreamFormat; import org.dspace.content.service.BitstreamFormatService; @@ -44,7 +43,7 @@ public class BitstreamFormatRestRepository extends DSpaceRestRepository page = utils.getPage(bit, pageable).map(converter); + Page page = utils.getPage(bit, pageable).map(converter::toRest); return page; } @@ -100,7 +99,7 @@ public class BitstreamFormatRestRepository extends DSpaceRestRepository getDomainClass() { return BitstreamFormatRest.class; } - - @Override - public BitstreamFormatResource wrapResource(BitstreamFormatRest bs, String... rels) { - return new BitstreamFormatResource(bs, utils, rels); - } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamRestRepository.java index d1ce46a719..a7c0f1e057 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamRestRepository.java @@ -16,10 +16,8 @@ import java.util.List; import java.util.UUID; import javax.servlet.http.HttpServletRequest; -import org.dspace.app.rest.converter.BitstreamConverter; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.BitstreamRest; -import org.dspace.app.rest.model.hateoas.BitstreamResource; import org.dspace.app.rest.model.patch.Patch; import org.dspace.app.rest.repository.patch.DSpaceObjectPatch; import org.dspace.authorize.AuthorizeException; @@ -47,9 +45,8 @@ public class BitstreamRestRepository extends DSpaceObjectRestRepository() { }); + public BitstreamRestRepository(BitstreamService dsoService) { + super(dsoService, new DSpaceObjectPatch() { }); this.bs = dsoService; } @@ -72,7 +69,7 @@ public class BitstreamRestRepository extends DSpaceObjectRestRepository page = new PageImpl(bit, pageable, total).map(dsoConverter); + Page page = new PageImpl(bit, pageable, total).map(converter::toRest); return page; } @@ -106,11 +103,6 @@ public class BitstreamRestRepository extends DSpaceObjectRestRepository { - @Autowired - BrowseEntryConverter converter; + implements LinkRestRepository { @Autowired - BrowseIndexConverter bixConverter; + ConverterService converter; + + @Autowired + BrowseEntryConverter browseEntryConverter; @Autowired ScopeResolver scopeResolver; @@ -122,22 +120,13 @@ public class BrowseEntryLinkRepository extends AbstractDSpaceRestRepository BrowseInfo binfo = be.browse(bs); Pageable pageResultInfo = new PageRequest((binfo.getStart() - 1) / binfo.getResultsPerPage(), binfo.getResultsPerPage()); - Page page = new PageImpl(Arrays.asList(binfo.getStringResults()), pageResultInfo, - binfo.getTotal()).map(converter); - page.forEach(new Consumer() { - @Override - public void accept(BrowseEntryRest t) { - t.setBrowseIndex(bixConverter.convert(bi)); - } - }); + Page page = new PageImpl<>(Arrays.asList(binfo.getStringResults()), pageResultInfo, + binfo.getTotal()).map(browseEntryConverter); + BrowseIndexRest biRest = converter.toRest(bi); + page.forEach(t -> t.setBrowseIndex(biRest)); return page; } - @Override - public BrowseEntryResource wrapResource(BrowseEntryRest entry, String... rels) { - return new BrowseEntryResource(entry); - } - @Override public boolean isEmbeddableRelation(Object data, String name) { BrowseIndexRest bir = (BrowseIndexRest) data; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseIndexRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseIndexRestRepository.java index f8b6bec7a0..1ee7b73109 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseIndexRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseIndexRestRepository.java @@ -10,9 +10,8 @@ package org.dspace.app.rest.repository; import java.util.ArrayList; import java.util.List; -import org.dspace.app.rest.converter.BrowseIndexConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.BrowseIndexRest; -import org.dspace.app.rest.model.hateoas.BrowseIndexResource; import org.dspace.browse.BrowseException; import org.dspace.browse.BrowseIndex; import org.dspace.core.Context; @@ -29,8 +28,9 @@ import org.springframework.stereotype.Component; */ @Component(BrowseIndexRest.CATEGORY + "." + BrowseIndexRest.NAME) public class BrowseIndexRestRepository extends DSpaceRestRepository { + @Autowired - BrowseIndexConverter converter; + ConverterService converter; @Override public BrowseIndexRest findOne(Context context, String name) { @@ -42,7 +42,7 @@ public class BrowseIndexRestRepository extends DSpaceRestRepository page = new PageImpl(indexesList, pageable, total).map(converter); + Page page = new PageImpl(indexesList, pageable, total).map(converter::toRest); return page; } @@ -69,10 +69,4 @@ public class BrowseIndexRestRepository extends DSpaceRestRepository getDomainClass() { return BrowseIndexRest.class; } - - @Override - public BrowseIndexResource wrapResource(BrowseIndexRest bix, String... rels) { - return new BrowseIndexResource(bix, utils, rels); - } - -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseItemLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseItemLinkRepository.java index 9308bfe14a..be616b289f 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseItemLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseItemLinkRepository.java @@ -11,14 +11,12 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; - import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; import org.dspace.app.rest.converter.ItemConverter; import org.dspace.app.rest.model.BrowseIndexRest; import org.dspace.app.rest.model.ItemRest; -import org.dspace.app.rest.model.hateoas.ItemResource; import org.dspace.app.rest.utils.ScopeResolver; import org.dspace.browse.BrowseEngine; import org.dspace.browse.BrowseException; @@ -47,13 +45,10 @@ import org.springframework.stereotype.Component; */ @Component(BrowseIndexRest.CATEGORY + "." + BrowseIndexRest.NAME + "." + BrowseIndexRest.ITEMS) public class BrowseItemLinkRepository extends AbstractDSpaceRestRepository - implements LinkRestRepository { + implements LinkRestRepository { @Autowired ItemConverter converter; - @Autowired - ItemRestRepository itemRestRepository; - @Autowired ScopeResolver scopeResolver; @@ -160,11 +155,6 @@ public class BrowseItemLinkRepository extends AbstractDSpaceRestRepository return page; } - @Override - public ItemResource wrapResource(ItemRest item, String... rels) { - return itemRestRepository.wrapResource(item, rels); - } - @Override public boolean isEmbeddableRelation(Object data, String name) { BrowseIndexRest bir = (BrowseIndexRest) data; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java index ed4ff40cb7..e409b21e6b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java @@ -11,7 +11,6 @@ import java.io.IOException; import java.sql.SQLException; import java.util.List; import java.util.UUID; - import javax.mail.MessagingException; import javax.servlet.http.HttpServletRequest; @@ -19,13 +18,12 @@ import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; -import org.dspace.app.rest.converter.ClaimedTaskConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.RESTAuthorizationException; import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.ClaimedTaskRest; import org.dspace.app.rest.model.PoolTaskRest; -import org.dspace.app.rest.model.hateoas.ClaimedTaskResource; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.service.AuthorizeService; import org.dspace.content.service.ItemService; @@ -72,7 +70,7 @@ public class ClaimedTaskRestRepository extends DSpaceRestRepository page = utils.getPage(tasks, pageable).map(converter); + Page page = utils.getPage(tasks, pageable).map(converter::toRest); return page; } @@ -129,11 +127,6 @@ public class ClaimedTaskRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { throw new RepositoryMethodNotImplementedException(ClaimedTaskRest.NAME, "findAll"); } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java index 1ec8e4ba0a..e3be796b6e 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java @@ -19,14 +19,12 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; -import org.dspace.app.rest.converter.CollectionConverter; -import org.dspace.app.rest.converter.MetadataConverter; +import org.dspace.app.rest.converter.ConverterService; 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.CollectionRest; import org.dspace.app.rest.model.CommunityRest; -import org.dspace.app.rest.model.hateoas.CollectionResource; import org.dspace.app.rest.model.patch.Patch; import org.dspace.app.rest.repository.patch.DSpaceObjectPatch; import org.dspace.app.rest.utils.CollectionRestEqualityUtils; @@ -60,18 +58,13 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository() {}); + public CollectionRestRepository(CollectionService dsoService) { + super(dsoService, new DSpaceObjectPatch() {}); this.cs = dsoService; } @@ -87,7 +80,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository page = new PageImpl(collections, pageable, total).map(dsoConverter); + Page page = new PageImpl<>(collections, pageable, total).map(converter::toRest); return page; } @@ -128,7 +121,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository page = utils.getPage(collections, pageable).map(dsoConverter); + Page page = utils.getPage(collections, pageable).map(converter::toRest); return page; } @@ -145,7 +138,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository page = utils.getPage(collections, pageable).map(dsoConverter); + Page page = utils.getPage(collections, pageable).map(converter::toRest); return page; } @@ -161,11 +154,6 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository() {}); + public CommunityRestRepository(CommunityService dsoService) { + super(dsoService, new DSpaceObjectPatch() {}); this.cs = dsoService; } @@ -90,7 +80,7 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository page = new PageImpl(communities, pageable, total).map(dsoConverter); + Page page = new PageImpl(communities, pageable, total).map(converter::toRest); return page; } @@ -173,7 +163,7 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository page = utils.getPage(topCommunities, pageable).map(dsoConverter); + Page page = utils.getPage(topCommunities, pageable).map(converter::toRest); return page; } @@ -194,7 +184,7 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository page = utils.getPage(subCommunities, pageable).map(dsoConverter); + Page page = utils.getPage(subCommunities, pageable).map(converter::toRest); return page; } @@ -210,11 +200,6 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository dsoService; final DSpaceObjectPatch dsoPatch; - final DSpaceObjectConverter dsoConverter; @Autowired MetadataConverter metadataConverter; + @Autowired + ConverterService converter; + DSpaceObjectRestRepository(DSpaceObjectService dsoService, - DSpaceObjectConverter dsoConverter, DSpaceObjectPatch dsoPatch) { this.dsoService = dsoService; this.dsoPatch = dsoPatch; - this.dsoConverter = dsoConverter; } /** @@ -78,7 +78,7 @@ public abstract class DSpaceObjectRestRepository getDomainClass(); - /** - * Wrap the REST model in a REST HAL Resource - * - * @param model - * the rest model instance - * @param rels - * the HAL links - * @return the REST Resource - */ - public abstract DSpaceResource wrapResource(T model, String... rels); - /** * Create and return a new instance. Data are usually retrieved from the thread bound http request * @@ -596,4 +583,4 @@ public abstract class DSpaceRestRepository page = new PageImpl(epersons, pageable, total).map(dsoConverter); + Page page = new PageImpl<>(epersons, pageable, total).map(converter::toRest); return page; } @@ -156,7 +149,7 @@ public class EPersonRestRepository extends DSpaceObjectRestRepository page = new PageImpl(epersons, pageable, total).map(dsoConverter); + Page page = new PageImpl<>(epersons, pageable, total).map(converter::toRest); return page; } @@ -166,8 +159,6 @@ public class EPersonRestRepository extends DSpaceObjectRestRepository getDomainClass() { return EPersonRest.class; } - - @Override - public EPersonResource wrapResource(EPersonRest eperson, String... rels) { - return new EPersonResource(eperson, utils, rels); - } - } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EntityTypeRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EntityTypeRestRepository.java index 31c4e4392c..4adb7e6dfa 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EntityTypeRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EntityTypeRestRepository.java @@ -10,10 +10,8 @@ package org.dspace.app.rest.repository; import java.sql.SQLException; import java.util.List; -import org.dspace.app.rest.converter.EntityTypeConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.EntityTypeRest; -import org.dspace.app.rest.model.hateoas.DSpaceResource; -import org.dspace.app.rest.model.hateoas.EntityTypeResource; import org.dspace.content.EntityType; import org.dspace.content.service.EntityTypeService; import org.dspace.core.Context; @@ -33,7 +31,7 @@ public class EntityTypeRestRepository extends DSpaceRestRepository page = utils.getPage(entityTypeList, pageable).map(entityTypeConverter); + Page page = utils.getPage(entityTypeList, pageable).map(converter::toRest); return page; } public Class getDomainClass() { return EntityTypeRest.class; } - - public DSpaceResource wrapResource(EntityTypeRest model, String... rels) { - return new EntityTypeResource(model, utils, rels); - } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/GroupRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/GroupRestRepository.java index 112453316c..1bb5bff849 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/GroupRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/GroupRestRepository.java @@ -11,16 +11,13 @@ import java.io.IOException; import java.sql.SQLException; import java.util.List; import java.util.UUID; - import javax.servlet.http.HttpServletRequest; import com.fasterxml.jackson.databind.ObjectMapper; -import org.dspace.app.rest.converter.GroupConverter; import org.dspace.app.rest.converter.MetadataConverter; import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.GroupRest; -import org.dspace.app.rest.model.hateoas.GroupResource; import org.dspace.app.rest.model.patch.Patch; import org.dspace.app.rest.repository.patch.DSpaceObjectPatch; import org.dspace.authorize.AuthorizeException; @@ -46,9 +43,8 @@ public class GroupRestRepository extends DSpaceObjectRestRepository() {}); + GroupRestRepository(GroupService dsoService) { + super(dsoService, new DSpaceObjectPatch() {}); this.gs = dsoService; } @@ -79,7 +75,7 @@ public class GroupRestRepository extends DSpaceObjectRestRepository page = new PageImpl(groups, pageable, total).map(dsoConverter); + Page page = new PageImpl(groups, pageable, total).map(converter::toRest); return page; } @@ -123,10 +119,4 @@ public class GroupRestRepository extends DSpaceObjectRestRepository getDomainClass() { return GroupRest.class; } - - @Override - public GroupResource wrapResource(GroupRest eperson, String... rels) { - return new GroupResource(eperson, utils, rels); - } - } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/HarvestedCollectionRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/HarvestedCollectionRestRepository.java index 5cd11df986..a2ecd92107 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/HarvestedCollectionRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/HarvestedCollectionRestRepository.java @@ -75,7 +75,7 @@ public class HarvestedCollectionRestRepository extends AbstractDSpaceRestReposit if (harvestedCollectionRest.getHarvestType() == HarvestTypeEnum.NONE.getValue() && harvestedCollection != null) { harvestedCollectionService.delete(context, harvestedCollection); - return harvestedCollectionConverter.fromModel(null); + return harvestedCollectionConverter.convert(null); } else if (harvestedCollectionRest.getHarvestType() != HarvestTypeEnum.NONE.getValue()) { List errors = testHarvestSettings(harvestedCollectionRest); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java index a0b67fd5ba..ce260f88fa 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java @@ -20,13 +20,11 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; -import org.dspace.app.rest.converter.ItemConverter; import org.dspace.app.rest.converter.MetadataConverter; 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.ItemRest; -import org.dspace.app.rest.model.hateoas.ItemResource; import org.dspace.app.rest.model.patch.Patch; import org.dspace.app.rest.repository.patch.ItemPatch; import org.dspace.authorize.AuthorizeException; @@ -78,10 +76,8 @@ public class ItemRestRepository extends DSpaceObjectRestRepository page = new PageImpl(items, pageable, total).map(dsoConverter); + Page page = new PageImpl(items, pageable, total).map(converter::toRest); return page; } @@ -151,11 +147,6 @@ public class ItemRestRepository extends DSpaceObjectRestRepository { + implements LinkRestRepository { @Autowired CollectionService collectionService; @@ -39,11 +37,6 @@ public class LicenseRestLinkRepository extends AbstractDSpaceRestRepository @Autowired LicenseService licenseService; - @Override - public HALResource wrapResource(LicenseRest model, String... rels) { - return new LicenseResource(model); - } - @PreAuthorize("hasAuthority('AUTHENTICATED')") public LicenseRest getLicenseCollection(HttpServletRequest request, UUID uuid, Pageable pageable, String projection) throws Exception { @@ -62,7 +55,8 @@ public class LicenseRestLinkRepository extends AbstractDSpaceRestRepository return licenseRest; } - public boolean isEmbeddableRelation(LicenseRest data, String name) { + @Override + public boolean isEmbeddableRelation(Object data, String name) { return false; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/LinkRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/LinkRestRepository.java index ddd3d3fb32..98cc08fd23 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/LinkRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/LinkRestRepository.java @@ -7,19 +7,13 @@ */ package org.dspace.app.rest.repository; -import java.io.Serializable; - -import org.dspace.app.rest.model.hateoas.HALResource; - /** * This is the interface for Link Repositories. * * @author Andrea Bollini (andrea.bollini at 4science.it) */ -public interface LinkRestRepository { - public abstract HALResource wrapResource(L model, String... rels); - - public default boolean isEmbeddableRelation(Object data, String name) { +public interface LinkRestRepository { + default boolean isEmbeddableRelation(Object data, String name) { return true; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataFieldRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataFieldRestRepository.java index 923ae6aecb..72ce16862c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataFieldRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataFieldRestRepository.java @@ -21,11 +21,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; -import org.dspace.app.rest.converter.MetadataFieldConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.MetadataFieldRest; -import org.dspace.app.rest.model.hateoas.MetadataFieldResource; import org.dspace.authorize.AuthorizeException; import org.dspace.content.MetadataField; import org.dspace.content.MetadataSchema; @@ -55,7 +54,7 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository page = utils.getPage(metadataField, pageable).map(converter); + Page page = utils.getPage(metadataField, pageable).map(converter::toRest); return page; } @@ -100,7 +99,7 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository page = utils.getPage(metadataFields, pageable).map(converter); + Page page = utils.getPage(metadataFields, pageable).map(converter::toRest); return page; } @@ -109,11 +108,6 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository page = utils.getPage(metadataSchema, pageable).map(converter); + Page page = utils.getPage(metadataSchema, pageable).map(converter::toRest); return page; } @@ -83,11 +82,6 @@ public class MetadataSchemaRestRepository extends DSpaceRestRepository page = utils.getPage(tasks, pageable).map(converter); + Page page = utils.getPage(tasks, pageable).map(converter::toRest); return page; } @@ -125,11 +123,6 @@ public class PoolTaskRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { throw new RuntimeException("Method not allowed!"); } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipRestRepository.java index cd3a78918e..5eb5c71e6c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipRestRepository.java @@ -20,13 +20,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.log4j.Logger; import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; -import org.dspace.app.rest.converter.RelationshipConverter; -import org.dspace.app.rest.converter.RelationshipTypeConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.RelationshipRest; -import org.dspace.app.rest.model.hateoas.DSpaceResource; -import org.dspace.app.rest.model.hateoas.RelationshipResource; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.service.AuthorizeService; import org.dspace.content.DSpaceObject; @@ -66,23 +63,21 @@ public class RelationshipRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { int total = 0; List relationships = new ArrayList<>(); @@ -93,19 +88,15 @@ public class RelationshipRestRepository extends DSpaceRestRepository page = new PageImpl(relationships, - pageable, total).map(relationshipConverter); + Page page = new PageImpl<>(relationships, pageable, total).map(converter::toRest); return page; } + @Override public Class getDomainClass() { return RelationshipRest.class; } - public DSpaceResource wrapResource(RelationshipRest model, String... rels) { - return new RelationshipResource(model, utils, rels); - } - @Override protected RelationshipRest createAndReturn(Context context, List stringList) throws AuthorizeException, SQLException, RepositoryMethodNotImplementedException { @@ -135,7 +126,7 @@ public class RelationshipRestRepository extends DSpaceRestRepository page = new PageImpl(relationships, - pageable, total).map(relationshipConverter); + Page page = new PageImpl<>(relationships, pageable, total).map(converter::toRest); return page; } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipTypeRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipTypeRestRepository.java index ff163555f6..8e67475fa7 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipTypeRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipTypeRestRepository.java @@ -10,10 +10,8 @@ package org.dspace.app.rest.repository; import java.sql.SQLException; import java.util.List; -import org.dspace.app.rest.converter.RelationshipTypeConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.RelationshipTypeRest; -import org.dspace.app.rest.model.hateoas.DSpaceResource; -import org.dspace.app.rest.model.hateoas.RelationshipTypeResource; import org.dspace.content.RelationshipType; import org.dspace.content.service.RelationshipTypeService; import org.dspace.core.Context; @@ -32,16 +30,18 @@ public class RelationshipTypeRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { List relationshipTypeList = null; try { @@ -49,15 +49,12 @@ public class RelationshipTypeRestRepository extends DSpaceRestRepository page = utils.getPage(relationshipTypeList, pageable).map(relationshipTypeConverter); + Page page = utils.getPage(relationshipTypeList, pageable).map(converter::toRest); return page; } + @Override public Class getDomainClass() { return RelationshipTypeRest.class; } - - public DSpaceResource wrapResource(RelationshipTypeRest model, String... rels) { - return new RelationshipTypeResource(model, utils, rels); - } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ResourcePolicyRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ResourcePolicyRestRepository.java index 004d7b72ab..1c75e2abca 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ResourcePolicyRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ResourcePolicyRestRepository.java @@ -9,10 +9,9 @@ package org.dspace.app.rest.repository; import java.sql.SQLException; -import org.dspace.app.rest.converter.ResourcePolicyConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException; import org.dspace.app.rest.model.ResourcePolicyRest; -import org.dspace.app.rest.model.hateoas.ResourcePolicyResource; import org.dspace.app.rest.utils.Utils; import org.dspace.authorize.ResourcePolicy; import org.dspace.authorize.service.ResourcePolicyService; @@ -35,7 +34,7 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository getDomainClass() { return ResourcePolicyRest.class; } - - - @Override - public ResourcePolicyResource wrapResource(ResourcePolicyRest model, String... rels) { - return new ResourcePolicyResource(model, utils, rels); - } - } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SiteRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SiteRestRepository.java index e374df7fca..dc252a2fac 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SiteRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SiteRestRepository.java @@ -13,9 +13,7 @@ import java.util.List; import java.util.UUID; import javax.servlet.http.HttpServletRequest; -import org.dspace.app.rest.converter.SiteConverter; import org.dspace.app.rest.model.SiteRest; -import org.dspace.app.rest.model.hateoas.SiteResource; import org.dspace.app.rest.model.patch.Patch; import org.dspace.app.rest.repository.patch.DSpaceObjectPatch; import org.dspace.authorize.AuthorizeException; @@ -41,9 +39,8 @@ public class SiteRestRepository extends DSpaceObjectRestRepository() {}); + public SiteRestRepository(SiteService dsoService) { + super(dsoService, new DSpaceObjectPatch() {}); this.sitesv = dsoService; } @@ -58,7 +55,7 @@ public class SiteRestRepository extends DSpaceObjectRestRepository page = new PageImpl(sites, pageable, total).map(dsoConverter); + Page page = new PageImpl(sites, pageable, total).map(converter::toRest); return page; } @@ -85,10 +82,4 @@ public class SiteRestRepository extends DSpaceObjectRestRepository getDomainClass() { return SiteRest.class; } - - @Override - public SiteResource wrapResource(SiteRest site, String... rels) { - return new SiteResource(site, utils, rels); - } - -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionDefinitionRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionDefinitionRestRepository.java index 27f6913289..37e5be1a5a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionDefinitionRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionDefinitionRestRepository.java @@ -8,15 +8,13 @@ package org.dspace.app.rest.repository; import java.sql.SQLException; -import java.util.ArrayList; import java.util.List; import java.util.UUID; import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; -import org.dspace.app.rest.converter.SubmissionDefinitionConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.SubmissionDefinitionRest; -import org.dspace.app.rest.model.hateoas.SubmissionDefinitionResource; import org.dspace.app.util.SubmissionConfig; import org.dspace.app.util.SubmissionConfigReader; import org.dspace.app.util.SubmissionConfigReaderException; @@ -43,7 +41,7 @@ public class SubmissionDefinitionRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { - List subConfs = new ArrayList(); int total = submissionConfigReader.countSubmissionConfigs(); - subConfs = submissionConfigReader.getAllSubmissionConfigs(pageable.getPageSize(), pageable.getOffset()); - Page page = new PageImpl(subConfs, pageable, total).map(converter); + List subConfs = submissionConfigReader.getAllSubmissionConfigs( + pageable.getPageSize(), pageable.getOffset()); + Page page = new PageImpl<>(subConfs, pageable, total).map(converter::toRest); return page; } @@ -78,7 +76,7 @@ public class SubmissionDefinitionRestRepository extends DSpaceRestRepository getDomainClass() { return SubmissionDefinitionRest.class; } - - @Override - public SubmissionDefinitionResource wrapResource(SubmissionDefinitionRest sd, String... rels) { - return new SubmissionDefinitionResource(sd, utils, rels); - } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionFormRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionFormRestRepository.java index 5bbc05b882..7063d255c2 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionFormRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionFormRestRepository.java @@ -10,9 +10,8 @@ package org.dspace.app.rest.repository; import java.util.ArrayList; import java.util.List; -import org.dspace.app.rest.converter.SubmissionFormConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.SubmissionFormRest; -import org.dspace.app.rest.model.hateoas.SubmissionFormResource; import org.dspace.app.util.DCInputSet; import org.dspace.app.util.DCInputsReader; import org.dspace.app.util.DCInputsReaderException; @@ -31,12 +30,12 @@ import org.springframework.stereotype.Component; */ @Component(SubmissionFormRest.CATEGORY + "." + SubmissionFormRest.NAME) public class SubmissionFormRestRepository extends DSpaceRestRepository - implements LinkRestRepository { + implements LinkRestRepository { private DCInputsReader inputReader; @Autowired - private SubmissionFormConverter converter; + private ConverterService converter; public SubmissionFormRestRepository() throws DCInputsReaderException { inputReader = new DCInputsReader(); @@ -54,7 +53,7 @@ public class SubmissionFormRestRepository extends DSpaceRestRepository page = new PageImpl(subConfs, pageable, total).map(converter); + Page page = new PageImpl<>(subConfs, pageable, total).map(converter::toRest); return page; } @@ -75,9 +74,4 @@ public class SubmissionFormRestRepository extends DSpaceRestRepository getDomainClass() { return SubmissionFormRest.class; } - - @Override - public SubmissionFormResource wrapResource(SubmissionFormRest sd, String... rels) { - return new SubmissionFormResource(sd, utils, rels); - } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionPanelRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionPanelRestRepository.java index 125884af49..2f0202bf12 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionPanelRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionPanelRestRepository.java @@ -10,10 +10,9 @@ package org.dspace.app.rest.repository; import java.util.ArrayList; import java.util.List; -import org.dspace.app.rest.converter.SubmissionSectionConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.SubmissionDefinitionRest; import org.dspace.app.rest.model.SubmissionSectionRest; -import org.dspace.app.rest.model.hateoas.SubmissionSectionResource; import org.dspace.app.util.SubmissionConfig; import org.dspace.app.util.SubmissionConfigReader; import org.dspace.app.util.SubmissionConfigReaderException; @@ -37,7 +36,7 @@ public class SubmissionPanelRestRepository extends DSpaceRestRepository page = new PageImpl(stepConfs, pageable, total) - .map(converter); + Page page = new PageImpl<>(stepConfs, pageable, total).map(converter::toRest); return page; } @@ -78,10 +76,4 @@ public class SubmissionPanelRestRepository extends DSpaceRestRepository getDomainClass() { return SubmissionSectionRest.class; } - - @Override - public SubmissionSectionResource wrapResource(SubmissionSectionRest model, String... rels) { - return new SubmissionSectionResource(model, utils, rels); - } - -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java index 69fb7a64fc..95bba5ce8e 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java @@ -14,7 +14,6 @@ import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Logger; import org.dspace.app.rest.model.AccessConditionOptionRest; import org.dspace.app.rest.model.SubmissionUploadRest; -import org.dspace.app.rest.model.hateoas.SubmissionUploadResource; import org.dspace.app.rest.utils.DateMathParser; import org.dspace.app.util.SubmissionConfig; import org.dspace.app.util.SubmissionConfigReader; @@ -41,7 +40,7 @@ import org.springframework.stereotype.Component; */ @Component(SubmissionUploadRest.CATEGORY + "." + SubmissionUploadRest.NAME) public class SubmissionUploadRestRepository extends DSpaceRestRepository - implements LinkRestRepository { + implements LinkRestRepository { private static final Logger log = org.apache.logging.log4j.LogManager .getLogger(SubmissionUploadRestRepository.class); @@ -104,11 +103,6 @@ public class SubmissionUploadRestRepository extends DSpaceRestRepository page = new PageImpl(witems, pageable, total).map(converter); + Page page = new PageImpl<>(witems, pageable, total).map(converter::toRest); return page; } @@ -139,7 +137,7 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository page = new PageImpl(witems, pageable, total).map(converter); + Page page = new PageImpl<>(witems, pageable, total).map(converter::toRest); return page; } @@ -163,7 +161,7 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository page = new PageImpl(witems, pageable, total).map(converter); + Page page = new PageImpl(witems, pageable, total).map(converter::toRest); return page; } @@ -156,21 +157,21 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository page = new PageImpl(witems, pageable, total).map(converter); + Page page = new PageImpl<>(witems, pageable, total).map(converter::toRest); return page; } @Override protected WorkspaceItemRest createAndReturn(Context context) throws SQLException, AuthorizeException { WorkspaceItem source = submissionService.createWorkspaceItem(context, getRequestService().getCurrentRequest()); - return converter.convert(source); + return converter.toRest(source); } @Override protected WorkspaceItemRest save(Context context, WorkspaceItemRest wsi) { SubmissionConfig submissionConfig = submissionConfigReader .getSubmissionConfigByName(submissionConfigReader.getDefaultSubmissionConfigName()); - WorkspaceItem source = converter.toModel(wsi); + WorkspaceItem source = workspaceItemConverter.toModel(wsi); for (int stepNum = 0; stepNum < submissionConfig.getNumberOfSteps(); stepNum++) { SubmissionStepConfig stepConfig = submissionConfig.getStep(stepNum); @@ -211,11 +212,6 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository workflowService; @Autowired private RequestService requestService; - @Autowired(required = true) - BitstreamFormatConverter bfConverter; @Autowired - WorkspaceItemConverter workspaceItemConverter; - @Autowired(required = true) - ResourcePolicyConverter aCConverter; + private ConverterService converter; /** * Create a workspaceitem using the information in the reqest @@ -170,11 +163,11 @@ public class SubmissionService { } HttpServletRequest request = requestService.getCurrentRequest().getHttpServletRequest(); - data.setFormat(bfConverter.convert(source.getFormat(ContextUtil.obtainContext(request)))); + data.setFormat(converter.toRest(source.getFormat(ContextUtil.obtainContext(request)))); for (ResourcePolicy rp : source.getResourcePolicies()) { if (ResourcePolicy.TYPE_CUSTOM.equals(rp.getRpType())) { - ResourcePolicyRest resourcePolicyRest = aCConverter.convert(rp); + ResourcePolicyRest resourcePolicyRest = converter.toRest(rp); data.getAccessConditions().add(resourcePolicyRest); } } @@ -225,7 +218,8 @@ public class SubmissionService { if (wsi == null) { throw new UnprocessableEntityException("Workspace item is not found"); } - if (!workspaceItemConverter.convert(wsi).getErrors().isEmpty()) { + WorkspaceItemRest wsiRest = converter.toRest(wsi); + if (!wsiRest.getErrors().isEmpty()) { throw new UnprocessableEntityException( "Start workflow failed due to validation error on workspaceitem"); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/AuthorityUtils.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/AuthorityUtils.java index ac2b3844d8..2ffc5ce3d4 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/AuthorityUtils.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/AuthorityUtils.java @@ -7,8 +7,7 @@ */ package org.dspace.app.rest.utils; -import org.dspace.app.rest.converter.AuthorityEntryRestConverter; -import org.dspace.app.rest.converter.AuthorityRestConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.AuthorityEntryRest; import org.dspace.app.rest.model.AuthorityRest; import org.dspace.content.authority.Choice; @@ -35,10 +34,7 @@ public class AuthorityUtils { private ChoiceAuthorityService cas; @Autowired - private AuthorityEntryRestConverter entryConverter; - - @Autowired - private AuthorityRestConverter authorityConverter; + private ConverterService converter; public boolean isChoice(String schema, String element, String qualifier) { @@ -65,7 +61,7 @@ public class AuthorityUtils { * @return */ public AuthorityEntryRest convertEntry(Choice choice, String authorityName) { - AuthorityEntryRest entry = entryConverter.convert(choice); + AuthorityEntryRest entry = converter.toRest(choice); entry.setAuthorityName(authorityName); return entry; } @@ -74,11 +70,11 @@ public class AuthorityUtils { * TODO the authorityName MUST be a part of ChoiceAuthority model * * @param source - * @param name + * @param authorityName * @return */ public AuthorityRest convertAuthority(ChoiceAuthority source, String authorityName) { - AuthorityRest result = authorityConverter.convert(source); + AuthorityRest result = converter.toRest(source); result.setName(authorityName); return result; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java index ef9c6d8bc8..974d0b7b91 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java @@ -12,6 +12,9 @@ import static java.util.stream.Collectors.toList; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; @@ -19,25 +22,38 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.Scanner; - +import java.util.Set; +import java.util.TreeSet; +import java.util.UUID; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.PaginationException; import org.dspace.app.rest.exception.RepositoryNotFoundException; import org.dspace.app.rest.model.AuthorityRest; +import org.dspace.app.rest.model.BaseObjectRest; import org.dspace.app.rest.model.CommunityRest; import org.dspace.app.rest.model.LinkRest; import org.dspace.app.rest.model.LinksRest; import org.dspace.app.rest.model.ResourcePolicyRest; import org.dspace.app.rest.model.RestAddressableModel; +import org.dspace.app.rest.model.RestModel; import org.dspace.app.rest.model.hateoas.DSpaceResource; +import org.dspace.app.rest.model.hateoas.EmbeddedPage; +import org.dspace.app.rest.model.hateoas.HALResource; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.repository.DSpaceRestRepository; import org.dspace.app.rest.repository.LinkRestRepository; import org.dspace.content.BitstreamFormat; @@ -50,8 +66,10 @@ import org.dspace.util.UUIDUtils; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; +import org.springframework.core.annotation.AnnotationUtils; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.hateoas.Link; import org.springframework.stereotype.Component; @@ -67,6 +85,8 @@ public class Utils { private static final Logger log = Logger.getLogger(Utils.class); + private static final int EMBEDDED_PAGE_SIZE = 20; + @Autowired ApplicationContext applicationContext; @@ -76,6 +96,9 @@ public class Utils { @Autowired private BitstreamFormatService bitstreamFormatService; + @Autowired + private ConverterService converter; + public Page getPage(List fullContents, Pageable pageable) { int total = fullContents.size(); List pageContent = null; @@ -158,23 +181,13 @@ public class Utils { /** * @param rel - * @param domainClass - * @return the LinkRest annotation corresponding to the specified rel in the - * domainClass. Null if not found + * @param restClass + * @return the LinkRest annotation corresponding to the specified rel in the rest class, or null if not found. */ - public LinkRest getLinkRest(String rel, Class domainClass) { - LinkRest linkRest = null; - LinksRest linksAnnotation = domainClass.getDeclaredAnnotation(LinksRest.class); - if (linksAnnotation != null) { - LinkRest[] links = linksAnnotation.links(); - for (LinkRest l : links) { - if (StringUtils.equals(rel, l.name())) { - linkRest = l; - break; - } - } - } - return linkRest; + public LinkRest getClassLevelLinkRest(String rel, Class restClass) { + Optional optionalLinkRest = getLinkRests(restClass).stream().filter((linkRest) -> + rel.equals(linkRest.name())).findFirst(); + return optionalLinkRest.isPresent() ? optionalLinkRest.get() : null; } /** @@ -225,7 +238,7 @@ public class Utils { /** * Return the filename part from a multipartFile upload that could eventually contains the fullpath on the client - * filesystem + * * @param multipartFile * the file uploaded @@ -355,4 +368,206 @@ public class Utils { } return list; } + + public T toResource(RestModel restObject) { + return converter.toResource(restObject); + } + + /** + * Gets the alphanumerically sorted union of multiple string arrays. + * + * @param arrays the string arrays. + * @return the sorted union of them, with no duplicate values. + */ + public String[] getSortedUnion(String[]... arrays) { + Set set = new TreeSet<>(); + for (String[] array : arrays) { + for (String string : array) { + set.add(string); + } + } + return set.toArray(arrays[0]); + } + + /** + * Gets the method with the given name in the given class. + * + * @param clazz the class. + * @param name the method name. + * @return the first method found with the given name. + * @throws IllegalArgumentException if no such method is found. + */ + public Method requireMethod(Class clazz, String name) { + for (Method method : clazz.getMethods()) { + if (method.getName().equals(name)) { + return method; + } + } + throw new IllegalArgumentException("No such method in " + clazz + ": " + name); + } + + /** + * Adds embeds or links for all class-level LinkRel annotations for which embeds or links are allowed. + * + * @param halResource the resource. + */ + public void embedOrLinkClassLevelRels(HALResource halResource) { + Projection projection = halResource.getContent().getProjection(); + getLinkRests(halResource.getContent().getClass()).stream().forEach((linkRest) -> { + Link link = linkToSubResource(halResource.getContent(), linkRest.name()); + if (!linkRest.embedOptional() || projection.allowOptionalEmbed(halResource, linkRest)) { + embedRelFromRepository(halResource, linkRest.name(), link, linkRest.method()); + } else if (!linkRest.linkOptional() || projection.allowOptionalLink(halResource, linkRest)) { + halResource.add(link); + } + }); + } + + private List getLinkRests(Class restClass) { + List list = new ArrayList<>(); + LinksRest linksAnnotation = restClass.getDeclaredAnnotation(LinksRest.class); + if (linksAnnotation != null) { + list.addAll(Arrays.asList(linksAnnotation.links())); + } + return list; + } + + /** + * Embeds a rel whose value comes from a {@LinkRestRepository}. + * + * @param resource the resource. + * @param rel the name of the rel. + * @param link the link. + * @param methodName the method name in the link repository. + */ + private void embedRelFromRepository(HALResource resource, + String rel, Link link, String methodName) { + LinkRestRepository linkRepository = getLinkResourceRepository(resource.getContent().getCategory(), + resource.getContent().getType(), rel); + if (linkRepository.isEmbeddableRelation(resource.getContent(), rel)) { + Method method = requireMethod(linkRepository.getClass(), methodName); + Object contentId = getContentIdForLinkMethod(resource.getContent(), method); + try { + Object linkedObject = method.invoke(linkRepository, null, contentId, null, null); + resource.embedResource(rel, wrapForEmbedding(linkedObject, link)); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + } + + /** + * Adds embeds for all properties annotated with {@code @LinkRel} or whose return types are + * {@link RestAddressableModel} subclasses. + */ + public void embedMethodLevelRels(HALResource resource) { + try { + for (PropertyDescriptor pd : Introspector.getBeanInfo( + resource.getContent().getClass()).getPropertyDescriptors()) { + Method readMethod = pd.getReadMethod(); + String propertyName = pd.getName(); + if (readMethod != null && !"class".equals(propertyName)) { + embedMethodLevelRel(resource, readMethod, propertyName); + } + } + } catch (IntrospectionException e) { + throw new RuntimeException(e); + } + } + + /** + * Adds an embed for the given property read method. If the @LinkRel annotation is present and + * specifies a method name, the value will come from invoking that method in the appropriate link + * rest repository. Otherwise, the value will come from invoking the method directly on the wrapped + * rest object. + * + * @param readMethod the property read method. + * @param propertyName the property name, which will be used as the rel/embed name unless the @LinkRel + * annotation is present and specifies a different name. + */ + private void embedMethodLevelRel(HALResource resource, + Method readMethod, + String propertyName) { + String rel = propertyName; + LinkRest linkRest = AnnotationUtils.findAnnotation(readMethod, LinkRest.class); + try { + if (linkRest != null) { + if (linkRest.embedOptional() + && !resource.getContent().getProjection().allowOptionalEmbed(resource, linkRest)) { + return; // projection disallows this optional method-level embed + } + if (StringUtils.isNotBlank(linkRest.name())) { + rel = linkRest.name(); + } + Link link = linkToSubResource(resource.getContent(), rel); + if (StringUtils.isBlank(linkRest.method())) { + resource.embedResource(rel, wrapForEmbedding(readMethod.invoke(resource.getContent()), link)); + } else { + embedRelFromRepository(resource, rel, link, linkRest.method()); + } + } else if (RestAddressableModel.class.isAssignableFrom(readMethod.getReturnType())) { + RestAddressableModel linkedObject = (RestAddressableModel) readMethod.invoke(resource.getContent()); + resource.embedResource(rel, linkedObject == null ? null : + wrapForEmbedding(linkedObject, linkToSubResource(resource.getContent(), rel))); + } + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + /** + * Wraps the given linked object (retrieved from a link repository or link method on the rest item) + * in an object that is appropriate for embedding, if needed. + * + * @param linkedObject the linked object. + * @param link the link, which is used if the linked object is a list or page, to determine the self link + * and embed property name to use for the subresource. + * @return the wrapped object. + */ + private Object wrapForEmbedding(Object linkedObject, Link link) { + if (linkedObject instanceof RestAddressableModel) { + return converter.toResource((RestAddressableModel) linkedObject); + } else if (linkedObject instanceof Page || linkedObject instanceof List) { + List list = linkedObject instanceof Page ? ((Page) linkedObject).getContent() + : (List) linkedObject; + if (list.size() > 0) { + PageImpl page = new PageImpl( + list.subList(0, list.size() > EMBEDDED_PAGE_SIZE ? EMBEDDED_PAGE_SIZE : list.size()), + new PageRequest(0, EMBEDDED_PAGE_SIZE), list.size()); + return new EmbeddedPage(link.getHref(), page.map(converter::toResource), list, link.getRel()); + } else { + PageImpl page = new PageImpl(list); + return new EmbeddedPage(link.getHref(), page, list, link.getRel()); + } + } else { + return linkedObject; + } + } + + /** + * Gets an object representing the id of the wrapped object, whose runtime time matches the second + * (id) argument of the given link method. This is necessary because it is possible for the rest + * object's id to be a string while the domain object's id may be a uuid or numeric type. + * + * @param linkMethod the link method. + * @return the id, which may be a UUID, Integer, or Long. + */ + private Object getContentIdForLinkMethod(RestAddressableModel restObject, Method linkMethod) { + Object contentId = ((BaseObjectRest) restObject).getId(); + Class requiredIdType = linkMethod.getParameterTypes()[1]; + if (!requiredIdType.isAssignableFrom(contentId.getClass())) { + if (requiredIdType.equals(UUID.class)) { + contentId = UUID.fromString(contentId.toString()); + } else if (requiredIdType.equals(Integer.class)) { + contentId = Integer.parseInt(contentId.toString()); + } else if (requiredIdType.equals(Long.class)) { + contentId = Long.parseLong(contentId.toString()); + } else { + throw new IllegalArgumentException("Cannot cast " + restObject.getClass() + + " id type " + contentId.getClass() + " to id type required by " + + linkMethod.getDeclaringClass() + "#" + linkMethod.getName() + ": " + requiredIdType); + } + } + return contentId; + } } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamFormatRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamFormatRestRepositoryIT.java index fa6ecaedfe..4957d89ea4 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamFormatRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamFormatRestRepositoryIT.java @@ -27,7 +27,7 @@ import java.util.concurrent.atomic.AtomicReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.dspace.app.rest.builder.BitstreamFormatBuilder; import org.dspace.app.rest.builder.EPersonBuilder; -import org.dspace.app.rest.converter.BitstreamFormatConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.matcher.BitstreamFormatMatcher; import org.dspace.app.rest.model.BitstreamFormatRest; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; @@ -49,7 +49,7 @@ import org.springframework.test.web.servlet.MvcResult; public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrationTest { @Autowired - BitstreamFormatConverter converter; + ConverterService converter; @Autowired BitstreamFormatService bitstreamFormatService; @@ -279,7 +279,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati .build(); context.restoreAuthSystemState(); - BitstreamFormatRest bitstreamFormatRest = converter.fromModel(bitstreamFormat); + BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat); String token = getAuthToken(admin.getEmail(), password); //Update it bitstreamFormatRest.setShortDescription("Test short UPDATED"); @@ -311,7 +311,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati .build(); context.restoreAuthSystemState(); - BitstreamFormatRest bitstreamFormatRest = converter.fromModel(bitstreamFormat); + BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat); String token = getAuthToken(admin.getEmail(), password); //Update it bitstreamFormatRest.setShortDescription("Test short UPDATED"); @@ -349,7 +349,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati int nonExistentBitstreamFormatID = 404404404; - BitstreamFormatRest bitstreamFormatRest = converter.fromModel(bitstreamFormat); + BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat); String token = getAuthToken(admin.getEmail(), password); //Update it with non existent ID in URL and in JSON bitstreamFormatRest.setShortDescription("Test short UPDATED"); @@ -386,7 +386,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati int nonExistentBitstreamFormatID = 404404404; - BitstreamFormatRest bitstreamFormatRest = converter.fromModel(bitstreamFormat); + BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat); String token = getAuthToken(admin.getEmail(), password); //Update it with non existent ID in URL bitstreamFormatRest.setShortDescription("Test short UPDATED"); @@ -422,7 +422,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati int nonExistentBitstreamFormatID = 404404404; - BitstreamFormatRest bitstreamFormatRest = converter.fromModel(bitstreamFormat); + BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat); String token = getAuthToken(admin.getEmail(), password); //Update it with non existent ID in JSON, but valid in URL bitstreamFormatRest.setShortDescription("Test short UPDATED"); @@ -460,7 +460,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati .build(); context.restoreAuthSystemState(); - BitstreamFormatRest bitstreamFormatRest = converter.fromModel(bitstreamFormat1); + BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat1); String token = getAuthToken(admin.getEmail(), password); //Update but id in body is not same id as in URL bitstreamFormatRest.setShortDescription("Test short UPDATED"); @@ -493,7 +493,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati .build(); context.restoreAuthSystemState(); - BitstreamFormatRest bitstreamFormatRest = converter.fromModel(bitstreamFormat); + BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat); //Try to update bitstreamFormat without auth token bitstreamFormatRest.setShortDescription("Test short UPDATED"); @@ -529,7 +529,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati .build(); context.restoreAuthSystemState(); - BitstreamFormatRest bitstreamFormatRest = converter.fromModel(bitstreamFormat); + BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat); String token = getAuthToken(user.getEmail(), password); //Try to update bitstreamFormat without non-admin auth token @@ -654,4 +654,4 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati bitstreamFormatRest.setExtensions(Arrays.asList("txt", "asc")); return bitstreamFormatRest; } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionRestRepositoryIT.java index ac019ef2e7..21ad836cea 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionRestRepositoryIT.java @@ -24,7 +24,7 @@ import java.util.UUID; import com.fasterxml.jackson.databind.ObjectMapper; import org.dspace.app.rest.builder.CollectionBuilder; import org.dspace.app.rest.builder.CommunityBuilder; -import org.dspace.app.rest.converter.CollectionConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.matcher.CollectionMatcher; import org.dspace.app.rest.matcher.MetadataMatcher; import org.dspace.app.rest.model.CollectionRest; @@ -45,7 +45,7 @@ import org.springframework.http.MediaType; public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTest { @Autowired - CollectionConverter collectionConverter; + ConverterService converter; @Autowired AuthorizeService authorizeService; @@ -369,7 +369,7 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes ObjectMapper mapper = new ObjectMapper(); - CollectionRest collectionRest = collectionConverter.fromModel(col1); + CollectionRest collectionRest = converter.toRest(col1); collectionRest.setMetadata(new MetadataRest() .put("dc.title", new MetadataValueRest("Electronic theses and dissertations"))); @@ -730,7 +730,7 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes String token = getAuthToken(eperson.getEmail(), password); ObjectMapper mapper = new ObjectMapper(); - CollectionRest collectionRest = collectionConverter.fromModel(col1); + CollectionRest collectionRest = converter.toRest(col1); collectionRest.setMetadata(new MetadataRest() .put("dc.title", new MetadataValueRest("Electronic theses and dissertations"))); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CommunityRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CommunityRestRepositoryIT.java index cdf0c203e8..1d39c9c41b 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CommunityRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CommunityRestRepositoryIT.java @@ -30,10 +30,9 @@ import java.util.stream.Collectors; import java.util.stream.StreamSupport; import com.fasterxml.jackson.databind.ObjectMapper; - import org.dspace.app.rest.builder.CollectionBuilder; import org.dspace.app.rest.builder.CommunityBuilder; -import org.dspace.app.rest.converter.CommunityConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.matcher.CommunityMatcher; import org.dspace.app.rest.matcher.MetadataMatcher; import org.dspace.app.rest.matcher.PageMatcher; @@ -62,7 +61,7 @@ import org.springframework.test.web.servlet.MvcResult; public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest { @Autowired - CommunityConverter communityConverter; + ConverterService converter; @Autowired CommunityService communityService; @@ -831,7 +830,7 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest ObjectMapper mapper = new ObjectMapper(); - CommunityRest communityRest = communityConverter.fromModel(parentCommunity); + CommunityRest communityRest = converter.toRest(parentCommunity); communityRest.setMetadata(new MetadataRest() .put("dc.title", new MetadataValueRest("Electronic theses and dissertations"))); @@ -1041,7 +1040,7 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest ObjectMapper mapper = new ObjectMapper(); - CommunityRest communityRest = communityConverter.fromModel(parentCommunity); + CommunityRest communityRest = converter.toRest(parentCommunity); communityRest.setMetadata(new MetadataRest() .put("dc.title", new MetadataValueRest("Electronic theses and dissertations"))); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataSchemaRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataSchemaRestRepositoryIT.java index 8ffcd4df67..64b43bb8bd 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataSchemaRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataSchemaRestRepositoryIT.java @@ -22,7 +22,7 @@ import java.util.concurrent.atomic.AtomicReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.dspace.app.rest.builder.MetadataSchemaBuilder; -import org.dspace.app.rest.converter.MetadataSchemaConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.matcher.MetadataschemaMatcher; import org.dspace.app.rest.model.MetadataSchemaRest; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; @@ -45,7 +45,7 @@ public class MetadataSchemaRestRepositoryIT extends AbstractControllerIntegratio private static final String TEST_NAMESPACE_UPDATED = "testSchemaNameSpaceUpdated"; @Autowired - MetadataSchemaConverter metadataSchemaConverter; + ConverterService converter; @Test public void findAll() throws Exception { @@ -88,7 +88,7 @@ public class MetadataSchemaRestRepositoryIT extends AbstractControllerIntegratio .build(); context.restoreAuthSystemState(); - MetadataSchemaRest metadataSchemaRest = metadataSchemaConverter.fromModel(metadataSchema); + MetadataSchemaRest metadataSchemaRest = converter.toRest(metadataSchema); metadataSchemaRest.setPrefix(TEST_NAME); metadataSchemaRest.setNamespace(TEST_NAMESPACE); From 32098c4ffb5ae6c6caf24d5ff0a2a24da5f546d3 Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Thu, 31 Oct 2019 10:28:14 -0400 Subject: [PATCH 02/20] DS-3533 Use list projection when embedding a page from a link repository --- .../src/main/java/org/dspace/app/rest/utils/Utils.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java index 974d0b7b91..022de7873a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java @@ -53,6 +53,7 @@ import org.dspace.app.rest.model.RestModel; import org.dspace.app.rest.model.hateoas.DSpaceResource; import org.dspace.app.rest.model.hateoas.EmbeddedPage; import org.dspace.app.rest.model.hateoas.HALResource; +import org.dspace.app.rest.projection.ListProjection; import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.repository.DSpaceRestRepository; import org.dspace.app.rest.repository.LinkRestRepository; @@ -534,7 +535,9 @@ public class Utils { PageImpl page = new PageImpl( list.subList(0, list.size() > EMBEDDED_PAGE_SIZE ? EMBEDDED_PAGE_SIZE : list.size()), new PageRequest(0, EMBEDDED_PAGE_SIZE), list.size()); - return new EmbeddedPage(link.getHref(), page.map(converter::toResource), list, link.getRel()); + return new EmbeddedPage(link.getHref(), + page.map((restObject) -> converter.toResource(restObject, ListProjection.NAME)), + list, link.getRel()); } else { PageImpl page = new PageImpl(list); return new EmbeddedPage(link.getHref(), page, list, link.getRel()); From f4737bb74b17d1177090574388b04ba25e8bba79 Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Thu, 31 Oct 2019 09:57:29 -0400 Subject: [PATCH 03/20] DS-3533 Provide item relationships via link repository --- .../app/rest/BitstreamRestController.java | 7 +- .../app/rest/converter/ItemConverter.java | 34 ---------- .../org/dspace/app/rest/model/ItemRest.java | 23 +++---- .../ItemRelationshipLinkRepository.java | 68 +++++++++++++++++++ 4 files changed, 81 insertions(+), 51 deletions(-) create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRelationshipLinkRepository.java diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/BitstreamRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/BitstreamRestController.java index 868e6413f2..88c7620b4e 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/BitstreamRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/BitstreamRestController.java @@ -22,7 +22,7 @@ import javax.ws.rs.core.Response; import org.apache.catalina.connector.ClientAbortException; import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.Logger; -import org.dspace.app.rest.converter.BitstreamConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.model.BitstreamRest; import org.dspace.app.rest.model.hateoas.BitstreamResource; @@ -90,7 +90,7 @@ public class BitstreamRestController { private ConfigurationService configurationService; @Autowired - BitstreamConverter converter; + ConverterService converter; @Autowired Utils utils; @@ -238,7 +238,6 @@ public class BitstreamRestController { context.commit(); - return (BitstreamResource) utils.getResourceRepository(BitstreamRest.CATEGORY, BitstreamRest.NAME) - .wrapResource(converter.fromModel(context.reloadEntity(bitstream))); + return converter.toResource(converter.toRest(context.reloadEntity(bitstream))); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ItemConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ItemConverter.java index 6bc84c98ef..1b34d3a480 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ItemConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ItemConverter.java @@ -7,29 +7,19 @@ */ package org.dspace.app.rest.converter; -import java.sql.SQLException; import java.util.ArrayList; -import java.util.LinkedList; import java.util.List; -import javax.servlet.http.HttpServletRequest; import org.apache.logging.log4j.Logger; import org.dspace.app.rest.model.BitstreamRest; import org.dspace.app.rest.model.ItemRest; -import org.dspace.app.rest.model.RelationshipRest; -import org.dspace.app.rest.utils.ContextUtil; import org.dspace.content.Bitstream; import org.dspace.content.Bundle; import org.dspace.content.Collection; import org.dspace.content.Item; import org.dspace.content.MetadataValue; -import org.dspace.content.Relationship; import org.dspace.content.service.ItemService; -import org.dspace.content.service.RelationshipService; -import org.dspace.core.Context; import org.dspace.discovery.IndexableObject; -import org.dspace.services.RequestService; -import org.dspace.services.model.Request; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -49,10 +39,6 @@ public class ItemConverter @Autowired private MetadataConverter metadataConverter; @Autowired - private RequestService requestService; - @Autowired - private RelationshipService relationshipService; - @Autowired private ItemService itemService; private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(ItemConverter.class); @@ -79,26 +65,6 @@ public class ItemConverter } } item.setBitstreams(bitstreams); - List relationships = new LinkedList<>(); - try { - Context context; - Request currentRequest = requestService.getCurrentRequest(); - if (currentRequest != null) { - HttpServletRequest request = currentRequest.getHttpServletRequest(); - context = ContextUtil.obtainContext(request); - } else { - context = new Context(); - } - relationships = relationshipService.findByItem(context, obj); - } catch (SQLException e) { - log.error("Error retrieving relationships for item " + item.getHandle(), e); - } - List relationshipRestList = new LinkedList<>(); - for (Relationship relationship : relationships) { - RelationshipRest relationshipRest = converter.toRest(relationship); - relationshipRestList.add(relationshipRest); - } - item.setRelationships(relationshipRestList); List fullList = itemService.getMetadata(obj, Item.ANY, Item.ANY, Item.ANY, Item.ANY, true); item.setMetadata(metadataConverter.convert(fullList)); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java index abe1d3473f..7246c63b3b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java @@ -18,9 +18,18 @@ import com.fasterxml.jackson.annotation.JsonProperty; * * @author Andrea Bollini (andrea.bollini at 4science.it) */ +@LinksRest(links = { + @LinkRest( + name = ItemRest.RELATIONSHIPS, + linkClass = RelationshipRest.class, + method = "getItemRelationships", + embedOptional = true + ) +}) public class ItemRest extends DSpaceObjectRest { public static final String NAME = "item"; public static final String CATEGORY = RestAddressableModel.CORE; + public static final String RELATIONSHIPS = "relationships"; private boolean inArchive = false; private boolean discoverable = false; private boolean withdrawn = false; @@ -31,8 +40,6 @@ public class ItemRest extends DSpaceObjectRest { private CollectionRest templateItemOf; List bitstreams; - List relationships; - @Override public String getCategory() { return CATEGORY; @@ -101,14 +108,4 @@ public class ItemRest extends DSpaceObjectRest { public void setBitstreams(List bitstreams) { this.bitstreams = bitstreams; } - - @LinkRest(linkClass = RelationshipRest.class) - @JsonIgnore - public List getRelationships() { - return relationships; - } - - public void setRelationships(List relationships) { - this.relationships = relationships; - } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRelationshipLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRelationshipLinkRepository.java new file mode 100644 index 0000000000..21a139b4e5 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRelationshipLinkRepository.java @@ -0,0 +1,68 @@ +/** + * 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.sql.SQLException; +import java.util.List; +import java.util.UUID; +import javax.annotation.Nullable; +import javax.servlet.http.HttpServletRequest; + +import org.dspace.app.rest.converter.ConverterService; +import org.dspace.app.rest.model.ItemRest; +import org.dspace.app.rest.model.RelationshipRest; +import org.dspace.content.Item; +import org.dspace.content.Relationship; +import org.dspace.content.service.ItemService; +import org.dspace.content.service.RelationshipService; +import org.dspace.core.Context; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Component; + +/** + * Link repository for "relationships" subresource of an individual item. + */ +@Component(ItemRest.CATEGORY + "." + ItemRest.NAME + "." + ItemRest.RELATIONSHIPS) +public class ItemRelationshipLinkRepository extends AbstractDSpaceRestRepository + implements LinkRestRepository { + + @Autowired + RelationshipService relationshipService; + + @Autowired + ItemService itemService; + + @Autowired + ConverterService converter; + + //@PreAuthorize("hasPermission(#itemId, 'ITEM', 'READ')") + public Page getItemRelationships(@Nullable HttpServletRequest request, + UUID itemId, + @Nullable Pageable optionalPageable, + @Nullable String projection) { + try { + Context context = obtainContext(); + Item item = itemService.find(context, itemId); + if (item == null) { + return null; + } + Pageable pageable = optionalPageable != null ? optionalPageable : new PageRequest(0, 20); + Integer limit = pageable == null ? null : pageable.getPageSize(); + Integer offset = pageable == null ? null : pageable.getOffset(); + int total = relationshipService.countByItem(context, item); + List relationships = relationshipService.findByItem(context, item, limit, offset); + return new PageImpl<>(relationships, pageable, total).map(converter::toRest); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} From b67a67c2b8901b3e3e11dc68eca82b6b1d8a00ac Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Thu, 31 Oct 2019 10:29:30 -0400 Subject: [PATCH 04/20] DS-3533 Use list projection for ItemRestRepository.findALl --- .../org/dspace/app/rest/repository/ItemRestRepository.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java index ce260f88fa..5b4d923199 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java @@ -26,6 +26,8 @@ import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.ItemRest; import org.dspace.app.rest.model.patch.Patch; +import org.dspace.app.rest.projection.ListProjection; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.repository.patch.ItemPatch; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Collection; @@ -112,7 +114,8 @@ public class ItemRestRepository extends DSpaceObjectRestRepository page = new PageImpl(items, pageable, total).map(converter::toRest); + Page page = new PageImpl<>(items, pageable, total).map( + (item) -> converter.toRest(item, ListProjection.NAME)); return page; } From 71c81d28cffcaa61ebd3c35b7b318352fd62016e Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Thu, 31 Oct 2019 14:50:57 -0400 Subject: [PATCH 05/20] DS-3533 Fix checkstyle issues --- .../org/dspace/app/rest/repository/ItemRestRepository.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java index 5b4d923199..d10b149015 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java @@ -27,7 +27,6 @@ import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.ItemRest; import org.dspace.app.rest.model.patch.Patch; import org.dspace.app.rest.projection.ListProjection; -import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.repository.patch.ItemPatch; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Collection; @@ -114,9 +113,7 @@ public class ItemRestRepository extends DSpaceObjectRestRepository page = new PageImpl<>(items, pageable, total).map( - (item) -> converter.toRest(item, ListProjection.NAME)); - return page; + return new PageImpl<>(items, pageable, total).map((item) -> converter.toRest(item, ListProjection.NAME)); } @Override From 640c9071ef216bc8a510f37410197a65554760a2 Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Thu, 31 Oct 2019 15:59:31 -0400 Subject: [PATCH 06/20] DS-3533 Add javadocs for new classes --- .../app/rest/converter/ConverterService.java | 286 ++++++++++++------ .../rest/projection/AbstractProjection.java | 3 + .../rest/projection/DefaultProjection.java | 3 + .../app/rest/projection/ListProjection.java | 3 + .../app/rest/projection/Projection.java | 76 +++++ 5 files changed, 283 insertions(+), 88 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java index bf0b92b550..9e579b37f5 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java @@ -17,11 +17,12 @@ import javax.annotation.Nullable; import javax.annotation.PostConstruct; import org.apache.log4j.Logger; +import org.dspace.app.rest.link.HalLinkFactory; import org.dspace.app.rest.link.HalLinkService; import org.dspace.app.rest.model.RestAddressableModel; import org.dspace.app.rest.model.RestModel; -import org.dspace.app.rest.model.hateoas.DSpaceResource; import org.dspace.app.rest.model.hateoas.HALResource; +import org.dspace.app.rest.projection.DefaultProjection; import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.utils.Utils; import org.springframework.beans.factory.annotation.Autowired; @@ -30,11 +31,13 @@ import org.springframework.context.annotation.ClassPathScanningCandidateComponen import org.springframework.core.type.filter.AssignableTypeFilter; import org.springframework.hateoas.Resource; import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; /** - * Service to convert domain objects from the service layer to rest and resource form on the way out of DSpace. + * Converts domain objects from the DSpace service layer to rest objects, and from rest objects to resource + * objects, applying {@link Projection}s where applicable. */ -@Component +@Service public class ConverterService { private static final Logger log = Logger.getLogger(ConverterService.class); @@ -57,17 +60,205 @@ public class ConverterService { @Autowired private List projections; + /** + * Converts the given model object to rest object, using the appropriate {@link DSpaceConverter}. + * + * @param modelObject the model object, which may be a JPA entity or other class provided by the DSpace + * service layer. + * @param the type of model object. A converter {@link Component} must exist that takes this as input. + * @param the inferred return type. + * @return the converted object. If it's a {@link RestAddressableModel}, its + * {@link RestAddressableModel#getProjection()} will be {@link DefaultProjection}. + * @throws IllegalArgumentException if there is no compatible converter. + * @throws ClassCastException if the converter's return type is not compatible with the inferred return type. + */ + public R toRest(M modelObject) { + return toRest(modelObject, null); + } + + /** + * Converts the given model object to a rest object, using the appropriate {@link DSpaceConverter}. + *

+ * The projection's {@link Projection#transformModel(Object)} method will be automatically applied + * before conversion. If the rest object is a {@link RestModel}, the projection's + * {@link Projection#transformRest(RestModel)} method will be automatically called after conversion. + * If the rest object is a {@link RestAddressableModel}, its {@code projection} field will also be set so + * that a subsequent call to {@link #toResource(RestModel)} will respect the projection without it + * having to be provided as an argument again. + *

+ * + * @param modelObject the model object, which may be a JPA entity or other class provided by the DSpace + * service layer. + * @param projectionName the name of the projection to use. If given as {@code null}, the default no-op + * projection, {@link DefaultProjection} will be used. + * @param the type of model object. A converter {@link Component} must exist that takes this as input. + * @param the inferred return type. + * @return the converted object. If it's a {@link RestAddressableModel}, its + * {@link RestAddressableModel#getProjection()} will be set to the named projection. + * @throws IllegalArgumentException if there is no compatible converter or no such projection. + * @throws ClassCastException if the converter's return type is not compatible with the inferred return type. + */ + public R toRest(M modelObject, @Nullable String projectionName) { + Projection projection = projectionName == null ? Projection.DEFAULT : requireProjection(projectionName); + M transformedModel = projection.transformModel(modelObject); + DSpaceConverter converter = requireConverter(modelObject.getClass()); + R restObject = converter.convert(transformedModel); + if (restObject instanceof RestModel) { + if (restObject instanceof RestAddressableModel) { + RestAddressableModel ram = projection.transformRest((RestAddressableModel) restObject); + ram.setProjection(projection); + return (R) ram; + } + return (R) projection.transformRest((RestModel) restObject); + } + return restObject; + } + + /** + * Gets the converter supporting the given class as input. + * + * @param sourceClass the desired converter's input type. + * @param the converter's input type. + * @param the converter's output type. + * @return the converter. + * @throws IllegalArgumentException if there is no such converter. + */ + DSpaceConverter getConverter(Class sourceClass) { + return (DSpaceConverter) requireConverter(sourceClass); + } + + /** + * Converts the given rest object to a {@link HALResource} object, assigning the named projection beforehand, + * if it is a {@link RestAddressableModel}. + *

+ * After the projection is assigned, behavior of this method is exactly the same as {@link #toResource(RestModel)}. + *

+ * + * @param restObject the input rest object. + * @param projectionName the name of the projection to assign and use. + * @param the return type, a subclass of {@link HALResource}. + * @return the fully converted resource, with all automatic links and embeds applied. + * @throws IllegalArgumentException if there is no such projection. + */ + public T toResource(RestModel restObject, String projectionName) { + if (restObject instanceof RestAddressableModel) { + ((RestAddressableModel) restObject).setProjection(requireProjection(projectionName)); + } + return toResource(restObject); + } + + /** + * Converts the given rest object to a {@link HALResource} object. + *

+ * If the rest object is a {@link RestAddressableModel}, the projection returned by + * {@link RestAddressableModel#getProjection()} will be used to determine which optional + * embeds and links will be added, and {@link Projection#transformResource(HALResource)} + * will be automatically called before returning the final, fully converted resource. + *

+ * In all cases, the {@link HalLinkService} will be used immediately after the resource is constructed, + * to ensure all {@link HalLinkFactory}s have had a chance to add links as needed. + *

+ * + * @param restObject the input rest object. + * @param the return type, a subclass of {@link HALResource}. + * @return the fully converted resource, with all automatic links and embeds applied. + * @throws IllegalArgumentException if there is no such projection. + */ + public T toResource(RestModel restObject) { + T halResource = getResource(restObject); + if (restObject instanceof RestAddressableModel) { + utils.embedOrLinkClassLevelRels(halResource); + halLinkService.addLinks(halResource); + Projection projection = ((RestAddressableModel) restObject).getProjection(); + return projection.transformResource(halResource); + } else { + halLinkService.addLinks(halResource); + } + return halResource; + } + + /** + * Creates and returns an instance of the appropriate {@link HALResource} subclass for the given rest object. + *

+ * Note: Only two forms of constructor are supported for resources that can be created with this method: + * A one-argument constructor taking the wrapped {@link RestModel}, and a two-argument constructor also taking + * a {@link Utils} instance. If both are found in a candidate resource's constructor, the two-argument form + * will be used. + *

+ * + * @param restObject the rest object to wrap. + * @param the return type, a subclass of {@link HALResource}. + * @return a new resource instance of the appropriate type. + */ + private T getResource(RestModel restObject) { + Constructor constructor = resourceConstructors.get(restObject.getClass()); + try { + if (constructor.getParameterCount() == 2) { + return (T) constructor.newInstance(restObject, utils); + } else { + return (T) constructor.newInstance(restObject); + } + } catch (InvocationTargetException e) { + if (e.getTargetException() instanceof RuntimeException) { + throw (RuntimeException) e.getTargetException(); + } + throw new RuntimeException(e); + } catch (InstantiationException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + /** + * Gets the projection with the given name or throws an {@link IllegalArgumentException}. + * + * @param projectionName the projection name. + * @return the projection. + * @throws IllegalArgumentException if not found. + */ + private Projection requireProjection(String projectionName) { + if (!projectionMap.containsKey(projectionName)) { + throw new IllegalArgumentException("No such projection: " + projectionName); + } + return projectionMap.get(projectionName); + } + + /** + * Gets the converter that supports the given source/input class or throws an {@link IllegalArgumentException}. + * + * @param sourceClass the source/input class. + * @return the converter. + * @throws IllegalArgumentException if not found. + */ + private DSpaceConverter requireConverter(Class sourceClass) { + if (converterMap.containsKey(sourceClass)) { + return converterMap.get(sourceClass); + } + for (Class converterSourceClass : converterMap.keySet()) { + if (converterSourceClass.isAssignableFrom(sourceClass)) { + return converterMap.get(converterSourceClass); + } + } + throw new IllegalArgumentException("No converter found to get rest class from " + sourceClass); + } + + /** + * Populates maps of injected components and constructors to be used by this service's public methods. + */ @PostConstruct private void initialize() { + // put all available projections in a map keyed by name for (Projection projection : projections) { projectionMap.put(projection.getName(), projection); } projectionMap.put(Projection.DEFAULT.getName(), Projection.DEFAULT); + // put all available converters in a map keyed by model (input) class for (DSpaceConverter converter : converters) { converterMap.put(converter.getModelClass(), converter); } + // scan all resource classes and look for compatible rest classes (by naming convention), + // creating a map of resource constructors keyed by rest class, for later use. ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false); provider.addIncludeFilter(new AssignableTypeFilter(Resource.class)); Set beanDefinitions = provider.findCandidateComponents( @@ -96,94 +287,13 @@ public class ConverterService { if (compatibleConstructor != null) { resourceConstructors.put(restClass, compatibleConstructor); } else { - logSkipping(resourceClassName, "compatible constructor not found"); + log.warn("Skipping registration of resource class " + resourceClassName + + "; compatible constructor not found"); } } catch (ClassNotFoundException e) { - logSkipping(resourceClassName, "rest class not found: " + restClassName); + log.warn("Skipping registration of resource class " + resourceClassName + + "; rest class not found: " + restClassName); } } } - - private void logSkipping(String resourceClassName, String reason) { - log.warn("Skipping registration of resource class " + resourceClassName + "; " + reason); - } - - private Projection requireProjection(String projectionName) { - if (!projectionMap.containsKey(projectionName)) { - throw new IllegalArgumentException("No such projection: " + projectionName); - } - return projectionMap.get(projectionName); - } - - public T toRest(Object modelObject) { - return toRest(modelObject, null); - } - - public R toRest(M modelObject, @Nullable String projectionName) { - Projection projection = projectionName == null ? Projection.DEFAULT : requireProjection(projectionName); - M transformedModel = projection.transformModel(modelObject); - DSpaceConverter converter = requireConverter(modelObject.getClass()); - R restObject = converter.convert(transformedModel); - if (restObject instanceof RestAddressableModel) { - RestAddressableModel ram = projection.transformRest((RestAddressableModel) restObject); - ram.setProjection(projection); - return (R) ram; - } - return restObject; - } - - public DSpaceConverter getConverter(Class sourceClass) { - return (DSpaceConverter) requireConverter(sourceClass); - } - - private DSpaceConverter requireConverter(Class sourceClass) { - if (converterMap.containsKey(sourceClass)) { - return converterMap.get(sourceClass); - } - for (Class converterSourceClass : converterMap.keySet()) { - if (converterSourceClass.isAssignableFrom(sourceClass)) { - return converterMap.get(converterSourceClass); - } - } - throw new IllegalArgumentException("No converter found to get rest class from " + sourceClass); - } - - public T toResource(RestModel restObject, @Nullable String projectionName) { - if (restObject instanceof RestAddressableModel) { - ((RestAddressableModel) restObject).setProjection(requireProjection(projectionName)); - } - return toResource(restObject); - } - - public T toResource(RestModel restObject) { - T halResource = getResource(restObject); - if (restObject instanceof RestAddressableModel) { - utils.embedOrLinkClassLevelRels(halResource); - halLinkService.addLinks(halResource); - Projection projection = ((RestAddressableModel) restObject).getProjection(); - return projection.transformResource(halResource); - } else { - halLinkService.addLinks(halResource); - } - return halResource; - } - - private T getResource(RestModel restObject) { - Constructor constructor = resourceConstructors.get(restObject.getClass()); - try { - if (constructor == null) { - constructor = DSpaceResource.class.getDeclaredConstructor(); - } - if (constructor.getParameterCount() == 2) { - return (T) constructor.newInstance(restObject, utils); - } else { - return (T) constructor.newInstance(restObject); - } - } catch (InstantiationException - | IllegalAccessException - | InvocationTargetException - | NoSuchMethodException e) { - throw new RuntimeException(e); - } - } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/AbstractProjection.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/AbstractProjection.java index 783c70fb86..563f33f48c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/AbstractProjection.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/AbstractProjection.java @@ -11,6 +11,9 @@ import org.dspace.app.rest.model.LinkRest; import org.dspace.app.rest.model.RestModel; import org.dspace.app.rest.model.hateoas.HALResource; +/** + * Abstract base class for projections. By default each method has no effect unless overridden by a subclass. + */ public abstract class AbstractProjection implements Projection { @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/DefaultProjection.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/DefaultProjection.java index f4d0f267a0..0d9395a11f 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/DefaultProjection.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/DefaultProjection.java @@ -7,6 +7,9 @@ */ package org.dspace.app.rest.projection; +/** + * The default projection, which has no effect. + */ public class DefaultProjection extends AbstractProjection { public final static String NAME = "default"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/ListProjection.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/ListProjection.java index 54ad4c8bf5..9129f5221f 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/ListProjection.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/ListProjection.java @@ -11,6 +11,9 @@ import org.dspace.app.rest.model.LinkRest; import org.dspace.app.rest.model.hateoas.HALResource; import org.springframework.stereotype.Component; +/** + * A projection that provides an abbreviated form of any resource that omits all optional embeds. + */ @Component public class ListProjection extends AbstractProjection { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/Projection.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/Projection.java index 7a3c2abf7a..290a4e073c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/Projection.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/projection/Projection.java @@ -7,10 +7,56 @@ */ package org.dspace.app.rest.projection; +import javax.persistence.Entity; + import org.dspace.app.rest.model.LinkRest; import org.dspace.app.rest.model.RestModel; import org.dspace.app.rest.model.hateoas.HALResource; +import org.dspace.app.rest.repository.DSpaceRestRepository; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.RestController; +/** + * A pluggable, uniquely-named {@link Component} that provides a way to change how a domain object is represented, + * at one or more points in its lifecycle on the way to its being exposed via the REST API. + * + *

The object lifecycle

+ * + *

+ * While fulfilling a typical REST request, a DSpace domain object takes three major forms, in order: + *

+ * + *
    + *
  • A model object provided by some service. This is typically a JPA {@link Entity}.
  • + *
  • A {@link RestModel} object provided by a {@link DSpaceRestRepository}.
  • + *
  • A {@link HALResource} object provided by the {@link RestController} to Spring, which then + * serializes it as JSON for the client to consume.
  • + *
+ * + *

What a projection can modify, and when

+ * + * A {@code Projection} implementation is capable of adding to or omitting information from the object + * in any of these forms, at the following points in time: + * + *
    + *
  • Before it is converted to a {@link RestModel}, the projection may modify it + * via {@link #transformModel(Object)}.
  • + *
  • After it is converted to a {@link RestModel}, the projection may modify it + * via {@link #transformRest(RestModel)}.
  • + *
  • During conversion to a {@link HALResource}, the projection may opt out of certain annotation-discovered + * HAL embeds and links via {@link #allowOptionalEmbed(HALResource, LinkRest)} + * and {@link #allowOptionalLink(HALResource, LinkRest)}.
  • + *
  • After conversion to a {@link HALResource}, the projection may modify it + * via {@link #transformResource(HALResource)}.
  • + *
+ * + *

How a projection is chosen

+ * + * When a REST request is made, the use of a projection may be explicit, as when it is provided as an argument + * to the request, e.g. {@code /items/{uuid}?projection={projectionName}}. It may also be implicit, as when the + * {@link ListProjection} is used automatically, in order to provide an abbreviated representation when serving + * a collection of resources. + */ public interface Projection { /** @@ -25,10 +71,40 @@ public interface Projection { */ String getName(); + /** + * Transforms the original model object (e.g. JPA entity) before conversion to a {@link RestModel}. + * + * This is a good place to omit data for certain properties that should not be included in the object's + * representation as a {@link HALResource}. Omitting these properties early helps to prevent unnecessary + * database calls for lazy-loaded properties that are unwanted for the projection. + * + * @param modelObject the original model object, which may be of any type. + * @param the return type, which must be the same type as the given model object. + * @return the transformed model object, or the original, if the projection does not modify it. + */ T transformModel(T modelObject); + /** + * Transforms the rest object after it was converted from a model object. + * + * This may add data to, or omit data from the rest representation of the object. + * + * @param restObject the rest object. + * @param the return type, which must be of the same type as the given rest object. + * @return the transformed rest object, or the original, if the projection does not modify it. + */ T transformRest(T restObject); + /** + * Transforms the resource object after it has been constructed and any constructor or annotation-based + * links and embeds have been added. + * + * This may add data to, or omit data from the HAL resource representation of the object. + * + * @param halResource the resource object. + * @param the return type, which must be of the same type as the given resource object. + * @return the transformed resource object, or the original, if the projection does not modify it. + */ T transformResource(T halResource); /** From 7eb15083875279d811e0eec9ab56706ed647e659 Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Tue, 5 Nov 2019 09:44:12 -0500 Subject: [PATCH 07/20] DS-3533 Apply projections uniformly --- .../rest/AuthenticationRestController.java | 14 ++-- .../app/rest/BitstreamRestController.java | 4 +- .../app/rest/DiscoveryRestController.java | 5 +- .../app/rest/HarvesterMetadataController.java | 4 +- .../app/rest/IdentifierRestController.java | 7 +- ...mOwningCollectionUpdateRestController.java | 3 +- .../dspace/app/rest/ItemUploadController.java | 3 +- .../rest/MappedCollectionRestController.java | 3 +- .../app/rest/MappedItemRestController.java | 3 +- .../rest/RelationshipTypeRestController.java | 9 ++- .../app/rest/RestResourceController.java | 69 +++++++------------ .../app/rest/UUIDLookupRestController.java | 6 +- .../converter/AInprogressItemConverter.java | 11 +-- .../AuthorityEntryRestConverter.java | 6 +- .../converter/AuthorityRestConverter.java | 6 +- .../rest/converter/BitstreamConverter.java | 10 +-- .../converter/BitstreamFormatConverter.java | 4 +- .../rest/converter/BrowseIndexConverter.java | 4 +- .../rest/converter/ClaimedTaskConverter.java | 11 +-- .../rest/converter/CollectionConverter.java | 13 ++-- .../rest/converter/CommunityConverter.java | 11 +-- .../app/rest/converter/ConverterService.java | 66 +++++------------- .../app/rest/converter/DSpaceConverter.java | 7 +- .../rest/converter/DSpaceObjectConverter.java | 4 +- .../DiscoverConfigurationConverter.java | 14 +++- .../DiscoverFacetResultsConverter.java | 25 ++++--- .../DiscoverFacetValueConverter.java | 4 +- .../converter/DiscoverFacetsConverter.java | 12 ++-- .../converter/DiscoverResultConverter.java | 23 ++++--- .../app/rest/converter/EPersonConverter.java | 12 ++-- .../rest/converter/EntityTypeConverter.java | 10 +-- .../app/rest/converter/GroupConverter.java | 7 +- .../HarvestedCollectionConverter.java | 15 ++-- .../app/rest/converter/ItemConverter.java | 13 ++-- .../app/rest/converter/MetadataConverter.java | 3 +- .../converter/MetadataFieldConverter.java | 8 ++- .../converter/MetadataSchemaConverter.java | 6 +- .../converter/MetadataValueConverter.java | 9 +-- .../app/rest/converter/PoolTaskConverter.java | 10 +-- .../rest/converter/RelationshipConverter.java | 13 ++-- .../converter/RelationshipTypeConverter.java | 15 ++-- .../converter/ResourcePolicyConverter.java | 4 +- .../app/rest/converter/SiteConverter.java | 8 +-- .../SubmissionDefinitionConverter.java | 9 ++- .../converter/SubmissionFormConverter.java | 4 +- .../converter/SubmissionSectionConverter.java | 4 +- .../rest/converter/WorkflowItemConverter.java | 6 +- .../converter/WorkspaceItemConverter.java | 7 +- .../link/AuthorityEntryHalLinkFactory.java | 6 +- .../rest/link/BrowseEntryHalLinkFactory.java | 2 +- .../link/SubmissionSectionHalLinkFactory.java | 4 +- .../relation/EntityTypeHalLinkFactory.java | 3 +- .../relation/RelationshipHalLinkFactory.java | 4 +- .../rest/model/AInprogressSubmissionRest.java | 6 +- .../app/rest/model/BitstreamFormatRest.java | 2 +- .../app/rest/model/ClaimedTaskRest.java | 2 +- .../app/rest/model/DiscoveryResultsRest.java | 1 - .../dspace/app/rest/model/EPersonRest.java | 2 +- .../app/rest/model/MetadataFieldRest.java | 2 +- .../app/rest/model/MetadataSchemaRest.java | 2 +- .../dspace/app/rest/model/PoolTaskRest.java | 2 +- .../model/RelationshipTypeRestWrapper.java | 2 - .../app/rest/model/SearchEventRest.java | 13 ---- .../app/rest/model/SearchResultEntryRest.java | 1 - .../app/rest/model/SearchResultsRest.java | 2 - .../rest/model/SubmissionDefinitionRest.java | 2 +- .../app/rest/model/SubmissionUploadRest.java | 2 +- .../app/rest/model/WorkflowItemRest.java | 2 +- .../app/rest/model/WorkspaceItemRest.java | 2 +- .../AuthorityEntryLinkRepository.java | 9 +-- .../AuthorityEntryValueLinkRepository.java | 5 +- .../repository/AuthorityRestRepository.java | 6 +- .../BitstreamFormatRestRepository.java | 11 +-- .../repository/BitstreamRestRepository.java | 7 +- .../repository/BrowseEntryLinkRepository.java | 5 +- .../repository/BrowseIndexRestRepository.java | 7 +- .../repository/BrowseItemLinkRepository.java | 11 +-- .../repository/ClaimedTaskRestRepository.java | 5 +- .../repository/CollectionRestRepository.java | 19 +++-- .../repository/CommunityRestRepository.java | 21 +++--- .../DSpaceObjectRestRepository.java | 3 +- .../repository/DiscoveryRestRepository.java | 14 ++-- .../repository/EPersonRestRepository.java | 14 ++-- .../repository/EntityTypeRestRepository.java | 7 +- .../rest/repository/GroupRestRepository.java | 9 ++- .../HarvestedCollectionRestRepository.java | 15 ++-- .../ItemRelationshipLinkRepository.java | 6 +- .../rest/repository/ItemRestRepository.java | 11 +-- .../repository/LicenseRestLinkRepository.java | 4 +- .../MetadataFieldRestRepository.java | 15 ++-- .../MetadataSchemaRestRepository.java | 11 +-- .../repository/PoolTaskRestRepository.java | 7 +- .../RelationshipRestRepository.java | 17 +++-- .../RelationshipTypeRestRepository.java | 7 +- .../ResourcePolicyRestRepository.java | 2 +- .../rest/repository/SiteRestRepository.java | 7 +- .../SubmissionDefinitionRestRepository.java | 10 ++- .../SubmissionFormRestRepository.java | 7 +- .../SubmissionPanelRestRepository.java | 7 +- .../SubmissionUploadRestRepository.java | 14 +++- .../WorkflowItemRestRepository.java | 15 ++-- .../WorkspaceItemRestRepository.java | 17 +++-- .../app/rest/submit/SubmissionService.java | 7 +- .../dspace/app/rest/utils/AuthorityUtils.java | 11 +-- .../java/org/dspace/app/rest/utils/Utils.java | 40 +++++++++-- .../rest/BitstreamFormatRestRepositoryIT.java | 17 ++--- .../app/rest/CollectionRestRepositoryIT.java | 5 +- .../app/rest/CommunityRestRepositoryIT.java | 5 +- .../rest/MetadataSchemaRestRepositoryIT.java | 3 +- .../DiscoverConfigurationConverterTest.java | 23 ++++--- 110 files changed, 580 insertions(+), 444 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/AuthenticationRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/AuthenticationRestController.java index f123b17656..6e282d8552 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/AuthenticationRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/AuthenticationRestController.java @@ -19,6 +19,7 @@ import org.dspace.app.rest.model.AuthnRest; import org.dspace.app.rest.model.EPersonRest; import org.dspace.app.rest.model.hateoas.AuthenticationStatusResource; import org.dspace.app.rest.model.hateoas.AuthnResource; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.utils.ContextUtil; import org.dspace.app.rest.utils.Utils; import org.dspace.core.Context; @@ -70,20 +71,23 @@ public class AuthenticationRestController implements InitializingBean { @RequestMapping(method = RequestMethod.GET) public AuthnResource authn() { - AuthnResource authnResource = converter.toResource(new AuthnRest()); - return authnResource; + AuthnRest authnRest = new AuthnRest(); + authnRest.setProjection(utils.obtainProjection()); + return converter.toResource(authnRest); } @RequestMapping(value = "/status", method = RequestMethod.GET) public AuthenticationStatusResource status(HttpServletRequest request) throws SQLException { Context context = ContextUtil.obtainContext(request); EPersonRest ePersonRest = null; + Projection projection = utils.obtainProjection(); if (context.getCurrentUser() != null) { - ePersonRest = ePersonConverter.fromModelWithGroups(context, context.getCurrentUser()); + ePersonRest = ePersonConverter.fromModelWithGroups(context, context.getCurrentUser(), projection); } - AuthenticationStatusResource authenticationStatusResource = converter.toResource( - new AuthenticationStatusRest(ePersonRest)); + AuthenticationStatusRest authenticationStatusRest = new AuthenticationStatusRest(ePersonRest); + authenticationStatusRest.setProjection(projection); + AuthenticationStatusResource authenticationStatusResource = converter.toResource(authenticationStatusRest); return authenticationStatusResource; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/BitstreamRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/BitstreamRestController.java index 88c7620b4e..b320371fa1 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/BitstreamRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/BitstreamRestController.java @@ -26,6 +26,7 @@ import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.model.BitstreamRest; import org.dspace.app.rest.model.hateoas.BitstreamResource; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.utils.ContextUtil; import org.dspace.app.rest.utils.MultipartFileSender; import org.dspace.app.rest.utils.Utils; @@ -238,6 +239,7 @@ public class BitstreamRestController { context.commit(); - return converter.toResource(converter.toRest(context.reloadEntity(bitstream))); + BitstreamRest bitstreamRest = converter.toRest(context.reloadEntity(bitstream), Projection.DEFAULT); + return converter.toResource(bitstreamRest); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/DiscoveryRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/DiscoveryRestController.java index 1e3aaacac1..6be17ae24c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/DiscoveryRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/DiscoveryRestController.java @@ -143,9 +143,8 @@ public class DiscoveryRestController implements InitializingBean { } //Get the Search results in JSON format - SearchResultsRest searchResultsRest = null; - searchResultsRest = discoveryRestRepository - .getSearchObjects(query, dsoType, dsoScope, configuration, searchFilters, page); + SearchResultsRest searchResultsRest = discoveryRestRepository + .getSearchObjects(query, dsoType, dsoScope, configuration, searchFilters, page, utils.obtainProjection()); //Convert the Search JSON results to paginated HAL resources SearchResultsResource searchResultsResource = new SearchResultsResource(searchResultsRest, utils, page); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/HarvesterMetadataController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/HarvesterMetadataController.java index de23aac866..dad1a2eb75 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/HarvesterMetadataController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/HarvesterMetadataController.java @@ -18,7 +18,6 @@ import org.dspace.app.rest.model.HarvesterMetadataRest; import org.dspace.app.rest.model.hateoas.HarvesterMetadataResource; import org.dspace.app.rest.utils.Utils; import org.dspace.harvest.OAIHarvester; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -50,10 +49,11 @@ public class HarvesterMetadataController { */ @RequestMapping(method = RequestMethod.GET) public HarvesterMetadataResource get(HttpServletRequest request, - HttpServletResponse response) { + HttpServletResponse response) { List> configs = OAIHarvester.getAvailableMetadataFormats(); HarvesterMetadataRest data = new HarvesterMetadataRest(); + data.setProjection(utils.obtainProjection()); data.setConfigs(configs); HarvesterMetadataResource resource = converter.toResource(data); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/IdentifierRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/IdentifierRestController.java index bb84a0c9e1..09b6468b3c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/IdentifierRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/IdentifierRestController.java @@ -13,7 +13,6 @@ import java.io.IOException; import java.net.URI; import java.sql.SQLException; import java.util.Arrays; - import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -22,6 +21,7 @@ import org.atteo.evo.inflector.English; import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.DSpaceObjectRest; import org.dspace.app.rest.utils.ContextUtil; +import org.dspace.app.rest.utils.Utils; import org.dspace.content.DSpaceObject; import org.dspace.core.Context; import org.dspace.identifier.IdentifierNotFoundException; @@ -55,6 +55,9 @@ public class IdentifierRestController implements InitializingBean { @Autowired private ConverterService converter; + @Autowired + private Utils utils; + @Autowired private DiscoverableEndpointsService discoverableEndpointsService; @@ -84,7 +87,7 @@ public class IdentifierRestController implements InitializingBean { try { dso = identifierService.resolve(context, id); if (dso != null) { - DSpaceObjectRest dsor = converter.toRest(dso); + DSpaceObjectRest dsor = converter.toRest(dso, utils.obtainProjection()); URI link = linkTo(dsor.getController(), dsor.getCategory(), English.plural(dsor.getType())) .slash(dsor.getId()).toUri(); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemOwningCollectionUpdateRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemOwningCollectionUpdateRestController.java index 3ba8fa4b06..5432bda670 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemOwningCollectionUpdateRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemOwningCollectionUpdateRestController.java @@ -20,6 +20,7 @@ import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.CollectionRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.utils.ContextUtil; import org.dspace.app.rest.utils.Utils; import org.dspace.authorize.AuthorizeException; @@ -97,7 +98,7 @@ public class ItemOwningCollectionUpdateRestController { if (targetCollection == null) { return null; } - return converter.toRest(targetCollection); + return converter.toRest(targetCollection, Projection.DEFAULT); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemUploadController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemUploadController.java index 8c290058c8..5f2cd66648 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemUploadController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemUploadController.java @@ -22,6 +22,7 @@ import org.dspace.app.rest.converter.MetadataConverter; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.BitstreamRest; import org.dspace.app.rest.model.hateoas.BitstreamResource; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.utils.ContextUtil; import org.dspace.app.rest.utils.Utils; import org.dspace.authorize.AuthorizeException; @@ -109,7 +110,7 @@ public class ItemUploadController { log.error(message, e); throw new RuntimeException(message, e); } - return converter.toResource(converter.toRest(bitstream)); + return converter.toResource(converter.toRest(bitstream, Projection.DEFAULT)); } /** diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/MappedCollectionRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/MappedCollectionRestController.java index a921a8ec36..95287b3253 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/MappedCollectionRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/MappedCollectionRestController.java @@ -100,11 +100,12 @@ public class MappedCollectionRestController { List mappingCollectionRest = new LinkedList<>(); for (Collection collection : collections) { if (collection.getID() != owningCollectionUuid) { - mappingCollectionRest.add(converter.toRest(collection)); + mappingCollectionRest.add(converter.toRest(collection, utils.obtainProjection())); } } MappedCollectionRestWrapper mappingCollectionRestWrapper = new MappedCollectionRestWrapper(); + mappingCollectionRestWrapper.setProjection(utils.obtainProjection()); mappingCollectionRestWrapper.setMappedCollectionRestList(mappingCollectionRest); mappingCollectionRestWrapper.setItem(item); MappedCollectionResourceWrapper mappingCollectionResourceWrapper = diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/MappedItemRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/MappedItemRestController.java index 9ccbeebd2f..d613e8dc0f 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/MappedItemRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/MappedItemRestController.java @@ -95,11 +95,12 @@ public class MappedItemRestController { while (itemIterator.hasNext()) { Item item = itemIterator.next(); if (item.getOwningCollection().getID() != uuid) { - mappedItemRestList.add(converter.toRest(item)); + mappedItemRestList.add(converter.toRest(item, utils.obtainProjection())); } } MappedItemRestWrapper mappedItemRestWrapper = new MappedItemRestWrapper(); + mappedItemRestWrapper.setProjection(utils.obtainProjection()); mappedItemRestWrapper.setMappedItemRestList(mappedItemRestList); mappedItemRestWrapper.setCollectionUuid(uuid); MappedItemResourceWrapper mappedItemResourceWrapper = diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RelationshipTypeRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RelationshipTypeRestController.java index d71085f285..490eefb6c4 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RelationshipTypeRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RelationshipTypeRestController.java @@ -18,6 +18,7 @@ import org.dspace.app.rest.link.HalLinkService; import org.dspace.app.rest.model.RelationshipTypeRest; import org.dspace.app.rest.model.RelationshipTypeRestWrapper; import org.dspace.app.rest.model.hateoas.RelationshipTypeResourceWrapper; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.utils.ContextUtil; import org.dspace.app.rest.utils.Utils; import org.dspace.content.EntityType; @@ -67,7 +68,8 @@ public class RelationshipTypeRestController { * @throws SQLException If something goes wrong */ @RequestMapping(method = RequestMethod.GET) - public RelationshipTypeResourceWrapper retrieve(@PathVariable Integer id, HttpServletResponse response, + public RelationshipTypeResourceWrapper retrieve(@PathVariable Integer id, + HttpServletResponse response, HttpServletRequest request) throws SQLException { Context context = ContextUtil.obtainContext(request); EntityType entityType = entityTypeService.find(context, id); @@ -75,12 +77,13 @@ public class RelationshipTypeRestController { List relationshipTypeRests = new LinkedList<>(); + Projection projection = utils.obtainProjection(); for (RelationshipType relationshipType : list) { - relationshipTypeRests.add(converter.toRest(relationshipType)); + relationshipTypeRests.add(converter.toRest(relationshipType, projection)); } - RelationshipTypeRestWrapper relationshipTypeRestWrapper = new RelationshipTypeRestWrapper(); + relationshipTypeRestWrapper.setProjection(projection); relationshipTypeRestWrapper.setEntityTypeId(id); relationshipTypeRestWrapper.setEntityTypeLabel(entityType.getLabel()); relationshipTypeRestWrapper.setRelationshipTypeRestList(relationshipTypeRests); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java index ee83bca3af..d3b6ffef80 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java @@ -160,15 +160,13 @@ public class RestResourceController implements InitializingBean { * @param apiCategory * @param model * @param id - * @param projection * @return */ @RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT) @SuppressWarnings("unchecked") public DSpaceResource findOne(@PathVariable String apiCategory, @PathVariable String model, - @PathVariable Integer id, - @RequestParam(required = false) String projection) { - return findOneInternal(apiCategory, model, id, projection); + @PathVariable Integer id) { + return findOneInternal(apiCategory, model, id); } /** @@ -194,15 +192,13 @@ public class RestResourceController implements InitializingBean { * @param apiCategory * @param model * @param id - * @param projection * @return */ @RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG) @SuppressWarnings("unchecked") public DSpaceResource findOne(@PathVariable String apiCategory, @PathVariable String model, - @PathVariable String id, - @RequestParam(required = false) String projection) { - return findOneInternal(apiCategory, model, id, projection); + @PathVariable String id) { + return findOneInternal(apiCategory, model, id); } /** @@ -217,15 +213,13 @@ public class RestResourceController implements InitializingBean { * @param apiCategory * @param model * @param uuid - * @param projection * @return */ @RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID) @SuppressWarnings("unchecked") public DSpaceResource findOne(@PathVariable String apiCategory, @PathVariable String model, - @PathVariable UUID uuid, - @RequestParam(required = false) String projection) { - return findOneInternal(apiCategory, model, uuid, projection); + @PathVariable UUID uuid) { + return findOneInternal(apiCategory, model, uuid); } /** @@ -234,13 +228,10 @@ public class RestResourceController implements InitializingBean { * @param apiCategory * @param model * @param id - * @param projection * @return */ private DSpaceResource findOneInternal(String apiCategory, - String model, ID id, - String projection) { - checkModelPluralForm(apiCategory, model); + String model, ID id) { DSpaceRestRepository repository = utils.getResourceRepository(apiCategory, model); RestAddressableModel modelObject = null; try { @@ -266,7 +257,6 @@ public class RestResourceController implements InitializingBean { * @param rel * @param page * @param assembler - * @param projection * @return */ @RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT + "/{rel}") @@ -274,9 +264,8 @@ public class RestResourceController implements InitializingBean { @PathVariable String apiCategory, @PathVariable String model, @PathVariable Integer id, @PathVariable String rel, Pageable page, - PagedResourcesAssembler assembler, - @RequestParam(required = false) String projection) { - return findRelInternal(request, response, apiCategory, model, id, rel, page, assembler, projection); + PagedResourcesAssembler assembler) { + return findRelInternal(request, response, apiCategory, model, id, rel, page, assembler); } /** @@ -292,7 +281,6 @@ public class RestResourceController implements InitializingBean { * @param rel * @param page * @param assembler - * @param projection * @return */ @RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG + @@ -301,9 +289,8 @@ public class RestResourceController implements InitializingBean { @PathVariable String apiCategory, @PathVariable String model, @PathVariable String id, @PathVariable String rel, Pageable page, - PagedResourcesAssembler assembler, - @RequestParam(required = false) String projection) { - return findRelInternal(request, response, apiCategory, model, id, rel, page, assembler, projection); + PagedResourcesAssembler assembler) { + return findRelInternal(request, response, apiCategory, model, id, rel, page, assembler); } /** @@ -318,7 +305,6 @@ public class RestResourceController implements InitializingBean { * @param rel * @param page * @param assembler - * @param projection * @return */ @RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID + "/{rel}") @@ -326,9 +312,8 @@ public class RestResourceController implements InitializingBean { @PathVariable String apiCategory, @PathVariable String model, @PathVariable UUID uuid, @PathVariable String rel, Pageable page, - PagedResourcesAssembler assembler, - @RequestParam(required = false) String projection) { - return findRelInternal(request, response, apiCategory, model, uuid, rel, page, assembler, projection); + PagedResourcesAssembler assembler) { + return findRelInternal(request, response, apiCategory, model, uuid, rel, page, assembler); } /** @@ -361,7 +346,6 @@ public class RestResourceController implements InitializingBean { * @param relid * @param page * @param assembler - * @param projection * @return */ @RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG + @@ -370,9 +354,8 @@ public class RestResourceController implements InitializingBean { @PathVariable String apiCategory, @PathVariable String model, @PathVariable String id, @PathVariable String rel, @PathVariable String relid, - Pageable page, PagedResourcesAssembler assembler, - @RequestParam(required = false) String projection) throws Throwable { - return findRelEntryInternal(request, response, apiCategory, model, id, rel, relid, page, assembler, projection); + Pageable page, PagedResourcesAssembler assembler) throws Throwable { + return findRelEntryInternal(request, response, apiCategory, model, id, rel, relid, page, assembler); } @@ -751,7 +734,6 @@ public class RestResourceController implements InitializingBean { * @param relid * @param page * @param assembler - * @param projection * @return */ private ResourceSupport findRelEntryInternal(HttpServletRequest request, @@ -759,8 +741,8 @@ public class RestResourceController implements InitializingBean { String apiCategory, String model, String id, String rel, String relid, Pageable page, - PagedResourcesAssembler assembler, - String projection) throws Throwable { + PagedResourcesAssembler assembler) + throws Throwable { checkModelPluralForm(apiCategory, model); DSpaceRestRepository repository = utils.getResourceRepository(apiCategory, model); Class domainClass = repository.getDomainClass(); @@ -770,7 +752,7 @@ public class RestResourceController implements InitializingBean { LinkRestRepository linkRepository = utils.getLinkResourceRepository(apiCategory, model, linkRest.name()); Method linkMethod = utils.requireMethod(linkRepository.getClass(), "getResource"); try { - Object object = linkMethod.invoke(linkRepository, request, id, relid, page, projection); + Object object = linkMethod.invoke(linkRepository, request, id, relid, page, utils.obtainProjection()); Link link = linkTo(this.getClass(), apiCategory, model).slash(id).slash(rel).slash(relid).withSelfRel(); List result = new ArrayList(); @@ -803,17 +785,15 @@ public class RestResourceController implements InitializingBean { * @param apiCategory * @param model * @param uuid - * @param rel * @param page * @param assembler - * @param projection * @return */ private ResourceSupport findRelInternal(HttpServletRequest request, HttpServletResponse response, String apiCategory, String model, ID uuid, String subpath, - Pageable page, PagedResourcesAssembler assembler, - String projection) { + Pageable page, + PagedResourcesAssembler assembler) { checkModelPluralForm(apiCategory, model); DSpaceRestRepository repository = utils.getResourceRepository(apiCategory, model); Class domainClass = repository.getDomainClass(); @@ -827,7 +807,7 @@ public class RestResourceController implements InitializingBean { try { if (Page.class.isAssignableFrom(linkMethod.getReturnType())) { Page pageResult = (Page) linkMethod - .invoke(linkRepository, request, uuid, page, projection); + .invoke(linkRepository, request, uuid, page, utils.obtainProjection(true)); Link link = null; String querystring = request.getQueryString(); @@ -842,7 +822,7 @@ public class RestResourceController implements InitializingBean { return assembler.toResource(halResources, link); } else { RestModel object = (RestModel) linkMethod.invoke(linkRepository, request, uuid, page, - projection); + utils.obtainProjection()); Link link = linkTo(this.getClass(), apiCategory, model).slash(uuid).slash(subpath) .withSelfRel(); HALResource tmpresult = converter.toResource(object); @@ -917,7 +897,6 @@ public class RestResourceController implements InitializingBean { * @param model * @param page * @param assembler - * @param projection * @return */ @RequestMapping(method = RequestMethod.GET) @@ -926,12 +905,10 @@ public class RestResourceController implements InitializingBean { @PathVariable String model, Pageable page, PagedResourcesAssembler assembler, - @RequestParam(required = false) - String projection, HttpServletResponse response) { DSpaceRestRepository repository = utils.getResourceRepository(apiCategory, model); Link link = linkTo(methodOn(this.getClass(), apiCategory, model).findAll(apiCategory, model, - page, assembler, projection, response)) + page, assembler, response)) .withSelfRel(); Page> resources; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/UUIDLookupRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/UUIDLookupRestController.java index 280a91a41f..91555ae026 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/UUIDLookupRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/UUIDLookupRestController.java @@ -21,6 +21,7 @@ import org.apache.log4j.Logger; import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.DSpaceObjectRest; import org.dspace.app.rest.utils.ContextUtil; +import org.dspace.app.rest.utils.Utils; import org.dspace.content.DSpaceObject; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.DSpaceObjectService; @@ -56,6 +57,9 @@ public class UUIDLookupRestController implements InitializingBean { @Autowired private ContentServiceFactory contentServiceFactory; + @Autowired + private Utils utils; + private static final Logger log = Logger.getLogger(UUIDLookupRestController.class); @@ -91,7 +95,7 @@ public class UUIDLookupRestController implements InitializingBean { .getDSpaceObjectServices()) { DSpaceObject dso = dSpaceObjectService.find(context, uuid); if (dso != null) { - DSpaceObjectRest dsor = converter.toRest(dso); + DSpaceObjectRest dsor = converter.toRest(dso, utils.obtainProjection()); URI link = linkTo(dsor.getController(), dsor.getCategory(), dsor.getTypePlural()) .slash(dsor.getId()).toUri(); response.setStatus(HttpServletResponse.SC_FOUND); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AInprogressItemConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AInprogressItemConverter.java index 59e1d0db58..4ad8b5743a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AInprogressItemConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AInprogressItemConverter.java @@ -17,6 +17,7 @@ import org.dspace.app.rest.model.AInprogressSubmissionRest; import org.dspace.app.rest.model.ErrorRest; import org.dspace.app.rest.model.SubmissionDefinitionRest; import org.dspace.app.rest.model.SubmissionSectionRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.submit.AbstractRestProcessingStep; import org.dspace.app.rest.submit.SubmissionService; import org.dspace.app.util.SubmissionConfigReader; @@ -61,7 +62,7 @@ public abstract class AInprogressItemConverter { @Override - public AuthorityEntryRest convert(Choice choice) { + public AuthorityEntryRest convert(Choice choice, Projection projection) { AuthorityEntryRest entry = new AuthorityEntryRest(); + entry.setProjection(projection); entry.setValue(choice.value); entry.setDisplay(choice.label); entry.setId(choice.authority); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AuthorityRestConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AuthorityRestConverter.java index 64c332e283..7e78ef7f14 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AuthorityRestConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AuthorityRestConverter.java @@ -8,6 +8,7 @@ package org.dspace.app.rest.converter; import org.dspace.app.rest.model.AuthorityRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.utils.AuthorityUtils; import org.dspace.content.authority.ChoiceAuthority; import org.springframework.stereotype.Component; @@ -17,7 +18,7 @@ import org.springframework.stereotype.Component; * model and the REST data model * * TODO please do not use this convert but use the wrapper - * {@link AuthorityUtils#convertAuthority(ChoiceAuthority, String)} + * {@link AuthorityUtils#convertAuthority(ChoiceAuthority, String, String)} * * @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it) */ @@ -25,8 +26,9 @@ import org.springframework.stereotype.Component; public class AuthorityRestConverter implements DSpaceConverter { @Override - public AuthorityRest convert(ChoiceAuthority step) { + public AuthorityRest convert(ChoiceAuthority step, Projection projection) { AuthorityRest authorityRest = new AuthorityRest(); + authorityRest.setProjection(projection); authorityRest.setHierarchical(step.isHierarchical()); authorityRest.setScrollable(step.isScrollable()); authorityRest.setIdentifier(step.hasIdentifier()); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BitstreamConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BitstreamConverter.java index d8b8802778..5f41700dd9 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BitstreamConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BitstreamConverter.java @@ -12,6 +12,7 @@ import java.util.List; import org.dspace.app.rest.model.BitstreamRest; import org.dspace.app.rest.model.CheckSumRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.content.Bitstream; import org.dspace.content.Bundle; import org.springframework.beans.factory.annotation.Autowired; @@ -24,15 +25,14 @@ import org.springframework.stereotype.Component; * @author Andrea Bollini (andrea.bollini at 4science.it) */ @Component -public class BitstreamConverter - extends DSpaceObjectConverter { +public class BitstreamConverter extends DSpaceObjectConverter { @Autowired ConverterService converter; @Override - public BitstreamRest convert(org.dspace.content.Bitstream obj) { - BitstreamRest b = super.convert(obj); + public BitstreamRest convert(org.dspace.content.Bitstream obj, Projection projection) { + BitstreamRest b = super.convert(obj, projection); b.setSequenceId(obj.getSequenceID()); List bundles = null; try { @@ -49,7 +49,7 @@ public class BitstreamConverter checksum.setValue(obj.getChecksum()); b.setCheckSum(checksum); try { - b.setFormat(converter.toRest(obj.getFormat(null))); + b.setFormat(converter.toRest(obj.getFormat(null), projection)); } catch (SQLException e) { throw new RuntimeException(e); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BitstreamFormatConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BitstreamFormatConverter.java index 023008dbd4..2e0c552422 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BitstreamFormatConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/BitstreamFormatConverter.java @@ -8,6 +8,7 @@ package org.dspace.app.rest.converter; import org.dspace.app.rest.model.BitstreamFormatRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.content.BitstreamFormat; import org.dspace.content.service.BitstreamFormatService; import org.springframework.beans.factory.annotation.Autowired; @@ -26,8 +27,9 @@ public class BitstreamFormatConverter implements DSpaceConverter { @Override - public BrowseIndexRest convert(BrowseIndex obj) { + public BrowseIndexRest convert(BrowseIndex obj, Projection projection) { BrowseIndexRest bir = new BrowseIndexRest(); + bir.setProjection(projection); bir.setId(obj.getName()); bir.setOrder(obj.getDefaultOrder()); bir.setMetadataBrowse(obj.isMetadataIndex()); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ClaimedTaskConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ClaimedTaskConverter.java index 125969ed86..ab23be4c1c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ClaimedTaskConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ClaimedTaskConverter.java @@ -8,6 +8,7 @@ package org.dspace.app.rest.converter; import org.dspace.app.rest.model.ClaimedTaskRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.discovery.IndexableObject; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; @@ -22,21 +23,21 @@ import org.springframework.stereotype.Component; */ @Component public class ClaimedTaskConverter - implements IndexableObjectConverter { + implements IndexableObjectConverter { @Autowired private ConverterService converter; @Override - public ClaimedTaskRest convert(ClaimedTask obj) { + public ClaimedTaskRest convert(ClaimedTask obj, Projection projection) { ClaimedTaskRest taskRest = new ClaimedTaskRest(); - + taskRest.setProjection(projection); XmlWorkflowItem witem = obj.getWorkflowItem(); taskRest.setId(obj.getID()); - taskRest.setWorkflowitem(converter.toRest(witem)); + taskRest.setWorkflowitem(converter.toRest(witem, projection)); taskRest.setAction(obj.getActionID()); taskRest.setStep(obj.getStepID()); - taskRest.setOwner(converter.toRest(obj.getOwner())); + taskRest.setOwner(converter.toRest(obj.getOwner(), projection)); return taskRest; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/CollectionConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/CollectionConverter.java index c84d27de60..66d949630c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/CollectionConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/CollectionConverter.java @@ -16,6 +16,7 @@ import javax.servlet.http.HttpServletRequest; import org.apache.logging.log4j.Logger; import org.dspace.app.rest.model.CollectionRest; import org.dspace.app.rest.model.ResourcePolicyRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.utils.ContextUtil; import org.dspace.authorize.ResourcePolicy; import org.dspace.authorize.service.AuthorizeService; @@ -53,19 +54,19 @@ public class CollectionConverter private AuthorizeService authorizeService; @Override - public CollectionRest convert(org.dspace.content.Collection obj) { - CollectionRest col = super.convert(obj); + public CollectionRest convert(org.dspace.content.Collection obj, Projection projection) { + CollectionRest col = super.convert(obj, projection); Bitstream logo = obj.getLogo(); if (logo != null) { - col.setLogo(converter.toRest(logo)); + col.setLogo(converter.toRest(logo, projection)); } - col.setDefaultAccessConditions(getDefaultBitstreamPoliciesForCollection(obj.getID())); + col.setDefaultAccessConditions(getDefaultBitstreamPoliciesForCollection(obj.getID(), projection)); return col; } - private List getDefaultBitstreamPoliciesForCollection(UUID uuid) { + private List getDefaultBitstreamPoliciesForCollection(UUID uuid, Projection projection) { Context context = null; Request currentRequest = requestService.getCurrentRequest(); @@ -88,7 +89,7 @@ public class CollectionConverter List results = new ArrayList(); for (ResourcePolicy pp : defaultCollectionPolicies) { - ResourcePolicyRest accessCondition = converter.toRest(pp); + ResourcePolicyRest accessCondition = converter.toRest(pp, projection); if (accessCondition != null) { results.add(accessCondition); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/CommunityConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/CommunityConverter.java index 854d5807b2..4f386e7fcb 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/CommunityConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/CommunityConverter.java @@ -12,6 +12,7 @@ import java.util.List; import org.dspace.app.rest.model.CollectionRest; import org.dspace.app.rest.model.CommunityRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.content.Bitstream; import org.dspace.content.Collection; import org.dspace.content.Community; @@ -34,17 +35,17 @@ public class CommunityConverter private ConverterService converter; @Override - public CommunityRest convert(org.dspace.content.Community obj) { - CommunityRest com = super.convert(obj); + public CommunityRest convert(org.dspace.content.Community obj, Projection projection) { + CommunityRest com = super.convert(obj, projection); Bitstream logo = obj.getLogo(); if (logo != null) { - com.setLogo(converter.toRest(logo)); + com.setLogo(converter.toRest(logo, projection)); } List collections = obj.getCollections(); List collectionsRest = new ArrayList<>(); if (collections != null) { for (Collection col : collections) { - collectionsRest.add(converter.toRest(col)); + collectionsRest.add(converter.toRest(col, projection)); } } com.setCollections(collectionsRest); @@ -53,7 +54,7 @@ public class CommunityConverter List communityRest = new ArrayList<>(); if (subCommunities != null) { for (Community scom : subCommunities) { - CommunityRest scomrest = this.convert(scom); + CommunityRest scomrest = this.convert(scom, projection); communityRest.add(scomrest); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java index 9e579b37f5..9f3615a13e 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java @@ -61,36 +61,17 @@ public class ConverterService { private List projections; /** - * Converts the given model object to rest object, using the appropriate {@link DSpaceConverter}. - * - * @param modelObject the model object, which may be a JPA entity or other class provided by the DSpace - * service layer. - * @param the type of model object. A converter {@link Component} must exist that takes this as input. - * @param the inferred return type. - * @return the converted object. If it's a {@link RestAddressableModel}, its - * {@link RestAddressableModel#getProjection()} will be {@link DefaultProjection}. - * @throws IllegalArgumentException if there is no compatible converter. - * @throws ClassCastException if the converter's return type is not compatible with the inferred return type. - */ - public R toRest(M modelObject) { - return toRest(modelObject, null); - } - - /** - * Converts the given model object to a rest object, using the appropriate {@link DSpaceConverter}. + * Converts the given model object to a rest object, using the appropriate {@link DSpaceConverter} and + * the given projection. *

* The projection's {@link Projection#transformModel(Object)} method will be automatically applied * before conversion. If the rest object is a {@link RestModel}, the projection's * {@link Projection#transformRest(RestModel)} method will be automatically called after conversion. - * If the rest object is a {@link RestAddressableModel}, its {@code projection} field will also be set so - * that a subsequent call to {@link #toResource(RestModel)} will respect the projection without it - * having to be provided as an argument again. *

* * @param modelObject the model object, which may be a JPA entity or other class provided by the DSpace * service layer. - * @param projectionName the name of the projection to use. If given as {@code null}, the default no-op - * projection, {@link DefaultProjection} will be used. + * @param projection the projection to use. * @param the type of model object. A converter {@link Component} must exist that takes this as input. * @param the inferred return type. * @return the converted object. If it's a {@link RestAddressableModel}, its @@ -98,17 +79,11 @@ public class ConverterService { * @throws IllegalArgumentException if there is no compatible converter or no such projection. * @throws ClassCastException if the converter's return type is not compatible with the inferred return type. */ - public R toRest(M modelObject, @Nullable String projectionName) { - Projection projection = projectionName == null ? Projection.DEFAULT : requireProjection(projectionName); + public R toRest(M modelObject, Projection projection) { M transformedModel = projection.transformModel(modelObject); DSpaceConverter converter = requireConverter(modelObject.getClass()); - R restObject = converter.convert(transformedModel); + R restObject = converter.convert(transformedModel, projection); if (restObject instanceof RestModel) { - if (restObject instanceof RestAddressableModel) { - RestAddressableModel ram = projection.transformRest((RestAddressableModel) restObject); - ram.setProjection(projection); - return (R) ram; - } return (R) projection.transformRest((RestModel) restObject); } return restObject; @@ -127,26 +102,6 @@ public class ConverterService { return (DSpaceConverter) requireConverter(sourceClass); } - /** - * Converts the given rest object to a {@link HALResource} object, assigning the named projection beforehand, - * if it is a {@link RestAddressableModel}. - *

- * After the projection is assigned, behavior of this method is exactly the same as {@link #toResource(RestModel)}. - *

- * - * @param restObject the input rest object. - * @param projectionName the name of the projection to assign and use. - * @param the return type, a subclass of {@link HALResource}. - * @return the fully converted resource, with all automatic links and embeds applied. - * @throws IllegalArgumentException if there is no such projection. - */ - public T toResource(RestModel restObject, String projectionName) { - if (restObject instanceof RestAddressableModel) { - ((RestAddressableModel) restObject).setProjection(requireProjection(projectionName)); - } - return toResource(restObject); - } - /** * Converts the given rest object to a {@link HALResource} object. *

@@ -177,6 +132,17 @@ public class ConverterService { return halResource; } + /** + * Gets the projection with the given name, or the default (no-op) projection if null is given. + * + * @param projectionName the projection name, or {@code null}. + * @return the projection with the given name, or {@link DefaultProjection} if {@code null} is given. + * @throws IllegalArgumentException if a name is provided and such a projection cannot be found. + */ + public Projection getProjection(@Nullable String projectionName) { + return projectionName == null ? Projection.DEFAULT : requireProjection(projectionName); + } + /** * Creates and returns an instance of the appropriate {@link HALResource} subclass for the given rest object. *

diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceConverter.java index 17cecb33a6..2f53980673 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceConverter.java @@ -7,8 +7,11 @@ */ package org.dspace.app.rest.converter; -import org.springframework.core.convert.converter.Converter; +import org.dspace.app.rest.projection.Projection; + +public interface DSpaceConverter { + + R convert(M restObject, Projection projection); -public interface DSpaceConverter extends Converter { Class getModelClass(); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceObjectConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceObjectConverter.java index e8e11ecd50..d57d02ba5b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceObjectConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceObjectConverter.java @@ -7,6 +7,7 @@ */ package org.dspace.app.rest.converter; +import org.dspace.app.rest.projection.Projection; import org.dspace.content.DSpaceObject; import org.springframework.beans.factory.annotation.Autowired; @@ -25,8 +26,9 @@ public abstract class DSpaceObjectConverter { + + @Override + public SearchConfigurationRest convert(DiscoveryConfiguration configuration, Projection projection) { SearchConfigurationRest searchConfigurationRest = new SearchConfigurationRest(); + searchConfigurationRest.setProjection(projection); if (configuration != null) { addSearchFilters(searchConfigurationRest, configuration.getSearchFilters(), configuration.getSidebarFacets()); @@ -36,6 +41,11 @@ public class DiscoverConfigurationConverter { return searchConfigurationRest; } + @Override + public Class getModelClass() { + return DiscoveryConfiguration.class; + } + private void setDefaultSortOption(DiscoveryConfiguration configuration, SearchConfigurationRest searchConfigurationRest) { String defaultSort = configuration.getSearchSortConfiguration().SCORE; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverFacetResultsConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverFacetResultsConverter.java index 524dc3add3..1532502b86 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverFacetResultsConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverFacetResultsConverter.java @@ -15,6 +15,7 @@ import org.dspace.app.rest.model.SearchFacetEntryRest; import org.dspace.app.rest.model.SearchFacetValueRest; import org.dspace.app.rest.model.SearchResultsRest; import org.dspace.app.rest.parameter.SearchFilter; +import org.dspace.app.rest.projection.Projection; import org.dspace.core.Context; import org.dspace.discovery.DiscoverResult; import org.dspace.discovery.configuration.DiscoveryConfiguration; @@ -36,19 +37,20 @@ public class DiscoverFacetResultsConverter { public FacetResultsRest convert(Context context, String facetName, String prefix, String query, String dsoType, String dsoScope, List searchFilters, DiscoverResult searchResult, - DiscoveryConfiguration configuration, Pageable page) { + DiscoveryConfiguration configuration, Pageable page, Projection projection) { FacetResultsRest facetResultsRest = new FacetResultsRest(); + facetResultsRest.setProjection(projection); setRequestInformation(context, facetName, prefix, query, dsoType, dsoScope, searchFilters, searchResult, - configuration, facetResultsRest, page); + configuration, facetResultsRest, page, projection); - addToFacetResultList(facetName, searchResult, facetResultsRest, configuration, page); + addToFacetResultList(facetName, searchResult, facetResultsRest, configuration, page, projection); return facetResultsRest; } private void addToFacetResultList(String facetName, DiscoverResult searchResult, FacetResultsRest facetResultsRest, - DiscoveryConfiguration configuration, Pageable page) { + DiscoveryConfiguration configuration, Pageable page, Projection projection) { DiscoverySearchFilterFacet field = configuration.getSidebarFacet(facetName); List facetValues = searchResult.getFacetResult(field); @@ -59,26 +61,27 @@ public class DiscoverFacetResultsConverter { //We requested one facet value more as the page size. We must make sure to not return the extra value. break; } - SearchFacetValueRest searchFacetValueRest = buildSearchFacetValueRestFromFacetResult(value); + SearchFacetValueRest searchFacetValueRest = buildSearchFacetValueRestFromFacetResult(value, projection); facetResultsRest.addToFacetResultList(searchFacetValueRest); valueCount++; } } - private SearchFacetValueRest buildSearchFacetValueRestFromFacetResult(DiscoverResult.FacetResult value) { - return facetValueConverter.convert(value); + private SearchFacetValueRest buildSearchFacetValueRestFromFacetResult(DiscoverResult.FacetResult value, + Projection projection) { + return facetValueConverter.convert(value, projection); } private void setRequestInformation(Context context, String facetName, String prefix, String query, String dsoType, String dsoScope, List searchFilters, DiscoverResult searchResult, DiscoveryConfiguration configuration, FacetResultsRest facetResultsRest, - Pageable page) { + Pageable page, Projection projection) { facetResultsRest.setQuery(query); facetResultsRest.setPrefix(prefix); facetResultsRest.setScope(dsoScope); facetResultsRest.setDsoType(dsoType); - facetResultsRest.setFacetEntry(convertFacetEntry(facetName, searchResult, configuration, page)); + facetResultsRest.setFacetEntry(convertFacetEntry(facetName, searchResult, configuration, page, projection)); facetResultsRest.setSort(SearchResultsRest.Sorting.fromPage(page)); @@ -91,10 +94,12 @@ public class DiscoverFacetResultsConverter { } private SearchFacetEntryRest convertFacetEntry(final String facetName, final DiscoverResult searchResult, - final DiscoveryConfiguration configuration, final Pageable page) { + final DiscoveryConfiguration configuration, final Pageable page, + final Projection projection) { DiscoverySearchFilterFacet field = configuration.getSidebarFacet(facetName); SearchFacetEntryRest facetEntryRest = new SearchFacetEntryRest(facetName); + facetEntryRest.setProjection(projection); List facetResults = searchResult.getFacetResult(field); if (!facetResults.isEmpty()) { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverFacetValueConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverFacetValueConverter.java index c77d9050df..8c2200fa2d 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverFacetValueConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverFacetValueConverter.java @@ -8,6 +8,7 @@ package org.dspace.app.rest.converter; import org.dspace.app.rest.model.SearchFacetValueRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.discovery.DiscoverResult; import org.springframework.stereotype.Component; @@ -17,8 +18,9 @@ import org.springframework.stereotype.Component; @Component public class DiscoverFacetValueConverter { - public SearchFacetValueRest convert(final DiscoverResult.FacetResult value) { + public SearchFacetValueRest convert(final DiscoverResult.FacetResult value, final Projection projection) { SearchFacetValueRest valueRest = new SearchFacetValueRest(); + valueRest.setProjection(projection); valueRest.setLabel(value.getDisplayedValue()); valueRest.setFilterValue(value.getAsFilterQuery()); valueRest.setFilterType(value.getFilterType()); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverFacetsConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverFacetsConverter.java index f7970415e4..ad52f9b002 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverFacetsConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverFacetsConverter.java @@ -16,6 +16,7 @@ import org.dspace.app.rest.model.SearchFacetEntryRest; import org.dspace.app.rest.model.SearchFacetValueRest; import org.dspace.app.rest.model.SearchResultsRest; import org.dspace.app.rest.parameter.SearchFilter; +import org.dspace.app.rest.projection.Projection; import org.dspace.core.Context; import org.dspace.discovery.DiscoverQuery; import org.dspace.discovery.DiscoverResult; @@ -39,13 +40,15 @@ public class DiscoverFacetsConverter { public SearchResultsRest convert(Context context, String query, String dsoType, String configurationName, String dsoScope, List searchFilters, final Pageable page, - DiscoveryConfiguration configuration, DiscoverResult searchResult) { + DiscoveryConfiguration configuration, DiscoverResult searchResult, + Projection projection) { SearchResultsRest searchResultsRest = new SearchResultsRest(); + searchResultsRest.setProjection(projection); setRequestInformation(context, query, dsoType, configurationName, dsoScope, searchFilters, page, searchResultsRest); - addFacetValues(context, searchResult, searchResultsRest, configuration); + addFacetValues(context, searchResult, searchResultsRest, configuration, projection); return searchResultsRest; } @@ -64,13 +67,14 @@ public class DiscoverFacetsConverter { * The DiscoveryConfiguration applied to the query */ public void addFacetValues(Context context, final DiscoverResult searchResult, final SearchResultsRest resultsRest, - final DiscoveryConfiguration configuration) { + final DiscoveryConfiguration configuration, final Projection projection) { List facets = configuration.getSidebarFacets(); for (DiscoverySearchFilterFacet field : CollectionUtils.emptyIfNull(facets)) { List facetValues = searchResult.getFacetResult(field); SearchFacetEntryRest facetEntry = new SearchFacetEntryRest(field.getIndexFieldName()); + facetEntry.setProjection(projection); int valueCount = 0; facetEntry.setHasMore(false); facetEntry.setFacetLimit(field.getFacetLimit()); @@ -84,7 +88,7 @@ public class DiscoverFacetsConverter { // are // more results available. if (valueCount < field.getFacetLimit()) { - SearchFacetValueRest valueRest = facetValueConverter.convert(value); + SearchFacetValueRest valueRest = facetValueConverter.convert(value, projection); facetEntry.addValue(valueRest); } else { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverResultConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverResultConverter.java index 1cd1779e87..8826552015 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverResultConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverResultConverter.java @@ -18,6 +18,7 @@ import org.dspace.app.rest.model.RestAddressableModel; import org.dspace.app.rest.model.SearchResultEntryRest; import org.dspace.app.rest.model.SearchResultsRest; import org.dspace.app.rest.parameter.SearchFilter; +import org.dspace.app.rest.projection.Projection; import org.dspace.core.Context; import org.dspace.discovery.DiscoverResult; import org.dspace.discovery.IndexableObject; @@ -45,15 +46,17 @@ public class DiscoverResultConverter { public SearchResultsRest convert(final Context context, final String query, final String dsoType, final String configurationName, final String scope, final List searchFilters, final Pageable page, - final DiscoverResult searchResult, final DiscoveryConfiguration configuration) { + final DiscoverResult searchResult, final DiscoveryConfiguration configuration, + final Projection projection) { SearchResultsRest resultsRest = new SearchResultsRest(); + resultsRest.setProjection(projection); setRequestInformation(context, query, dsoType, configurationName, scope, searchFilters, page, resultsRest); - addSearchResults(searchResult, resultsRest); + addSearchResults(searchResult, resultsRest, projection); - addFacetValues(context, searchResult, resultsRest, configuration); + addFacetValues(context, searchResult, resultsRest, configuration, projection); resultsRest.setTotalNumberOfResults(searchResult.getTotalSearchResults()); @@ -61,16 +64,18 @@ public class DiscoverResultConverter { } private void addFacetValues(Context context, final DiscoverResult searchResult, final SearchResultsRest resultsRest, - final DiscoveryConfiguration configuration) { - facetConverter.addFacetValues(context, searchResult, resultsRest, configuration); + final DiscoveryConfiguration configuration, final Projection projection) { + facetConverter.addFacetValues(context, searchResult, resultsRest, configuration, projection); } - private void addSearchResults(final DiscoverResult searchResult, final SearchResultsRest resultsRest) { + private void addSearchResults(final DiscoverResult searchResult, final SearchResultsRest resultsRest, + final Projection projection) { for (IndexableObject dspaceObject : CollectionUtils.emptyIfNull(searchResult.getIndexableObjects())) { SearchResultEntryRest resultEntry = new SearchResultEntryRest(); + resultEntry.setProjection(projection); //Convert the DSpace Object to its REST model - resultEntry.setIndexableObject(convertDSpaceObject(dspaceObject)); + resultEntry.setIndexableObject(convertDSpaceObject(dspaceObject, projection)); //Add hit highlighting for this DSO if present DiscoverResult.IndexableObjectHighlightResult highlightedResults = searchResult @@ -86,10 +91,10 @@ public class DiscoverResultConverter { } } - private RestAddressableModel convertDSpaceObject(final IndexableObject dspaceObject) { + private RestAddressableModel convertDSpaceObject(final IndexableObject dspaceObject, final Projection projection) { for (IndexableObjectConverter converter : converters) { if (converter.supportsModel(dspaceObject)) { - return converter.convert(dspaceObject); + return converter.convert(dspaceObject, projection); } } return null; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EPersonConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EPersonConverter.java index d902d86b2a..79c7b9f1f5 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EPersonConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EPersonConverter.java @@ -14,6 +14,7 @@ import java.util.List; import org.apache.logging.log4j.Logger; import org.dspace.app.rest.model.EPersonRest; import org.dspace.app.rest.model.GroupRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; @@ -39,8 +40,8 @@ public class EPersonConverter extends DSpaceObjectConverter groups = new ArrayList<>(); for (Group g : groupService.allMemberGroups(context, ePerson)) { - groups.add(converter.toRest(g)); + groups.add(converter.toRest(g, projection)); } eperson.setGroups(groups); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EntityTypeConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EntityTypeConverter.java index e56e627de2..c61a4cf05c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EntityTypeConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/EntityTypeConverter.java @@ -8,6 +8,7 @@ package org.dspace.app.rest.converter; import org.dspace.app.rest.model.EntityTypeRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.content.EntityType; import org.springframework.stereotype.Component; @@ -18,15 +19,10 @@ import org.springframework.stereotype.Component; @Component public class EntityTypeConverter implements DSpaceConverter { - /** - * This method converts the EntityType model object that is passed along in the params to the - * REST representation of this object - * @param obj The EntityType model object to be converted - * @return The EntityType REST object that is made from the model object - */ @Override - public EntityTypeRest convert(EntityType obj) { + public EntityTypeRest convert(EntityType obj, Projection projection) { EntityTypeRest entityTypeRest = new EntityTypeRest(); + entityTypeRest.setProjection(projection); entityTypeRest.setId(obj.getID()); entityTypeRest.setLabel(obj.getLabel()); return entityTypeRest; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/GroupConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/GroupConverter.java index 378868a3bb..592a485555 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/GroupConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/GroupConverter.java @@ -12,6 +12,7 @@ import java.util.List; import org.apache.logging.log4j.Logger; import org.dspace.app.rest.model.GroupRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.eperson.Group; import org.springframework.stereotype.Component; @@ -27,12 +28,12 @@ public class GroupConverter extends DSpaceObjectConverter groups = new ArrayList(); for (Group g : obj.getMemberGroups()) { - groups.add(convert(g)); + groups.add(convert(g, projection)); } epersongroup.setGroups(groups); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/HarvestedCollectionConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/HarvestedCollectionConverter.java index 60f818da34..b989233612 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/HarvestedCollectionConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/HarvestedCollectionConverter.java @@ -14,6 +14,7 @@ import org.dspace.app.rest.model.HarvestStatusEnum; import org.dspace.app.rest.model.HarvestTypeEnum; import org.dspace.app.rest.model.HarvestedCollectionRest; import org.dspace.app.rest.model.HarvesterMetadataRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.content.Collection; import org.dspace.harvest.HarvestedCollection; import org.springframework.beans.factory.annotation.Autowired; @@ -31,15 +32,16 @@ public class HarvestedCollectionConverter implements DSpaceConverter> metadata_configs) { - HarvestedCollectionRest harvestedCollectionRest = this.convert(obj); + List> metadata_configs, + Projection projection) { + HarvestedCollectionRest harvestedCollectionRest = this.convert(obj, projection); // Add collectionRest to the empty HarvestedCollectionRest so that we can use its uuid later in the linkFactory if (obj == null) { - harvestedCollectionRest.setCollection(converter.toRest(collection)); + harvestedCollectionRest.setCollection(converter.toRest(collection, projection)); } HarvesterMetadataRest harvesterMetadataRest = new HarvesterMetadataRest(); + harvesterMetadataRest.setProjection(projection); harvesterMetadataRest.setConfigs(metadata_configs); - harvestedCollectionRest.setMetadataConfigs(harvesterMetadataRest); return harvestedCollectionRest; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ItemConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ItemConverter.java index 1b34d3a480..d365d23f19 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ItemConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ItemConverter.java @@ -13,6 +13,7 @@ import java.util.List; import org.apache.logging.log4j.Logger; import org.dspace.app.rest.model.BitstreamRest; import org.dspace.app.rest.model.ItemRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.content.Bitstream; import org.dspace.content.Bundle; import org.dspace.content.Collection; @@ -31,7 +32,7 @@ import org.springframework.stereotype.Component; */ @Component public class ItemConverter - extends DSpaceObjectConverter + extends DSpaceObjectConverter implements IndexableObjectConverter { @Autowired @@ -44,24 +45,24 @@ public class ItemConverter private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(ItemConverter.class); @Override - public ItemRest convert(org.dspace.content.Item obj) { - ItemRest item = super.convert(obj); + public ItemRest convert(Item obj, Projection projection) { + ItemRest item = super.convert(obj, projection); item.setInArchive(obj.isArchived()); item.setDiscoverable(obj.isDiscoverable()); item.setWithdrawn(obj.isWithdrawn()); item.setLastModified(obj.getLastModified()); Collection owningCollection = obj.getOwningCollection(); if (owningCollection != null) { - item.setOwningCollection(converter.toRest(owningCollection)); + item.setOwningCollection(converter.toRest(owningCollection, projection)); } Collection templateItemOf = obj.getTemplateItemOf(); if (templateItemOf != null) { - item.setTemplateItemOf(converter.toRest(templateItemOf)); + item.setTemplateItemOf(converter.toRest(templateItemOf, projection)); } List bitstreams = new ArrayList<>(); for (Bundle bun : obj.getBundles()) { for (Bitstream bit : bun.getBitstreams()) { - bitstreams.add(converter.toRest(bit)); + bitstreams.add(converter.toRest(bit, projection)); } } item.setBitstreams(bitstreams); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataConverter.java index 57b332cdd2..6e33f842fb 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataConverter.java @@ -18,6 +18,7 @@ import java.util.stream.Collectors; import org.dspace.app.rest.model.MetadataRest; import org.dspace.app.rest.model.MetadataValueRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.authorize.AuthorizeException; import org.dspace.content.DSpaceObject; import org.dspace.content.Item; @@ -58,7 +59,7 @@ public class MetadataConverter implements Converter, Metadat set = new TreeSet<>(Comparator.comparingInt(MetadataValueRest::getPlace)); mapOfSortedSets.put(key, set); } - set.add(converter.toRest(metadataValue)); + set.add(converter.toRest(metadataValue, Projection.DEFAULT)); } MetadataRest metadataRest = new MetadataRest(); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataFieldConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataFieldConverter.java index 8522f4d8d3..89da5b0dc9 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataFieldConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataFieldConverter.java @@ -8,6 +8,7 @@ package org.dspace.app.rest.converter; import org.dspace.app.rest.model.MetadataFieldRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.content.MetadataField; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -19,18 +20,19 @@ import org.springframework.stereotype.Component; * @author Andrea Bollini (andrea.bollini at 4science.it) */ @Component -public class MetadataFieldConverter implements DSpaceConverter { +public class MetadataFieldConverter implements DSpaceConverter { @Autowired private ConverterService converter; @Override - public MetadataFieldRest convert(org.dspace.content.MetadataField obj) { + public MetadataFieldRest convert(MetadataField obj, Projection projection) { MetadataFieldRest field = new MetadataFieldRest(); + field.setProjection(projection); field.setId(obj.getID()); field.setElement(obj.getElement()); field.setQualifier(obj.getQualifier()); field.setScopeNote(obj.getScopeNote()); - field.setSchema(converter.toRest(obj.getMetadataSchema())); + field.setSchema(converter.toRest(obj.getMetadataSchema(), projection)); return field; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataSchemaConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataSchemaConverter.java index b1b059bffc..739351bcef 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataSchemaConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataSchemaConverter.java @@ -8,6 +8,7 @@ package org.dspace.app.rest.converter; import org.dspace.app.rest.model.MetadataSchemaRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.content.MetadataSchema; import org.springframework.stereotype.Component; @@ -18,10 +19,11 @@ import org.springframework.stereotype.Component; * @author Andrea Bollini (andrea.bollini at 4science.it) */ @Component -public class MetadataSchemaConverter implements DSpaceConverter { +public class MetadataSchemaConverter implements DSpaceConverter { @Override - public MetadataSchemaRest convert(org.dspace.content.MetadataSchema obj) { + public MetadataSchemaRest convert(MetadataSchema obj, Projection projection) { MetadataSchemaRest schema = new MetadataSchemaRest(); + schema.setProjection(projection); schema.setId(obj.getID()); schema.setNamespace(obj.getNamespace()); schema.setPrefix(obj.getName()); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataValueConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataValueConverter.java index f04a59125a..c5f88998f0 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataValueConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataValueConverter.java @@ -8,6 +8,7 @@ package org.dspace.app.rest.converter; import org.dspace.app.rest.model.MetadataValueRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.content.MetadataValue; import org.springframework.stereotype.Component; @@ -17,14 +18,8 @@ import org.springframework.stereotype.Component; @Component public class MetadataValueConverter implements DSpaceConverter { - /** - * Gets a rest representation of the given domain metadata value. - * - * @param metadataValue the domain value. - * @return the rest representation. - */ @Override - public MetadataValueRest convert(MetadataValue metadataValue) { + public MetadataValueRest convert(MetadataValue metadataValue, Projection projection) { MetadataValueRest metadataValueRest = new MetadataValueRest(); metadataValueRest.setValue(metadataValue.getValue()); metadataValueRest.setLanguage(metadataValue.getLanguage()); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/PoolTaskConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/PoolTaskConverter.java index ad4e9cf638..e6530d6d6b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/PoolTaskConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/PoolTaskConverter.java @@ -8,6 +8,7 @@ package org.dspace.app.rest.converter; import org.dspace.app.rest.model.PoolTaskRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.discovery.IndexableObject; import org.dspace.xmlworkflow.storedcomponents.PoolTask; import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; @@ -28,17 +29,18 @@ public class PoolTaskConverter private ConverterService converter; @Override - public PoolTaskRest convert(PoolTask obj) { + public PoolTaskRest convert(PoolTask obj, Projection projection) { PoolTaskRest taskRest = new PoolTaskRest(); + taskRest.setProjection(projection); XmlWorkflowItem witem = obj.getWorkflowItem(); taskRest.setId(obj.getID()); - taskRest.setWorkflowitem(converter.toRest(witem)); + taskRest.setWorkflowitem(converter.toRest(witem, projection)); if (obj.getEperson() != null) { - taskRest.setEperson(converter.toRest(obj.getEperson())); + taskRest.setEperson(converter.toRest(obj.getEperson(), projection)); } if (obj.getGroup() != null) { - taskRest.setGroup(converter.toRest(obj.getGroup())); + taskRest.setGroup(converter.toRest(obj.getGroup(), projection)); } taskRest.setAction(obj.getActionID()); taskRest.setStep(obj.getStepID()); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/RelationshipConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/RelationshipConverter.java index 93b1583dab..f9d0cf52ec 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/RelationshipConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/RelationshipConverter.java @@ -8,6 +8,7 @@ package org.dspace.app.rest.converter; import org.dspace.app.rest.model.RelationshipRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.content.Relationship; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -22,17 +23,13 @@ public class RelationshipConverter implements DSpaceConverter { +public class SiteConverter extends DSpaceObjectConverter { @Override - public SiteRest convert(org.dspace.content.Site obj) { - return super.convert(obj); + public SiteRest convert(Site obj, Projection projection) { + return super.convert(obj, projection); } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionDefinitionConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionDefinitionConverter.java index e162ec25c3..1b4fa05a5b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionDefinitionConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionDefinitionConverter.java @@ -17,6 +17,7 @@ import org.apache.logging.log4j.Logger; import org.dspace.app.rest.model.CollectionRest; import org.dspace.app.rest.model.SubmissionDefinitionRest; import org.dspace.app.rest.model.SubmissionSectionRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.utils.ContextUtil; import org.dspace.app.util.SubmissionConfig; import org.dspace.app.util.SubmissionConfigReaderException; @@ -49,14 +50,15 @@ public class SubmissionDefinitionConverter implements DSpaceConverter panels = new LinkedList(); for (int idx = 0; idx < obj.getNumberOfSteps(); idx++) { SubmissionStepConfig step = obj.getStep(idx); - SubmissionSectionRest sp = converter.toRest(step); + SubmissionSectionRest sp = converter.toRest(step, projection); panels.add(sp); } @@ -68,7 +70,8 @@ public class SubmissionDefinitionConverter implements DSpaceConverter cc = converter.getConverter(Collection.class); - List collectionsRest = collections.stream().map(cc::convert).collect(Collectors.toList()); + List collectionsRest = collections.stream().map((collection) -> + cc.convert(collection, projection)).collect(Collectors.toList()); sd.setCollections(collectionsRest); } catch (SQLException | IllegalStateException | SubmissionConfigReaderException e) { log.error(e.getMessage(), e); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionFormConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionFormConverter.java index 55ae27c7a5..a1e747efc1 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionFormConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionFormConverter.java @@ -21,6 +21,7 @@ import org.dspace.app.rest.model.SubmissionVisibilityRest; import org.dspace.app.rest.model.VisibilityEnum; import org.dspace.app.rest.model.submit.SelectableMetadata; import org.dspace.app.rest.model.submit.SelectableRelationship; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.repository.SubmissionFormRestRepository; import org.dspace.app.rest.utils.AuthorityUtils; import org.dspace.app.util.DCInput; @@ -50,8 +51,9 @@ public class SubmissionFormConverter implements DSpaceConverter rows = getPage(step, obj.getFormName()); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionSectionConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionSectionConverter.java index e8bd41923a..bf683be8a4 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionSectionConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionSectionConverter.java @@ -11,6 +11,7 @@ import org.apache.logging.log4j.Logger; import org.dspace.app.rest.model.SubmissionSectionRest; import org.dspace.app.rest.model.SubmissionVisibilityRest; import org.dspace.app.rest.model.VisibilityEnum; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.util.SubmissionConfigReader; import org.dspace.app.util.SubmissionConfigReaderException; import org.dspace.app.util.SubmissionStepConfig; @@ -30,8 +31,9 @@ public class SubmissionSectionConverter implements DSpaceConverter { @Override protected void addLinks(EntityTypeResource halResource, Pageable pageable, LinkedList list) throws Exception { - list.add(buildLink("relationshiptypes", getMethodOn().retrieve(halResource.getContent().getId(), null, null))); + list.add(buildLink("relationshiptypes", getMethodOn().retrieve( + halResource.getContent().getId(), null, null))); } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/link/relation/RelationshipHalLinkFactory.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/link/relation/RelationshipHalLinkFactory.java index 9da50be395..9d4e4291f5 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/link/relation/RelationshipHalLinkFactory.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/link/relation/RelationshipHalLinkFactory.java @@ -29,10 +29,10 @@ public class RelationshipHalLinkFactory extends HalLinkFactory extends @JsonIgnore private EPersonRest submitter; - public AInprogressSubmissionRest() { - super(); - } - public Date getLastModified() { return lastModified; } @@ -90,4 +86,4 @@ public abstract class AInprogressSubmissionRest extends this.collection = collection; } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BitstreamFormatRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BitstreamFormatRest.java index 4d40b20ec1..1b02a1d89a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BitstreamFormatRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BitstreamFormatRest.java @@ -101,4 +101,4 @@ public class BitstreamFormatRest extends BaseObjectRest { public Class getController() { return RestResourceController.class; } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ClaimedTaskRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ClaimedTaskRest.java index 3da683c323..8b13aee2d6 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ClaimedTaskRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ClaimedTaskRest.java @@ -92,4 +92,4 @@ public class ClaimedTaskRest extends BaseObjectRest { public void setWorkflowitem(WorkflowItemRest workflowitem) { this.workflowitem = workflowitem; } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/DiscoveryResultsRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/DiscoveryResultsRest.java index d3e1dfbe35..d45d948fa6 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/DiscoveryResultsRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/DiscoveryResultsRest.java @@ -11,7 +11,6 @@ import java.util.LinkedList; import java.util.List; import com.fasterxml.jackson.annotation.JsonIgnore; - import org.dspace.app.rest.DiscoveryRestController; import org.dspace.app.rest.parameter.SearchFilter; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/EPersonRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/EPersonRest.java index 5798b9289b..96b4286cc4 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/EPersonRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/EPersonRest.java @@ -123,4 +123,4 @@ public class EPersonRest extends DSpaceObjectRest { return RestResourceController.class; } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MetadataFieldRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MetadataFieldRest.java index 7e6eabc4d0..966b3afbbe 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MetadataFieldRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MetadataFieldRest.java @@ -76,4 +76,4 @@ public class MetadataFieldRest extends BaseObjectRest { public String getCategory() { return CATEGORY; } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MetadataSchemaRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MetadataSchemaRest.java index 27229ea429..655d4c86d8 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MetadataSchemaRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MetadataSchemaRest.java @@ -54,4 +54,4 @@ public class MetadataSchemaRest extends BaseObjectRest { public String getCategory() { return CATEGORY; } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/PoolTaskRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/PoolTaskRest.java index 4555374520..6ab445659e 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/PoolTaskRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/PoolTaskRest.java @@ -107,4 +107,4 @@ public class PoolTaskRest extends BaseObjectRest { public void setWorkflowitem(WorkflowItemRest workflowitem) { this.workflowitem = workflowitem; } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RelationshipTypeRestWrapper.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RelationshipTypeRestWrapper.java index a86ee53f05..2aa0891005 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RelationshipTypeRestWrapper.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RelationshipTypeRestWrapper.java @@ -26,8 +26,6 @@ public class RelationshipTypeRestWrapper extends RestAddressableModel { private String entityTypeLabel; private Integer entityTypeId; - - public List getRelationshipTypeRestList() { return relationshipTypeRestList; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchEventRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchEventRest.java index a6281d961e..e029dbaf99 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchEventRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchEventRest.java @@ -29,19 +29,6 @@ public class SearchEventRest extends BaseObjectRest { private SearchResultsRest.Sorting sort; private PageRest page; - public SearchEventRest(String query, UUID scope, String configuration, - List appliedFilters, - SearchResultsRest.Sorting sort) { - this.query = query; - this.scope = scope; - this.configuration = configuration; - this.appliedFilters = appliedFilters; - this.sort = sort; - } - - public SearchEventRest() { - } - public String getCategory() { return CATEGORY; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchResultEntryRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchResultEntryRest.java index 60bb5b3db4..ac1d94f5f5 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchResultEntryRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchResultEntryRest.java @@ -12,7 +12,6 @@ import java.util.List; import java.util.Map; import com.fasterxml.jackson.annotation.JsonIgnore; - import org.dspace.app.rest.DiscoveryRestController; /** diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchResultsRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchResultsRest.java index 306b9c9ea1..92f091eebe 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchResultsRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchResultsRest.java @@ -11,7 +11,6 @@ import java.util.LinkedList; import java.util.List; import com.fasterxml.jackson.annotation.JsonIgnore; - import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -29,7 +28,6 @@ public class SearchResultsRest extends DiscoveryResultsRest { @JsonIgnore List facets; - public List getSearchResults() { return searchResults; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SubmissionDefinitionRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SubmissionDefinitionRest.java index e027b0b324..ed2d19e7ca 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SubmissionDefinitionRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SubmissionDefinitionRest.java @@ -86,4 +86,4 @@ public class SubmissionDefinitionRest extends BaseObjectRest { public void setCollections(List collections) { this.collections = collections; } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SubmissionUploadRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SubmissionUploadRest.java index 57fd87c727..4d8504fa0b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SubmissionUploadRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SubmissionUploadRest.java @@ -97,4 +97,4 @@ public class SubmissionUploadRest extends BaseObjectRest { public void setMetadata(SubmissionFormRest metadata) { this.metadata = metadata; } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowItemRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowItemRest.java index ca4f68e3fa..831baefec1 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowItemRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowItemRest.java @@ -32,4 +32,4 @@ public class WorkflowItemRest extends AInprogressSubmissionRest { public Class getController() { return RestResourceController.class; } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkspaceItemRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkspaceItemRest.java index 190bf99cf0..3fac0eeef1 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkspaceItemRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkspaceItemRest.java @@ -32,4 +32,4 @@ public class WorkspaceItemRest extends AInprogressSubmissionRest { public Class getController() { return RestResourceController.class; } -} \ No newline at end of file +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityEntryLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityEntryLinkRepository.java index 953eb5b21f..17ae198903 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityEntryLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityEntryLinkRepository.java @@ -16,6 +16,7 @@ import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; import org.dspace.app.rest.model.AuthorityEntryRest; import org.dspace.app.rest.model.AuthorityRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.utils.AuthorityUtils; import org.dspace.content.Collection; import org.dspace.content.authority.Choice; @@ -50,7 +51,7 @@ public class AuthorityEntryLinkRepository extends AbstractDSpaceRestRepository @PreAuthorize("hasAuthority('AUTHENTICATED')") public Page query(HttpServletRequest request, String name, - Pageable pageable, String projection) { + Pageable pageable, Projection projection) { Context context = obtainContext(); String query = request.getParameter("query"); String metadata = request.getParameter("metadata"); @@ -63,17 +64,17 @@ public class AuthorityEntryLinkRepository extends AbstractDSpaceRestRepository throw new RuntimeException(e); } } - List results = new ArrayList(); + List results = new ArrayList<>(); if (StringUtils.isNotBlank(metadata)) { String[] tokens = org.dspace.core.Utils.tokenize(metadata); String fieldKey = org.dspace.core.Utils.standardize(tokens[0], tokens[1], tokens[2], "_"); Choices choices = cas.getMatches(fieldKey, query, collection, pageable.getOffset(), pageable.getPageSize(), context.getCurrentLocale().toString()); for (Choice value : choices.values) { - results.add(authorityUtils.convertEntry(value, name)); + results.add(authorityUtils.convertEntry(value, name, projection)); } } - return new PageImpl(results, pageable, results.size()); + return new PageImpl<>(results, pageable, results.size()); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityEntryValueLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityEntryValueLinkRepository.java index 7d2df54164..24852b9a09 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityEntryValueLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityEntryValueLinkRepository.java @@ -11,6 +11,7 @@ import javax.servlet.http.HttpServletRequest; import org.dspace.app.rest.model.AuthorityEntryRest; import org.dspace.app.rest.model.AuthorityRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.utils.AuthorityUtils; import org.dspace.content.authority.Choice; import org.dspace.content.authority.ChoiceAuthority; @@ -39,14 +40,14 @@ public class AuthorityEntryValueLinkRepository extends AbstractDSpaceRestReposit @PreAuthorize("hasAuthority('AUTHENTICATED')") public AuthorityEntryRest getResource(HttpServletRequest request, String name, String relId, - Pageable pageable, String projection) { + Pageable pageable, Projection projection) { Context context = obtainContext(); ChoiceAuthority choiceAuthority = cas.getChoiceAuthorityByAuthorityName(name); Choice choice = choiceAuthority.getChoice(null, relId, context.getCurrentLocale().toString()); if (choice == null) { throw new ResourceNotFoundException("The authority was not found"); } - return authorityUtils.convertEntry(choice, name); + return authorityUtils.convertEntry(choice, name, projection); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityRestRepository.java index a1fc542cdb..4a5f72cd47 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityRestRepository.java @@ -12,6 +12,7 @@ import java.util.List; import java.util.Set; import org.dspace.app.rest.model.AuthorityRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.utils.AuthorityUtils; import org.dspace.content.authority.ChoiceAuthority; import org.dspace.content.authority.service.ChoiceAuthorityService; @@ -41,7 +42,7 @@ public class AuthorityRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { Set authoritiesName = cas.getChoiceAuthoritiesNames(); List results = new ArrayList(); + Projection projection = utils.obtainProjection(true); for (String authorityName : authoritiesName) { ChoiceAuthority source = cas.getChoiceAuthorityByAuthorityName(authorityName); - AuthorityRest result = authorityUtils.convertAuthority(source, authorityName); + AuthorityRest result = authorityUtils.convertAuthority(source, authorityName, projection); results.add(result); } return new PageImpl(results, pageable, results.size()); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java index 44ebf996f4..da9a8176d3 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java @@ -19,6 +19,7 @@ import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.BitstreamFormatRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.authorize.AuthorizeException; import org.dspace.content.BitstreamFormat; import org.dspace.content.service.BitstreamFormatService; @@ -61,7 +62,7 @@ public class BitstreamFormatRestRepository extends DSpaceRestRepository page = utils.getPage(bit, pageable).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = utils.getPage(bit, pageable) + .map((object) -> converter.toRest(object, projection)); return page; } @@ -99,7 +102,7 @@ public class BitstreamFormatRestRepository extends DSpaceRestRepository page = new PageImpl(bit, pageable, total).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = new PageImpl<>(bit, pageable, total) + .map((bitstream) -> converter.toRest(bitstream, projection)); return page; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseEntryLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseEntryLinkRepository.java index e755a043b7..8c4e2ca6d9 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseEntryLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseEntryLinkRepository.java @@ -17,6 +17,7 @@ import org.dspace.app.rest.converter.BrowseEntryConverter; import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.BrowseEntryRest; import org.dspace.app.rest.model.BrowseIndexRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.utils.ScopeResolver; import org.dspace.browse.BrowseEngine; import org.dspace.browse.BrowseException; @@ -55,7 +56,7 @@ public class BrowseEntryLinkRepository extends AbstractDSpaceRestRepository // FIXME It will be nice to drive arguments binding by annotation as in normal spring controller methods public Page listBrowseEntries(HttpServletRequest request, String browseName, - Pageable pageable, String projection) + Pageable pageable, Projection projection) throws BrowseException, SQLException { // FIXME this should be bind automatically and available as method // argument @@ -122,7 +123,7 @@ public class BrowseEntryLinkRepository extends AbstractDSpaceRestRepository binfo.getResultsPerPage()); Page page = new PageImpl<>(Arrays.asList(binfo.getStringResults()), pageResultInfo, binfo.getTotal()).map(browseEntryConverter); - BrowseIndexRest biRest = converter.toRest(bi); + BrowseIndexRest biRest = converter.toRest(bi, projection); page.forEach(t -> t.setBrowseIndex(biRest)); return page; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseIndexRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseIndexRestRepository.java index 1ee7b73109..a643b3d3d1 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseIndexRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseIndexRestRepository.java @@ -12,6 +12,7 @@ import java.util.List; import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.BrowseIndexRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.browse.BrowseException; import org.dspace.browse.BrowseIndex; import org.dspace.core.Context; @@ -42,7 +43,7 @@ public class BrowseIndexRestRepository extends DSpaceRestRepository page = new PageImpl(indexesList, pageable, total).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = new PageImpl<>(indexesList, pageable, total) + .map((object) -> converter.toRest(object, projection)); return page; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseItemLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseItemLinkRepository.java index be616b289f..6bd840f257 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseItemLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseItemLinkRepository.java @@ -14,9 +14,10 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; -import org.dspace.app.rest.converter.ItemConverter; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.BrowseIndexRest; import org.dspace.app.rest.model.ItemRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.utils.ScopeResolver; import org.dspace.browse.BrowseEngine; import org.dspace.browse.BrowseException; @@ -47,13 +48,13 @@ import org.springframework.stereotype.Component; public class BrowseItemLinkRepository extends AbstractDSpaceRestRepository implements LinkRestRepository { @Autowired - ItemConverter converter; + ConverterService converter; @Autowired ScopeResolver scopeResolver; public Page listBrowseItems(HttpServletRequest request, String browseName, Pageable pageable, - String projection) + Projection projection) throws BrowseException, SQLException { //FIXME these should be bind automatically and available as method arguments String scope = null; @@ -151,7 +152,9 @@ public class BrowseItemLinkRepository extends AbstractDSpaceRestRepository for (IndexableObject bb : binfo.getBrowseItemResults()) { tmpResult.add((Item) bb); } - Page page = new PageImpl(tmpResult, pageResultInfo, binfo.getTotal()).map(converter); + + Page page = new PageImpl(tmpResult, pageResultInfo, binfo.getTotal()) + .map((object) -> converter.toRest(object, projection)); return page; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java index e409b21e6b..248347ae0b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java @@ -93,7 +93,7 @@ public class ClaimedTaskRestRepository extends DSpaceRestRepository page = utils.getPage(tasks, pageable).map(converter::toRest); + Page page = utils.getPage(tasks, pageable) + .map((object) -> converter.toRest(object, utils.obtainProjection())); return page; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java index e3be796b6e..49d79c08b2 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java @@ -26,6 +26,7 @@ import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.CollectionRest; import org.dspace.app.rest.model.CommunityRest; import org.dspace.app.rest.model.patch.Patch; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.repository.patch.DSpaceObjectPatch; import org.dspace.app.rest.utils.CollectionRestEqualityUtils; import org.dspace.authorize.AuthorizeException; @@ -80,7 +81,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository page = new PageImpl<>(collections, pageable, total).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = new PageImpl<>(collections, pageable, total) + .map((object) -> converter.toRest(object, projection)); return page; } @@ -121,7 +124,8 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository page = utils.getPage(collections, pageable).map(converter::toRest); + Page page = utils.getPage(collections, pageable) + .map((object) -> converter.toRest(object, utils.obtainProjection())); return page; } @@ -138,7 +142,8 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository page = utils.getPage(collections, pageable).map(converter::toRest); + Page page = utils.getPage(collections, pageable) + .map((object) -> converter.toRest(object, utils.obtainProjection())); return page; } @@ -191,7 +196,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository page = new PageImpl(communities, pageable, total).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = new PageImpl<>(communities, pageable, total) + .map((object) -> converter.toRest(object, projection)); return page; } @@ -163,7 +166,8 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository page = utils.getPage(topCommunities, pageable).map(converter::toRest); + Page page = utils.getPage(topCommunities, pageable) + .map((object) -> converter.toRest(object, utils.obtainProjection())); return page; } @@ -184,7 +188,8 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository page = utils.getPage(subCommunities, pageable).map(converter::toRest); + Page page = utils.getPage(subCommunities, pageable) + .map((object) -> converter.toRest(object, utils.obtainProjection())); return page; } @@ -215,14 +220,14 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository searchFilters, final Pageable page) { + final List searchFilters, final Pageable page, + final Projection projection) { Context context = obtainContext(); IndexableObject scopeObject = scopeResolver.resolveScope(context, dsoScope); DiscoveryConfiguration discoveryConfiguration = searchConfigurationService @@ -111,7 +113,7 @@ public class DiscoveryRestRepository extends AbstractDSpaceRestRepository { return discoverResultConverter .convert(context, query, dsoType, configuration, dsoScope, searchFilters, page, searchResult, - discoveryConfiguration); + discoveryConfiguration, projection); } public FacetConfigurationRest getFacetsConfiguration(final String dsoScope, final String configuration) { @@ -150,7 +152,8 @@ public class DiscoveryRestRepository extends AbstractDSpaceRestRepository { } FacetResultsRest facetResultsRest = discoverFacetResultsConverter.convert(context, facetName, prefix, query, - dsoType, dsoScope, searchFilters, searchResult, discoveryConfiguration, page); + dsoType, dsoScope, searchFilters, searchResult, discoveryConfiguration, page, + utils.obtainProjection()); return facetResultsRest; } @@ -176,7 +179,8 @@ public class DiscoveryRestRepository extends AbstractDSpaceRestRepository { } SearchResultsRest searchResultsRest = discoverFacetsConverter.convert(context, query, dsoType, - configuration, dsoScope, searchFilters, page, discoveryConfiguration, searchResult); + configuration, dsoScope, searchFilters, page, discoveryConfiguration, searchResult, + utils.obtainProjection()); return searchResultsRest; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EPersonRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EPersonRestRepository.java index 20c2bb60a8..a0cec8ec22 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EPersonRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EPersonRestRepository.java @@ -22,6 +22,7 @@ import org.dspace.app.rest.exception.RESTAuthorizationException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.EPersonRest; import org.dspace.app.rest.model.patch.Patch; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.repository.patch.EPersonPatch; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.service.AuthorizeService; @@ -90,7 +91,7 @@ public class EPersonRestRepository extends DSpaceObjectRestRepository page = new PageImpl<>(epersons, pageable, total).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = new PageImpl<>(epersons, pageable, total) + .map((object) -> converter.toRest(object, projection)); return page; } @@ -149,7 +152,8 @@ public class EPersonRestRepository extends DSpaceObjectRestRepository page = new PageImpl<>(epersons, pageable, total).map(converter::toRest); + Page page = new PageImpl<>(epersons, pageable, total) + .map((object) -> converter.toRest(object, utils.obtainProjection())); return page; } @@ -173,7 +177,7 @@ public class EPersonRestRepository extends DSpaceObjectRestRepository page = utils.getPage(entityTypeList, pageable).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = utils.getPage(entityTypeList, pageable) + .map((object) -> converter.toRest(object, projection)); return page; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/GroupRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/GroupRestRepository.java index 1bb5bff849..5d6636abe0 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/GroupRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/GroupRestRepository.java @@ -19,6 +19,7 @@ import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.GroupRest; import org.dspace.app.rest.model.patch.Patch; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.repository.patch.DSpaceObjectPatch; import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; @@ -75,7 +76,7 @@ public class GroupRestRepository extends DSpaceObjectRestRepository page = new PageImpl(groups, pageable, total).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = new PageImpl(groups, pageable, total) + .map((object) -> converter.toRest(object, projection)); return page; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/HarvestedCollectionRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/HarvestedCollectionRestRepository.java index a2ecd92107..4ace76bbe9 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/HarvestedCollectionRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/HarvestedCollectionRestRepository.java @@ -13,15 +13,16 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; - import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import com.fasterxml.jackson.databind.ObjectMapper; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.converter.HarvestedCollectionConverter; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.HarvestTypeEnum; import org.dspace.app.rest.model.HarvestedCollectionRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.content.Collection; import org.dspace.core.Context; import org.dspace.harvest.HarvestedCollection; @@ -45,6 +46,9 @@ public class HarvestedCollectionRestRepository extends AbstractDSpaceRestReposit @Autowired HarvestedCollectionConverter harvestedCollectionConverter; + @Autowired + ConverterService converter; + public HarvestedCollectionRest findOne(Collection collection) throws SQLException { Context context = obtainContext(); @@ -54,7 +58,8 @@ public class HarvestedCollectionRestRepository extends AbstractDSpaceRestReposit HarvestedCollection harvestedCollection = harvestedCollectionService.find(context, collection); List> configs = OAIHarvester.getAvailableMetadataFormats(); - return harvestedCollectionConverter.fromModel(harvestedCollection, collection, configs); + return harvestedCollectionConverter.fromModel(harvestedCollection, collection, configs, + utils.obtainProjection()); } /** @@ -75,7 +80,7 @@ public class HarvestedCollectionRestRepository extends AbstractDSpaceRestReposit if (harvestedCollectionRest.getHarvestType() == HarvestTypeEnum.NONE.getValue() && harvestedCollection != null) { harvestedCollectionService.delete(context, harvestedCollection); - return harvestedCollectionConverter.convert(null); + return harvestedCollectionConverter.convert(null, utils.obtainProjection()); } else if (harvestedCollectionRest.getHarvestType() != HarvestTypeEnum.NONE.getValue()) { List errors = testHarvestSettings(harvestedCollectionRest); @@ -89,7 +94,8 @@ public class HarvestedCollectionRestRepository extends AbstractDSpaceRestReposit harvestedCollection = harvestedCollectionService.find(context, collection); List> configs = OAIHarvester.getAvailableMetadataFormats(); - return harvestedCollectionConverter.fromModel(harvestedCollection, collection, configs); + return harvestedCollectionConverter.fromModel(harvestedCollection, collection, configs, + Projection.DEFAULT); } else { throw new UnprocessableEntityException( "Incorrect harvest settings in request. The following errors were found: " + errors.toString() @@ -147,7 +153,6 @@ public class HarvestedCollectionRestRepository extends AbstractDSpaceRestReposit /** * Function used to verify that the harvest settings work - * @param collection The collection to which the harvest settings should be aplied * @param harvestedCollectionRest A object containg the harvest settings to be tested * @return */ diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRelationshipLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRelationshipLinkRepository.java index 21a139b4e5..08f2c62f8e 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRelationshipLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRelationshipLinkRepository.java @@ -16,6 +16,7 @@ import javax.servlet.http.HttpServletRequest; import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.ItemRest; import org.dspace.app.rest.model.RelationshipRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.content.Item; import org.dspace.content.Relationship; import org.dspace.content.service.ItemService; @@ -48,7 +49,7 @@ public class ItemRelationshipLinkRepository extends AbstractDSpaceRestRepository public Page getItemRelationships(@Nullable HttpServletRequest request, UUID itemId, @Nullable Pageable optionalPageable, - @Nullable String projection) { + Projection projection) { try { Context context = obtainContext(); Item item = itemService.find(context, itemId); @@ -60,7 +61,8 @@ public class ItemRelationshipLinkRepository extends AbstractDSpaceRestRepository Integer offset = pageable == null ? null : pageable.getOffset(); int total = relationshipService.countByItem(context, item); List relationships = relationshipService.findByItem(context, item, limit, offset); - return new PageImpl<>(relationships, pageable, total).map(converter::toRest); + return new PageImpl<>(relationships, pageable, total) + .map((object) -> converter.toRest(object, projection)); } catch (SQLException e) { throw new RuntimeException(e); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java index d10b149015..1d1d2ffcce 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java @@ -26,7 +26,7 @@ import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.ItemRest; import org.dspace.app.rest.model.patch.Patch; -import org.dspace.app.rest.projection.ListProjection; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.repository.patch.ItemPatch; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Collection; @@ -94,7 +94,7 @@ public class ItemRestRepository extends DSpaceObjectRestRepository(items, pageable, total).map((item) -> converter.toRest(item, ListProjection.NAME)); + Projection projection = utils.obtainProjection(true); + return new PageImpl<>(items, pageable, total).map((object) -> converter.toRest(object, projection)); } @Override @@ -208,7 +209,7 @@ public class ItemRestRepository extends DSpaceObjectRestRepository page = utils.getPage(metadataField, pageable).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = utils.getPage(metadataField, pageable) + .map((object) -> converter.toRest(object, projection)); return page; } @@ -99,7 +102,9 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository page = utils.getPage(metadataFields, pageable).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = utils.getPage(metadataFields, pageable) + .map((object) -> converter.toRest(object, projection)); return page; } @@ -157,7 +162,7 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository page = utils.getPage(metadataSchema, pageable).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = utils.getPage(metadataSchema, pageable) + .map((object) -> converter.toRest(object, projection)); return page; } @@ -119,7 +122,7 @@ public class MetadataSchemaRestRepository extends DSpaceRestRepository page = utils.getPage(tasks, pageable).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = utils.getPage(tasks, pageable) + .map((object) -> converter.toRest(object, projection)); return page; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipRestRepository.java index 5eb5c71e6c..a90be9b8f1 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipRestRepository.java @@ -24,6 +24,7 @@ import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.RelationshipRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.service.AuthorizeService; import org.dspace.content.DSpaceObject; @@ -71,7 +72,7 @@ public class RelationshipRestRepository extends DSpaceRestRepository page = new PageImpl<>(relationships, pageable, total).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = new PageImpl<>(relationships, pageable, total) + .map((object) -> converter.toRest(object, projection)); return page; } @@ -126,7 +129,7 @@ public class RelationshipRestRepository extends DSpaceRestRepository page = new PageImpl<>(relationships, pageable, total).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = new PageImpl<>(relationships, pageable, total) + .map((object) -> converter.toRest(object, projection)); return page; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipTypeRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipTypeRestRepository.java index 8e67475fa7..36f72b2fc7 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipTypeRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipTypeRestRepository.java @@ -12,6 +12,7 @@ import java.util.List; import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.RelationshipTypeRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.content.RelationshipType; import org.dspace.content.service.RelationshipTypeService; import org.dspace.core.Context; @@ -35,7 +36,7 @@ public class RelationshipTypeRestRepository extends DSpaceRestRepository page = utils.getPage(relationshipTypeList, pageable).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = utils.getPage(relationshipTypeList, pageable) + .map((object) -> converter.toRest(object, projection)); return page; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ResourcePolicyRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ResourcePolicyRestRepository.java index 1c75e2abca..3ef2148f5a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ResourcePolicyRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ResourcePolicyRestRepository.java @@ -51,7 +51,7 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository page = new PageImpl(sites, pageable, total).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = new PageImpl(sites, pageable, total) + .map((object) -> converter.toRest(object, projection)); return page; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionDefinitionRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionDefinitionRestRepository.java index 37e5be1a5a..213991e144 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionDefinitionRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionDefinitionRestRepository.java @@ -15,6 +15,7 @@ import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.SubmissionDefinitionRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.util.SubmissionConfig; import org.dspace.app.util.SubmissionConfigReader; import org.dspace.app.util.SubmissionConfigReaderException; @@ -54,7 +55,7 @@ public class SubmissionDefinitionRestRepository extends DSpaceRestRepository subConfs = submissionConfigReader.getAllSubmissionConfigs( pageable.getPageSize(), pageable.getOffset()); - Page page = new PageImpl<>(subConfs, pageable, total).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = new PageImpl<>(subConfs, pageable, total) + .map((object) -> converter.toRest(object, projection)); return page; } @@ -76,7 +79,8 @@ public class SubmissionDefinitionRestRepository extends DSpaceRestRepository page = new PageImpl<>(subConfs, pageable, total).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = new PageImpl<>(subConfs, pageable, total) + .map((object) -> converter.toRest(object, projection)); return page; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionPanelRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionPanelRestRepository.java index 2f0202bf12..456cd0e4f6 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionPanelRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionPanelRestRepository.java @@ -13,6 +13,7 @@ import java.util.List; import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.SubmissionDefinitionRest; import org.dspace.app.rest.model.SubmissionSectionRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.util.SubmissionConfig; import org.dspace.app.util.SubmissionConfigReader; import org.dspace.app.util.SubmissionConfigReaderException; @@ -47,7 +48,7 @@ public class SubmissionPanelRestRepository extends DSpaceRestRepository page = new PageImpl<>(stepConfs, pageable, total).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = new PageImpl<>(stepConfs, pageable, total) + .map((object) -> converter.toRest(object, projection)); return page; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java index 95bba5ce8e..5c4a9012a5 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java @@ -12,8 +12,10 @@ import java.util.List; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Logger; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.AccessConditionOptionRest; import org.dspace.app.rest.model.SubmissionUploadRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.utils.DateMathParser; import org.dspace.app.util.SubmissionConfig; import org.dspace.app.util.SubmissionConfigReader; @@ -56,6 +58,9 @@ public class SubmissionUploadRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { List subConfs = new ArrayList(); subConfs = submissionConfigReader.getAllSubmissionConfigs(pageable.getPageSize(), pageable.getOffset()); + Projection projection = utils.obtainProjection(true); List results = new ArrayList<>(); for (SubmissionConfig config : subConfs) { for (int i = 0; i < config.getNumberOfSteps(); i++) { @@ -87,7 +93,7 @@ public class SubmissionUploadRestRepository extends DSpaceRestRepository page = new PageImpl<>(witems, pageable, total).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = new PageImpl<>(witems, pageable, total) + .map((object) -> converter.toRest(object, projection)); return page; } @@ -137,7 +140,9 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository page = new PageImpl<>(witems, pageable, total).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = new PageImpl<>(witems, pageable, total) + .map((object) -> converter.toRest(object, projection)); return page; } @@ -161,7 +166,7 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository page = new PageImpl(witems, pageable, total).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = new PageImpl<>(witems, pageable, total) + .map((object) -> converter.toRest(object, projection)); return page; } @@ -157,14 +160,16 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository page = new PageImpl<>(witems, pageable, total).map(converter::toRest); + Projection projection = utils.obtainProjection(true); + Page page = new PageImpl<>(witems, pageable, total) + .map((object) -> converter.toRest(object, projection)); return page; } @Override protected WorkspaceItemRest createAndReturn(Context context) throws SQLException, AuthorizeException { WorkspaceItem source = submissionService.createWorkspaceItem(context, getRequestService().getCurrentRequest()); - return converter.toRest(source); + return converter.toRest(source, Projection.DEFAULT); } @Override @@ -252,7 +257,7 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository> dSpaceObjectServices; @@ -197,7 +201,6 @@ public class Utils { * * @param schema * @param element - * @param object * @return */ public String getMetadataKey(String schema, String element, String qualifier) { @@ -299,7 +302,6 @@ public class Utils { * It will then look through all the DSpaceObjectServices to try and match this UUID to a DSpaceObject. * If one is found, this DSpaceObject is added to the List of DSpaceObjects that we will return. * @param context The relevant DSpace context - * @param request The request out of which we'll create the List of DSpaceObjects * @return The resulting list of DSpaceObjects that we parsed out of the request */ public List constructDSpaceObjectList(Context context, List list) { @@ -407,6 +409,33 @@ public class Utils { throw new IllegalArgumentException("No such method in " + clazz + ": " + name); } + /** + * Gets the projection requested by the current servlet request, or a default projection if none is specified. + * + * @param defaultToList whether to return {@link ListProjection} by default. If false, the no-op + * {@link DefaultProjection} will be returned by default. + * @return the requested or default projection, never {@code null}. + * @throws IllegalArgumentException if the request specifies an unknown projection name. + */ + public Projection obtainProjection(boolean defaultToList) { + String projectionName = requestService.getCurrentRequest().getServletRequest().getParameter("projection"); + if (projectionName == null && defaultToList) { + projectionName = ListProjection.NAME; + } + return converter.getProjection(projectionName); + } + + /** + * Gets the projection requested by the current servlet request, or {@link DefaultProjection} if none + * is specified. + * + * @return the requested or default projection, never {@code null}. + * @throws IllegalArgumentException if the request specifies an unknown projection name. + */ + public Projection obtainProjection() { + return obtainProjection(false); + } + /** * Adds embeds or links for all class-level LinkRel annotations for which embeds or links are allowed. * @@ -445,11 +474,12 @@ public class Utils { String rel, Link link, String methodName) { LinkRestRepository linkRepository = getLinkResourceRepository(resource.getContent().getCategory(), resource.getContent().getType(), rel); + Projection projection = resource.getContent().getProjection(); if (linkRepository.isEmbeddableRelation(resource.getContent(), rel)) { Method method = requireMethod(linkRepository.getClass(), methodName); Object contentId = getContentIdForLinkMethod(resource.getContent(), method); try { - Object linkedObject = method.invoke(linkRepository, null, contentId, null, null); + Object linkedObject = method.invoke(linkRepository, null, contentId, null, projection); resource.embedResource(rel, wrapForEmbedding(linkedObject, link)); } catch (IllegalAccessException | InvocationTargetException e) { throw new RuntimeException(e); @@ -536,7 +566,7 @@ public class Utils { list.subList(0, list.size() > EMBEDDED_PAGE_SIZE ? EMBEDDED_PAGE_SIZE : list.size()), new PageRequest(0, EMBEDDED_PAGE_SIZE), list.size()); return new EmbeddedPage(link.getHref(), - page.map((restObject) -> converter.toResource(restObject, ListProjection.NAME)), + page.map((restObject) -> converter.toResource(restObject)), list, link.getRel()); } else { PageImpl page = new PageImpl(list); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamFormatRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamFormatRestRepositoryIT.java index 4957d89ea4..c2eda5bb64 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamFormatRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamFormatRestRepositoryIT.java @@ -30,6 +30,7 @@ import org.dspace.app.rest.builder.EPersonBuilder; import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.matcher.BitstreamFormatMatcher; import org.dspace.app.rest.model.BitstreamFormatRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.content.BitstreamFormat; import org.dspace.content.service.BitstreamFormatService; @@ -279,7 +280,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati .build(); context.restoreAuthSystemState(); - BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat); + BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat, Projection.DEFAULT); String token = getAuthToken(admin.getEmail(), password); //Update it bitstreamFormatRest.setShortDescription("Test short UPDATED"); @@ -311,7 +312,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati .build(); context.restoreAuthSystemState(); - BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat); + BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat, Projection.DEFAULT); String token = getAuthToken(admin.getEmail(), password); //Update it bitstreamFormatRest.setShortDescription("Test short UPDATED"); @@ -349,7 +350,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati int nonExistentBitstreamFormatID = 404404404; - BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat); + BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat, Projection.DEFAULT); String token = getAuthToken(admin.getEmail(), password); //Update it with non existent ID in URL and in JSON bitstreamFormatRest.setShortDescription("Test short UPDATED"); @@ -386,7 +387,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati int nonExistentBitstreamFormatID = 404404404; - BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat); + BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat, Projection.DEFAULT); String token = getAuthToken(admin.getEmail(), password); //Update it with non existent ID in URL bitstreamFormatRest.setShortDescription("Test short UPDATED"); @@ -422,7 +423,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati int nonExistentBitstreamFormatID = 404404404; - BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat); + BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat, Projection.DEFAULT); String token = getAuthToken(admin.getEmail(), password); //Update it with non existent ID in JSON, but valid in URL bitstreamFormatRest.setShortDescription("Test short UPDATED"); @@ -460,7 +461,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati .build(); context.restoreAuthSystemState(); - BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat1); + BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat1, Projection.DEFAULT); String token = getAuthToken(admin.getEmail(), password); //Update but id in body is not same id as in URL bitstreamFormatRest.setShortDescription("Test short UPDATED"); @@ -493,7 +494,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati .build(); context.restoreAuthSystemState(); - BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat); + BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat, Projection.DEFAULT); //Try to update bitstreamFormat without auth token bitstreamFormatRest.setShortDescription("Test short UPDATED"); @@ -529,7 +530,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati .build(); context.restoreAuthSystemState(); - BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat); + BitstreamFormatRest bitstreamFormatRest = converter.toRest(bitstreamFormat, Projection.DEFAULT); String token = getAuthToken(user.getEmail(), password); //Try to update bitstreamFormat without non-admin auth token diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionRestRepositoryIT.java index 21ad836cea..78e2cc39e2 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionRestRepositoryIT.java @@ -30,6 +30,7 @@ import org.dspace.app.rest.matcher.MetadataMatcher; import org.dspace.app.rest.model.CollectionRest; import org.dspace.app.rest.model.MetadataRest; import org.dspace.app.rest.model.MetadataValueRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.app.rest.test.MetadataPatchSuite; import org.dspace.authorize.service.AuthorizeService; @@ -369,7 +370,7 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes ObjectMapper mapper = new ObjectMapper(); - CollectionRest collectionRest = converter.toRest(col1); + CollectionRest collectionRest = converter.toRest(col1, Projection.DEFAULT); collectionRest.setMetadata(new MetadataRest() .put("dc.title", new MetadataValueRest("Electronic theses and dissertations"))); @@ -730,7 +731,7 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes String token = getAuthToken(eperson.getEmail(), password); ObjectMapper mapper = new ObjectMapper(); - CollectionRest collectionRest = converter.toRest(col1); + CollectionRest collectionRest = converter.toRest(col1, Projection.DEFAULT); collectionRest.setMetadata(new MetadataRest() .put("dc.title", new MetadataValueRest("Electronic theses and dissertations"))); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CommunityRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CommunityRestRepositoryIT.java index 1d39c9c41b..b3b8c6c22e 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CommunityRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CommunityRestRepositoryIT.java @@ -39,6 +39,7 @@ import org.dspace.app.rest.matcher.PageMatcher; import org.dspace.app.rest.model.CommunityRest; import org.dspace.app.rest.model.MetadataRest; import org.dspace.app.rest.model.MetadataValueRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.app.rest.test.MetadataPatchSuite; import org.dspace.authorize.service.AuthorizeService; @@ -830,7 +831,7 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest ObjectMapper mapper = new ObjectMapper(); - CommunityRest communityRest = converter.toRest(parentCommunity); + CommunityRest communityRest = converter.toRest(parentCommunity, Projection.DEFAULT); communityRest.setMetadata(new MetadataRest() .put("dc.title", new MetadataValueRest("Electronic theses and dissertations"))); @@ -1040,7 +1041,7 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest ObjectMapper mapper = new ObjectMapper(); - CommunityRest communityRest = converter.toRest(parentCommunity); + CommunityRest communityRest = converter.toRest(parentCommunity, Projection.DEFAULT); communityRest.setMetadata(new MetadataRest() .put("dc.title", new MetadataValueRest("Electronic theses and dissertations"))); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataSchemaRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataSchemaRestRepositoryIT.java index 64b43bb8bd..9aa2820eae 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataSchemaRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataSchemaRestRepositoryIT.java @@ -25,6 +25,7 @@ import org.dspace.app.rest.builder.MetadataSchemaBuilder; import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.matcher.MetadataschemaMatcher; import org.dspace.app.rest.model.MetadataSchemaRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.content.MetadataSchema; import org.hamcrest.Matchers; @@ -88,7 +89,7 @@ public class MetadataSchemaRestRepositoryIT extends AbstractControllerIntegratio .build(); context.restoreAuthSystemState(); - MetadataSchemaRest metadataSchemaRest = converter.toRest(metadataSchema); + MetadataSchemaRest metadataSchemaRest = converter.toRest(metadataSchema, Projection.DEFAULT); metadataSchemaRest.setPrefix(TEST_NAME); metadataSchemaRest.setNamespace(TEST_NAMESPACE); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/converter/DiscoverConfigurationConverterTest.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/converter/DiscoverConfigurationConverterTest.java index 5cd2b72107..333d624010 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/converter/DiscoverConfigurationConverterTest.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/converter/DiscoverConfigurationConverterTest.java @@ -16,6 +16,7 @@ import static org.mockito.Mockito.when; import java.util.LinkedList; import org.dspace.app.rest.model.SearchConfigurationRest; +import org.dspace.app.rest.projection.Projection; import org.dspace.discovery.configuration.DiscoveryConfiguration; import org.dspace.discovery.configuration.DiscoverySearchFilter; import org.dspace.discovery.configuration.DiscoverySortConfiguration; @@ -56,20 +57,20 @@ public class DiscoverConfigurationConverterTest { @Test public void testReturnType() throws Exception { populateDiscoveryConfigurationWithEmptyList(); - searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration); + searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration, Projection.DEFAULT); assertTrue(searchConfigurationRest.getFilters().isEmpty()); assertEquals(SearchConfigurationRest.class, searchConfigurationRest.getClass()); } @Test public void testConvertWithNullParamter() throws Exception { - assertNotNull(discoverConfigurationConverter.convert(null)); + assertNotNull(discoverConfigurationConverter.convert(null, Projection.DEFAULT)); } @Test public void testNoSearchSortConfigurationReturnObjectNotNull() throws Exception { discoveryConfiguration.setSearchFilters(new LinkedList<>()); - searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration); + searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration, Projection.DEFAULT); assertTrue(discoveryConfiguration.getSearchFilters().isEmpty()); assertTrue(searchConfigurationRest.getFilters().isEmpty()); assertNotNull(searchConfigurationRest); @@ -78,7 +79,7 @@ public class DiscoverConfigurationConverterTest { @Test public void testNoSearchFilterReturnObjectNotNull() throws Exception { discoveryConfiguration.setSearchSortConfiguration(new DiscoverySortConfiguration()); - searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration); + searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration, Projection.DEFAULT); assertTrue(searchConfigurationRest.getFilters().isEmpty()); assertNotNull(searchConfigurationRest); } @@ -87,7 +88,7 @@ public class DiscoverConfigurationConverterTest { // are null @Test public void testNoSearchSortConfigurationAndNoSearchFilterReturnObjectNotNull() throws Exception { - searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration); + searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration, Projection.DEFAULT); assertNotNull(searchConfigurationRest); } @@ -108,7 +109,7 @@ public class DiscoverConfigurationConverterTest { when(discoveryConfiguration.getSearchSortConfiguration()).thenReturn(discoverySortConfiguration); when(discoverySortConfiguration.getSortFields()).thenReturn(mockedList); - searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration); + searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration, Projection.DEFAULT); int counter = 0; for (SearchConfigurationRest.SortOption sortOption : searchConfigurationRest.getSortOptions()) { @@ -123,7 +124,7 @@ public class DiscoverConfigurationConverterTest { @Test public void testEmptySortOptionsAfterConvertWithConfigurationWithEmptySortFields() throws Exception { populateDiscoveryConfigurationWithEmptyList(); - searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration); + searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration, Projection.DEFAULT); assertEquals(0, searchConfigurationRest.getSortOptions().size()); } @@ -132,7 +133,7 @@ public class DiscoverConfigurationConverterTest { public void testEmptySortOptionsAfterConvertWithConfigurationWithNullSortFields() throws Exception { populateDiscoveryConfigurationWithEmptyList(); when(discoveryConfiguration.getSearchSortConfiguration()).thenReturn(null); - searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration); + searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration, Projection.DEFAULT); assertEquals(0, searchConfigurationRest.getSortOptions().size()); } @@ -151,7 +152,7 @@ public class DiscoverConfigurationConverterTest { mockedList.add(discoverySearchFilter1); when(discoveryConfiguration.getSearchFilters()).thenReturn(mockedList); - searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration); + searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration, Projection.DEFAULT); int counter = 0; for (SearchConfigurationRest.Filter filter : searchConfigurationRest.getFilters()) { @@ -169,7 +170,7 @@ public class DiscoverConfigurationConverterTest { @Test public void testEmptySearchFilterAfterConvertWithConfigurationWithEmptySearchFilters() throws Exception { populateDiscoveryConfigurationWithEmptyList(); - searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration); + searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration, Projection.DEFAULT); assertEquals(0, searchConfigurationRest.getFilters().size()); } @@ -178,7 +179,7 @@ public class DiscoverConfigurationConverterTest { populateDiscoveryConfigurationWithEmptyList(); when(discoveryConfiguration.getSearchFilters()).thenReturn(null); - searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration); + searchConfigurationRest = discoverConfigurationConverter.convert(discoveryConfiguration, Projection.DEFAULT); assertEquals(0, searchConfigurationRest.getFilters().size()); } From 1d914b74c7b03ef19a2d714f7c7e5dfe5dc609bb Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Thu, 7 Nov 2019 10:52:32 -0500 Subject: [PATCH 08/20] DS-3533 Simplify and normalize code --- .../app/rest/RestResourceController.java | 12 ++--- .../app/rest/converter/ConverterService.java | 22 +++++++++ .../AbstractDSpaceRestRepository.java | 4 ++ .../repository/AuthorityRestRepository.java | 7 ++- .../BitstreamFormatRestRepository.java | 17 +------ .../repository/BrowseEntryLinkRepository.java | 4 -- .../repository/BrowseIndexRestRepository.java | 23 ++------- .../repository/BrowseItemLinkRepository.java | 8 +--- .../repository/ClaimedTaskRestRepository.java | 11 +---- .../repository/CollectionRestRepository.java | 47 ++++--------------- .../repository/CommunityRestRepository.java | 31 +++--------- .../DSpaceObjectRestRepository.java | 4 -- .../repository/EPersonRestRepository.java | 28 +++-------- .../repository/EntityTypeRestRepository.java | 13 +---- .../rest/repository/GroupRestRepository.java | 12 ++--- .../HarvestedCollectionRestRepository.java | 4 -- .../ItemRelationshipLinkRepository.java | 8 +--- .../rest/repository/ItemRestRepository.java | 15 ++---- .../MetadataFieldRestRepository.java | 25 ++-------- .../MetadataSchemaRestRepository.java | 15 +----- .../repository/PoolTaskRestRepository.java | 13 +---- .../RelationshipRestRepository.java | 24 ++-------- .../RelationshipTypeRestRepository.java | 13 +---- .../ResourcePolicyRestRepository.java | 8 ---- .../rest/repository/SiteRestRepository.java | 13 ++--- .../repository/StatisticsRestRepository.java | 1 - .../SubmissionDefinitionRestRepository.java | 12 +---- .../SubmissionFormRestRepository.java | 18 ++----- .../SubmissionPanelRestRepository.java | 18 ++----- .../SubmissionUploadRestRepository.java | 4 -- .../WorkflowItemRestRepository.java | 35 +++++--------- .../WorkspaceItemRestRepository.java | 32 +++++-------- .../java/org/dspace/app/rest/utils/Utils.java | 2 + 33 files changed, 129 insertions(+), 374 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java index d3b6ffef80..8261c3f36c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java @@ -153,9 +153,9 @@ public class RestResourceController implements InitializingBean { * * Note that the regular expression in the request mapping accept a number as identifier; * - * Please see {@link RestResourceController#findOne(String, String, String, String)} for findOne with string as + * Please see {@link RestResourceController#findOne(String, String, String)} for findOne with string as * identifier - * and see {@link RestResourceController#findOne(String, String, UUID, String)} for uuid as identifier + * and see {@link RestResourceController#findOne(String, String, UUID)} for uuid as identifier * * @param apiCategory * @param model @@ -185,9 +185,9 @@ public class RestResourceController implements InitializingBean { * * * - * Please see {@link RestResourceController#findOne(String, String, Integer, String)} for findOne with number as + * Please see {@link RestResourceController#findOne(String, String, Integer)} for findOne with number as * identifier - * and see {@link RestResourceController#findOne(String, String, UUID, String)} for uuid as identifier + * and see {@link RestResourceController#findOne(String, String, UUID)} for uuid as identifier * * @param apiCategory * @param model @@ -206,9 +206,9 @@ public class RestResourceController implements InitializingBean { * * Note that the regular expression in the request mapping accept a UUID as identifier; * - * Please see {@link RestResourceController#findOne(String, String, Integer, String)} for findOne with number as + * Please see {@link RestResourceController#findOne(String, String, Integer)} for findOne with number as * identifier - * and see {@link RestResourceController#findOne(String, String, String, String)} for string as identifier + * and see {@link RestResourceController#findOne(String, String, String)} for string as identifier * * @param apiCategory * @param model diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java index 9f3615a13e..fb85a68f71 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java @@ -29,6 +29,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.core.type.filter.AssignableTypeFilter; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; import org.springframework.hateoas.Resource; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; @@ -89,6 +92,25 @@ public class ConverterService { return restObject; } + /** + * Converts a list of model objects to a page of rest objects using the given {@link Projection}. + * + * @param modelObjects + * @param pageable + * @param total + * @param projection + * @param + * @param + * @return + */ + public Page toRestPage(List modelObjects, Pageable pageable, long total, Projection projection) { + return new PageImpl<>(modelObjects, pageable, total).map((object) -> toRest(object, projection)); + } + + public Page toRestPage(Page modelObjects, Projection projection) { + return modelObjects.map((object) -> toRest(object, projection)); + } + /** * Gets the converter supporting the given class as input. * diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AbstractDSpaceRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AbstractDSpaceRestRepository.java index 8b37dbf79c..a64f8af5df 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AbstractDSpaceRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AbstractDSpaceRestRepository.java @@ -7,6 +7,7 @@ */ package org.dspace.app.rest.repository; +import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.utils.ContextUtil; import org.dspace.app.rest.utils.Utils; import org.dspace.core.Context; @@ -26,6 +27,9 @@ public abstract class AbstractDSpaceRestRepository { @Autowired protected Utils utils; + @Autowired + protected ConverterService converter; + protected RequestService requestService = new DSpace().getRequestService(); protected Context obtainContext() { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityRestRepository.java index 4a5f72cd47..27bc585f11 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorityRestRepository.java @@ -42,22 +42,21 @@ public class AuthorityRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { Set authoritiesName = cas.getChoiceAuthoritiesNames(); - List results = new ArrayList(); + List results = new ArrayList<>(); Projection projection = utils.obtainProjection(true); for (String authorityName : authoritiesName) { ChoiceAuthority source = cas.getChoiceAuthorityByAuthorityName(authorityName); AuthorityRest result = authorityUtils.convertAuthority(source, authorityName, projection); results.add(result); } - return new PageImpl(results, pageable, results.size()); + return new PageImpl<>(results, pageable, results.size()); } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java index da9a8176d3..9e9142cd63 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java @@ -15,7 +15,6 @@ import javax.servlet.http.HttpServletRequest; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.BitstreamFormatRest; @@ -43,14 +42,6 @@ public class BitstreamFormatRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { - List bit = null; try { - bit = bitstreamFormatService.findAll(context); + List bit = bitstreamFormatService.findAll(context); + return converter.toRestPage(utils.getPage(bit, pageable), utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Projection projection = utils.obtainProjection(true); - Page page = utils.getPage(bit, pageable) - .map((object) -> converter.toRest(object, projection)); - return page; } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseEntryLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseEntryLinkRepository.java index 8c4e2ca6d9..501d5202f1 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseEntryLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseEntryLinkRepository.java @@ -14,7 +14,6 @@ import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; import org.dspace.app.rest.converter.BrowseEntryConverter; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.BrowseEntryRest; import org.dspace.app.rest.model.BrowseIndexRest; import org.dspace.app.rest.projection.Projection; @@ -45,9 +44,6 @@ import org.springframework.stereotype.Component; public class BrowseEntryLinkRepository extends AbstractDSpaceRestRepository implements LinkRestRepository { - @Autowired - ConverterService converter; - @Autowired BrowseEntryConverter browseEntryConverter; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseIndexRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseIndexRestRepository.java index a643b3d3d1..83d230d503 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseIndexRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseIndexRestRepository.java @@ -7,18 +7,14 @@ */ package org.dspace.app.rest.repository; -import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.BrowseIndexRest; -import org.dspace.app.rest.projection.Projection; import org.dspace.browse.BrowseException; import org.dspace.browse.BrowseIndex; import org.dspace.core.Context; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Component; @@ -30,9 +26,6 @@ import org.springframework.stereotype.Component; @Component(BrowseIndexRest.CATEGORY + "." + BrowseIndexRest.NAME) public class BrowseIndexRestRepository extends DSpaceRestRepository { - @Autowired - ConverterService converter; - @Override public BrowseIndexRest findOne(Context context, String name) { BrowseIndexRest bi = null; @@ -50,22 +43,12 @@ public class BrowseIndexRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { - List it = null; - List indexesList = new ArrayList(); - int total = 0; try { - BrowseIndex[] indexes = BrowseIndex.getBrowseIndices(); - total = indexes.length; - for (BrowseIndex bix : indexes) { - indexesList.add(bix); - } + List indexes = Arrays.asList(BrowseIndex.getBrowseIndices()); + return converter.toRestPage(indexes, pageable, indexes.size(), utils.obtainProjection(true)); } catch (BrowseException e) { throw new RuntimeException(e.getMessage(), e); } - Projection projection = utils.obtainProjection(true); - Page page = new PageImpl<>(indexesList, pageable, total) - .map((object) -> converter.toRest(object, projection)); - return page; } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseItemLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseItemLinkRepository.java index 6bd840f257..8692bd6804 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseItemLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BrowseItemLinkRepository.java @@ -14,7 +14,6 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.BrowseIndexRest; import org.dspace.app.rest.model.ItemRest; import org.dspace.app.rest.projection.Projection; @@ -31,7 +30,6 @@ import org.dspace.sort.SortException; import org.dspace.sort.SortOption; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -47,8 +45,6 @@ import org.springframework.stereotype.Component; @Component(BrowseIndexRest.CATEGORY + "." + BrowseIndexRest.NAME + "." + BrowseIndexRest.ITEMS) public class BrowseItemLinkRepository extends AbstractDSpaceRestRepository implements LinkRestRepository { - @Autowired - ConverterService converter; @Autowired ScopeResolver scopeResolver; @@ -153,9 +149,7 @@ public class BrowseItemLinkRepository extends AbstractDSpaceRestRepository tmpResult.add((Item) bb); } - Page page = new PageImpl(tmpResult, pageResultInfo, binfo.getTotal()) - .map((object) -> converter.toRest(object, projection)); - return page; + return converter.toRestPage(tmpResult, pageResultInfo, binfo.getTotal(), projection); } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java index 248347ae0b..f0e1beff3c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java @@ -18,7 +18,6 @@ import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.RESTAuthorizationException; import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException; import org.dspace.app.rest.exception.UnprocessableEntityException; @@ -69,9 +68,6 @@ public class ClaimedTaskRestRepository extends DSpaceRestRepository findByUser(@Parameter(value = "uuid", required = true) UUID userID, Pageable pageable) { //FIXME this should be secured with annotation but they are currently ignored by search methods - List tasks = null; try { Context context = obtainContext(); EPerson currentUser = context.getCurrentUser(); @@ -111,16 +106,14 @@ public class ClaimedTaskRestRepository extends DSpaceRestRepository tasks = claimedTaskService.findByEperson(context, ep); + return converter.toRestPage(utils.getPage(tasks, pageable), utils.obtainProjection(true)); } else { throw new RESTAuthorizationException("Only administrators can search for claimed tasks of other users"); } } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Page page = utils.getPage(tasks, pageable) - .map((object) -> converter.toRest(object, utils.obtainProjection())); - return page; } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java index 49d79c08b2..0e2165eeae 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java @@ -9,7 +9,6 @@ package org.dspace.app.rest.repository; import java.io.IOException; import java.sql.SQLException; -import java.util.ArrayList; import java.util.List; import java.util.UUID; import javax.servlet.ServletInputStream; @@ -19,7 +18,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException; import org.dspace.app.rest.exception.UnprocessableEntityException; @@ -38,7 +36,6 @@ import org.dspace.core.Constants; import org.dspace.core.Context; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.rest.webmvc.ResourceNotFoundException; import org.springframework.security.access.prepost.PreAuthorize; @@ -58,9 +55,6 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository findAll(Context context, Pageable pageable) { - List it = null; - List collections = new ArrayList(); - int total = 0; try { - total = cs.countTotal(context); - it = cs.findAll(context, pageable.getPageSize(), pageable.getOffset()); - for (Collection c : it) { - collections.add(c); - } + long total = cs.countTotal(context); + List collections = cs.findAll(context, pageable.getPageSize(), pageable.getOffset()); + return converter.toRestPage(collections, pageable, total, utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Projection projection = utils.obtainProjection(true); - Page page = new PageImpl<>(collections, pageable, total) - .map((object) -> converter.toRest(object, projection)); - return page; } @SearchRestMethod(name = "findAuthorizedByCommunity") public Page findAuthorizedByCommunity( @Parameter(value = "uuid", required = true) UUID communityUuid, Pageable pageable) { - Context context = obtainContext(); - List it = null; - List collections = new ArrayList(); try { + Context context = obtainContext(); Community com = communityService.find(context, communityUuid); if (com == null) { throw new ResourceNotFoundException( CommunityRest.CATEGORY + "." + CommunityRest.NAME + " with id: " + communityUuid + " not found"); } - it = cs.findAuthorized(context, com, Constants.ADD); - for (Collection c : it) { - collections.add(c); - } + List collections = cs.findAuthorized(context, com, Constants.ADD); + return converter.toRestPage(utils.getPage(collections, pageable), utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Page page = utils.getPage(collections, pageable) - .map((object) -> converter.toRest(object, utils.obtainProjection())); - return page; } @SearchRestMethod(name = "findAuthorized") public Page findAuthorized(Pageable pageable) { - Context context = obtainContext(); - List it = null; - List collections = new ArrayList(); try { - it = cs.findAuthorizedOptimized(context, Constants.ADD); - for (Collection c : it) { - collections.add(c); - } + Context context = obtainContext(); + List collections = cs.findAuthorizedOptimized(context, Constants.ADD); + return converter.toRestPage(utils.getPage(collections, pageable), utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Page page = utils.getPage(collections, pageable) - .map((object) -> converter.toRest(object, utils.obtainProjection())); - return page; } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CommunityRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CommunityRestRepository.java index cf463f5cd9..c5aa6d07f4 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CommunityRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CommunityRestRepository.java @@ -9,7 +9,6 @@ package org.dspace.app.rest.repository; import java.io.IOException; import java.sql.SQLException; -import java.util.ArrayList; import java.util.List; import java.util.UUID; import javax.servlet.ServletInputStream; @@ -33,7 +32,6 @@ import org.dspace.content.service.CommunityService; import org.dspace.core.Context; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.rest.webmvc.ResourceNotFoundException; import org.springframework.security.access.prepost.PreAuthorize; @@ -138,37 +136,25 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository findAll(Context context, Pageable pageable) { - List it = null; - List communities = new ArrayList(); - int total = 0; try { - total = cs.countTotal(context); - it = cs.findAll(context, pageable.getPageSize(), pageable.getOffset()); - for (Community c : it) { - communities.add(c); - } + long total = cs.countTotal(context); + List communities = cs.findAll(context, pageable.getPageSize(), pageable.getOffset()); + return converter.toRestPage(communities, pageable, total, utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Projection projection = utils.obtainProjection(true); - Page page = new PageImpl<>(communities, pageable, total) - .map((object) -> converter.toRest(object, projection)); - return page; } // TODO: Add methods in dspace api to support pagination of top level // communities @SearchRestMethod(name = "top") public Page findAllTop(Pageable pageable) { - List topCommunities = null; try { - topCommunities = cs.findAllTop(obtainContext()); + List communities = cs.findAllTop(obtainContext()); + return converter.toRestPage(utils.getPage(communities, pageable), utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Page page = utils.getPage(topCommunities, pageable) - .map((object) -> converter.toRest(object, utils.obtainProjection())); - return page; } // TODO: add method in dspace api to support direct query for subcommunities @@ -177,20 +163,17 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository findSubCommunities(@Parameter(value = "parent", required = true) UUID parentCommunity, Pageable pageable) { Context context = obtainContext(); - List subCommunities = new ArrayList(); try { Community community = cs.find(context, parentCommunity); if (community == null) { throw new ResourceNotFoundException( CommunityRest.CATEGORY + "." + CommunityRest.NAME + " with id: " + parentCommunity + " not found"); } - subCommunities = community.getSubcommunities(); + List subCommunities = community.getSubcommunities(); + return converter.toRestPage(utils.getPage(subCommunities, pageable), utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Page page = utils.getPage(subCommunities, pageable) - .map((object) -> converter.toRest(object, utils.obtainProjection())); - return page; } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/DSpaceObjectRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/DSpaceObjectRestRepository.java index 5bf5af1193..c7a0082f1d 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/DSpaceObjectRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/DSpaceObjectRestRepository.java @@ -10,7 +10,6 @@ package org.dspace.app.rest.repository; import java.sql.SQLException; import java.util.UUID; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.converter.MetadataConverter; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.DSpaceObjectRest; @@ -38,9 +37,6 @@ public abstract class DSpaceObjectRestRepository dsoService, DSpaceObjectPatch dsoPatch) { this.dsoService = dsoService; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EPersonRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EPersonRestRepository.java index a0cec8ec22..3d4c40649d 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EPersonRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EPersonRestRepository.java @@ -18,7 +18,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang3.StringUtils; import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; -import org.dspace.app.rest.exception.RESTAuthorizationException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.EPersonRest; import org.dspace.app.rest.model.patch.Patch; @@ -31,7 +30,6 @@ import org.dspace.eperson.EPerson; import org.dspace.eperson.service.EPersonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; @@ -112,22 +110,13 @@ public class EPersonRestRepository extends DSpaceObjectRestRepository findAll(Context context, Pageable pageable) { - List epersons = null; - int total = 0; try { - if (!authorizeService.isAdmin(context)) { - throw new RESTAuthorizationException( - "The EPerson collection endpoint is reserved to system administrators"); - } - total = es.countTotal(context); - epersons = es.findAll(context, EPerson.EMAIL, pageable.getPageSize(), pageable.getOffset()); + long total = es.countTotal(context); + List epersons = es.findAll(context, EPerson.EMAIL, pageable.getPageSize(), pageable.getOffset()); + return converter.toRestPage(epersons, pageable, total, utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Projection projection = utils.obtainProjection(true); - Page page = new PageImpl<>(epersons, pageable, total) - .map((object) -> converter.toRest(object, projection)); - return page; } /** @@ -143,18 +132,15 @@ public class EPersonRestRepository extends DSpaceObjectRestRepository findByName(@Parameter(value = "q", required = true) String q, Pageable pageable) { - List epersons = null; - int total = 0; try { Context context = obtainContext(); - epersons = es.search(context, q, pageable.getOffset(), pageable.getOffset() + pageable.getPageSize()); - total = es.searchResultCount(context, q); + long total = es.searchResultCount(context, q); + List epersons = es.search(context, q, pageable.getOffset(), + pageable.getOffset() + pageable.getPageSize()); + return converter.toRestPage(epersons, pageable, total, utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Page page = new PageImpl<>(epersons, pageable, total) - .map((object) -> converter.toRest(object, utils.obtainProjection())); - return page; } /** diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EntityTypeRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EntityTypeRestRepository.java index 8c635a1946..c20388ad0c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EntityTypeRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EntityTypeRestRepository.java @@ -10,9 +10,7 @@ package org.dspace.app.rest.repository; import java.sql.SQLException; import java.util.List; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.EntityTypeRest; -import org.dspace.app.rest.projection.Projection; import org.dspace.content.EntityType; import org.dspace.content.service.EntityTypeService; import org.dspace.core.Context; @@ -31,9 +29,6 @@ public class EntityTypeRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { - List entityTypeList = null; try { - entityTypeList = entityTypeService.findAll(context); + List entityTypes = entityTypeService.findAll(context); + return converter.toRestPage(utils.getPage(entityTypes, pageable), utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Projection projection = utils.obtainProjection(true); - Page page = utils.getPage(entityTypeList, pageable) - .map((object) -> converter.toRest(object, projection)); - return page; } public Class getDomainClass() { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/GroupRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/GroupRestRepository.java index 5d6636abe0..e8f0ec9a54 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/GroupRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/GroupRestRepository.java @@ -27,7 +27,6 @@ import org.dspace.eperson.Group; import org.dspace.eperson.service.GroupService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; @@ -97,18 +96,13 @@ public class GroupRestRepository extends DSpaceObjectRestRepository findAll(Context context, Pageable pageable) { - List groups = null; - int total = 0; try { - total = gs.countTotal(context); - groups = gs.findAll(context, null, pageable.getPageSize(), pageable.getOffset()); + long total = gs.countTotal(context); + List groups = gs.findAll(context, null, pageable.getPageSize(), pageable.getOffset()); + return converter.toRestPage(groups, pageable, total, utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Projection projection = utils.obtainProjection(true); - Page page = new PageImpl(groups, pageable, total) - .map((object) -> converter.toRest(object, projection)); - return page; } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/HarvestedCollectionRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/HarvestedCollectionRestRepository.java index 4ace76bbe9..ad153a5ddc 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/HarvestedCollectionRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/HarvestedCollectionRestRepository.java @@ -17,7 +17,6 @@ import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import com.fasterxml.jackson.databind.ObjectMapper; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.converter.HarvestedCollectionConverter; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.HarvestTypeEnum; @@ -46,9 +45,6 @@ public class HarvestedCollectionRestRepository extends AbstractDSpaceRestReposit @Autowired HarvestedCollectionConverter harvestedCollectionConverter; - @Autowired - ConverterService converter; - public HarvestedCollectionRest findOne(Collection collection) throws SQLException { Context context = obtainContext(); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRelationshipLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRelationshipLinkRepository.java index 08f2c62f8e..4c76dc2274 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRelationshipLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRelationshipLinkRepository.java @@ -13,7 +13,6 @@ import java.util.UUID; import javax.annotation.Nullable; import javax.servlet.http.HttpServletRequest; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.ItemRest; import org.dspace.app.rest.model.RelationshipRest; import org.dspace.app.rest.projection.Projection; @@ -24,7 +23,6 @@ import org.dspace.content.service.RelationshipService; import org.dspace.core.Context; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Component; @@ -42,9 +40,6 @@ public class ItemRelationshipLinkRepository extends AbstractDSpaceRestRepository @Autowired ItemService itemService; - @Autowired - ConverterService converter; - //@PreAuthorize("hasPermission(#itemId, 'ITEM', 'READ')") public Page getItemRelationships(@Nullable HttpServletRequest request, UUID itemId, @@ -61,8 +56,7 @@ public class ItemRelationshipLinkRepository extends AbstractDSpaceRestRepository Integer offset = pageable == null ? null : pageable.getOffset(); int total = relationshipService.countByItem(context, item); List relationships = relationshipService.findByItem(context, item, limit, offset); - return new PageImpl<>(relationships, pageable, total) - .map((object) -> converter.toRest(object, projection)); + return converter.toRestPage(relationships, pageable, total, projection); } catch (SQLException e) { throw new RuntimeException(e); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java index 1d1d2ffcce..dba7f61e2d 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java @@ -40,7 +40,6 @@ import org.dspace.core.Context; import org.dspace.util.UUIDUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.rest.webmvc.ResourceNotFoundException; import org.springframework.security.access.prepost.PreAuthorize; @@ -100,21 +99,17 @@ public class ItemRestRepository extends DSpaceObjectRestRepository findAll(Context context, Pageable pageable) { - Iterator it = null; - List items = new ArrayList(); - int total = 0; try { - total = is.countTotal(context); - it = is.findAll(context, pageable.getPageSize(), pageable.getOffset()); + long total = is.countTotal(context); + Iterator it = is.findAll(context, pageable.getPageSize(), pageable.getOffset()); + List items = new ArrayList<>(); while (it.hasNext()) { - Item i = it.next(); - items.add(i); + items.add(it.next()); } + return converter.toRestPage(items, pageable, total, utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Projection projection = utils.obtainProjection(true); - return new PageImpl<>(items, pageable, total).map((object) -> converter.toRest(object, projection)); } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataFieldRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataFieldRestRepository.java index ebb7562d70..b61737549f 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataFieldRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataFieldRestRepository.java @@ -21,7 +21,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.MetadataFieldRest; @@ -54,12 +53,6 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { - List metadataField = null; try { - metadataField = metadataFieldService.findAll(context); + List metadataFields = metadataFieldService.findAll(context); + return converter.toRestPage(utils.getPage(metadataFields, pageable), utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Projection projection = utils.obtainProjection(true); - Page page = utils.getPage(metadataField, pageable) - .map((object) -> converter.toRest(object, projection)); - return page; } @SearchRestMethod(name = "bySchema") public Page findBySchema(@Parameter(value = "schema", required = true) String schemaName, Pageable pageable) { - Context context = obtainContext(); - List metadataFields = null; try { + Context context = obtainContext(); MetadataSchema schema = metadataSchemaService.find(context, schemaName); if (schema == null) { return null; } - metadataFields = metadataFieldService.findAllInSchema(context, schema); + List metadataFields = metadataFieldService.findAllInSchema(context, schema); + return converter.toRestPage(utils.getPage(metadataFields, pageable), utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Projection projection = utils.obtainProjection(true); - Page page = utils.getPage(metadataFields, pageable) - .map((object) -> converter.toRest(object, projection)); - return page; } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataSchemaRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataSchemaRestRepository.java index b23787d80b..4c00de9b11 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataSchemaRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataSchemaRestRepository.java @@ -18,7 +18,6 @@ import javax.servlet.http.HttpServletRequest; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.MetadataSchemaRest; @@ -46,12 +45,6 @@ public class MetadataSchemaRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { - List metadataSchema = null; try { - metadataSchema = metadataSchemaService.findAll(context); + List metadataSchemas = metadataSchemaService.findAll(context); + return converter.toRestPage(utils.getPage(metadataSchemas, pageable), utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Projection projection = utils.obtainProjection(true); - Page page = utils.getPage(metadataSchema, pageable) - .map((object) -> converter.toRest(object, projection)); - return page; } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/PoolTaskRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/PoolTaskRestRepository.java index f1236ecb3b..dc0c6d910e 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/PoolTaskRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/PoolTaskRestRepository.java @@ -17,11 +17,9 @@ import javax.servlet.http.HttpServletRequest; import org.apache.log4j.Logger; import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.RESTAuthorizationException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.PoolTaskRest; -import org.dspace.app.rest.projection.Projection; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.service.AuthorizeService; import org.dspace.content.service.ItemService; @@ -65,9 +63,6 @@ public class PoolTaskRestRepository extends DSpaceRestRepository findByUser(@Parameter(value = "uuid") UUID userID, Pageable pageable) { - List tasks = null; try { Context context = obtainContext(); //FIXME this should be secured with annotation but they are currently ignored by search methods @@ -106,7 +100,8 @@ public class PoolTaskRestRepository extends DSpaceRestRepository tasks = poolTaskService.findByEperson(context, ep); + return converter.toRestPage(utils.getPage(tasks, pageable), utils.obtainProjection(true)); } else { throw new RESTAuthorizationException("Only administrators can search for pool tasks of other users"); } @@ -115,10 +110,6 @@ public class PoolTaskRestRepository extends DSpaceRestRepository page = utils.getPage(tasks, pageable) - .map((object) -> converter.toRest(object, projection)); - return page; } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipRestRepository.java index a90be9b8f1..8ee25412fa 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipRestRepository.java @@ -9,7 +9,6 @@ package org.dspace.app.rest.repository; import java.io.IOException; import java.sql.SQLException; -import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.UUID; @@ -20,7 +19,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.log4j.Logger; import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.RelationshipRest; @@ -39,7 +37,6 @@ import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.rest.webmvc.ResourceNotFoundException; import org.springframework.security.access.AccessDeniedException; @@ -53,7 +50,6 @@ public class RelationshipRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { - int total = 0; - List relationships = new ArrayList<>(); try { - total = relationshipService.countTotal(context); - relationships = relationshipService.findAll(context, + long total = relationshipService.countTotal(context); + List relationships = relationshipService.findAll(context, pageable.getPageSize(), pageable.getOffset()); + return converter.toRestPage(relationships, pageable, total, utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Projection projection = utils.obtainProjection(true); - Page page = new PageImpl<>(relationships, pageable, total) - .map((object) -> converter.toRest(object, projection)); - return page; } @Override @@ -343,10 +331,6 @@ public class RelationshipRestRepository extends DSpaceRestRepository page = new PageImpl<>(relationships, pageable, total) - .map((object) -> converter.toRest(object, projection)); - return page; - + return converter.toRestPage(relationships, pageable, total, utils.obtainProjection(true)); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipTypeRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipTypeRestRepository.java index 36f72b2fc7..9e88019fba 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipTypeRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipTypeRestRepository.java @@ -10,9 +10,7 @@ package org.dspace.app.rest.repository; import java.sql.SQLException; import java.util.List; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.RelationshipTypeRest; -import org.dspace.app.rest.projection.Projection; import org.dspace.content.RelationshipType; import org.dspace.content.service.RelationshipTypeService; import org.dspace.core.Context; @@ -30,9 +28,6 @@ public class RelationshipTypeRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { - List relationshipTypeList = null; try { - relationshipTypeList = relationshipTypeService.findAll(context); + List relationshipTypes = relationshipTypeService.findAll(context); + return converter.toRestPage(utils.getPage(relationshipTypes, pageable), utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Projection projection = utils.obtainProjection(true); - Page page = utils.getPage(relationshipTypeList, pageable) - .map((object) -> converter.toRest(object, projection)); - return page; } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ResourcePolicyRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ResourcePolicyRestRepository.java index 3ef2148f5a..0d0657dbbb 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ResourcePolicyRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ResourcePolicyRestRepository.java @@ -9,10 +9,8 @@ package org.dspace.app.rest.repository; import java.sql.SQLException; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException; import org.dspace.app.rest.model.ResourcePolicyRest; -import org.dspace.app.rest.utils.Utils; import org.dspace.authorize.ResourcePolicy; import org.dspace.authorize.service.ResourcePolicyService; import org.dspace.core.Context; @@ -33,12 +31,6 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { - List sites = new ArrayList(); - int total = 1; try { - sites.add(sitesv.findSite(context)); + List sites = Arrays.asList(sitesv.findSite(context)); + return converter.toRestPage(sites, pageable, 1L, utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Projection projection = utils.obtainProjection(true); - Page page = new PageImpl(sites, pageable, total) - .map((object) -> converter.toRest(object, projection)); - return page; } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/StatisticsRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/StatisticsRestRepository.java index 8f7d2b8a44..0838b65d18 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/StatisticsRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/StatisticsRestRepository.java @@ -13,7 +13,6 @@ import org.springframework.stereotype.Component; @Component(StatisticsSupportRest.CATEGORY + "." + StatisticsSupportRest.NAME) public class StatisticsRestRepository extends AbstractDSpaceRestRepository { - public StatisticsSupportRest getStatisticsSupport() { return new StatisticsSupportRest(); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionDefinitionRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionDefinitionRestRepository.java index 213991e144..c4ea1bc866 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionDefinitionRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionDefinitionRestRepository.java @@ -13,9 +13,7 @@ import java.util.UUID; import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.SubmissionDefinitionRest; -import org.dspace.app.rest.projection.Projection; import org.dspace.app.util.SubmissionConfig; import org.dspace.app.util.SubmissionConfigReader; import org.dspace.app.util.SubmissionConfigReaderException; @@ -23,9 +21,7 @@ import org.dspace.content.Collection; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.CollectionService; import org.dspace.core.Context; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; @@ -41,9 +37,6 @@ public class SubmissionDefinitionRestRepository extends DSpaceRestRepository subConfs = submissionConfigReader.getAllSubmissionConfigs( pageable.getPageSize(), pageable.getOffset()); - Projection projection = utils.obtainProjection(true); - Page page = new PageImpl<>(subConfs, pageable, total) - .map((object) -> converter.toRest(object, projection)); - return page; + return converter.toRestPage(subConfs, pageable, total, utils.obtainProjection(true)); } @PreAuthorize("hasAuthority('AUTHENTICATED')") diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionFormRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionFormRestRepository.java index efd09c031e..51b0075e17 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionFormRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionFormRestRepository.java @@ -7,19 +7,14 @@ */ package org.dspace.app.rest.repository; -import java.util.ArrayList; import java.util.List; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.SubmissionFormRest; -import org.dspace.app.rest.projection.Projection; import org.dspace.app.util.DCInputSet; import org.dspace.app.util.DCInputsReader; import org.dspace.app.util.DCInputsReaderException; import org.dspace.core.Context; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; @@ -35,9 +30,6 @@ public class SubmissionFormRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { - List subConfs = new ArrayList(); - int total = inputReader.countInputs(); try { - subConfs = inputReader.getAllInputs(pageable.getPageSize(), pageable.getOffset()); + long total = inputReader.countInputs(); + List subConfs = inputReader.getAllInputs(pageable.getPageSize(), pageable.getOffset()); + return converter.toRestPage(subConfs, pageable, total, utils.obtainProjection(true)); } catch (DCInputsReaderException e) { throw new IllegalStateException(e.getMessage(), e); } - Projection projection = utils.obtainProjection(true); - Page page = new PageImpl<>(subConfs, pageable, total) - .map((object) -> converter.toRest(object, projection)); - return page; } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionPanelRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionPanelRestRepository.java index 456cd0e4f6..b9acb2ea32 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionPanelRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionPanelRestRepository.java @@ -10,18 +10,14 @@ package org.dspace.app.rest.repository; import java.util.ArrayList; import java.util.List; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.SubmissionDefinitionRest; import org.dspace.app.rest.model.SubmissionSectionRest; -import org.dspace.app.rest.projection.Projection; 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.core.Context; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; @@ -36,9 +32,6 @@ public class SubmissionPanelRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { - List subConfs = new ArrayList(); - subConfs = submissionConfigReader.getAllSubmissionConfigs(pageable.getPageSize(), pageable.getOffset()); - int total = 0; + List subConfs = submissionConfigReader.getAllSubmissionConfigs( + pageable.getPageSize(), pageable.getOffset()); + long total = 0; List stepConfs = new ArrayList<>(); for (SubmissionConfig config : subConfs) { total = +config.getNumberOfSteps(); @@ -69,10 +62,7 @@ public class SubmissionPanelRestRepository extends DSpaceRestRepository page = new PageImpl<>(stepConfs, pageable, total) - .map((object) -> converter.toRest(object, projection)); - return page; + return converter.toRestPage(stepConfs, pageable, total, utils.obtainProjection(true)); } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java index 5c4a9012a5..db3672aa4a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java @@ -12,7 +12,6 @@ import java.util.List; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Logger; -import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.AccessConditionOptionRest; import org.dspace.app.rest.model.SubmissionUploadRest; import org.dspace.app.rest.projection.Projection; @@ -58,9 +57,6 @@ public class SubmissionUploadRestRepository extends DSpaceRestRepository wfs; - private SubmissionConfigReader submissionConfigReader; + private final SubmissionConfigReader submissionConfigReader; public WorkflowItemRestRepository() throws SubmissionConfigReaderException { submissionConfigReader = new SubmissionConfigReader(); @@ -113,37 +113,28 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { - List witems = null; - int total = 0; try { - total = wis.countAll(context); - witems = wis.findAll(context, pageable.getPageNumber(), pageable.getPageSize()); + long total = wis.countAll(context); + List witems = wis.findAll(context, pageable.getPageNumber(), pageable.getPageSize()); + return converter.toRestPage(witems, pageable, total, utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Projection projection = utils.obtainProjection(true); - Page page = new PageImpl<>(witems, pageable, total) - .map((object) -> converter.toRest(object, projection)); - return page; } @SearchRestMethod(name = "findBySubmitter") @PreAuthorize("hasAuthority('ADMIN')") public Page findBySubmitter(@Parameter(value = "uuid") UUID submitterID, Pageable pageable) { - List witems = null; - int total = 0; try { Context context = obtainContext(); EPerson ep = epersonService.find(context, submitterID); - witems = wis.findBySubmitter(context, ep, pageable.getPageNumber(), pageable.getPageSize()); - total = wis.countBySubmitter(context, ep); + long total = wis.countBySubmitter(context, ep); + List witems = wis.findBySubmitter(context, ep, pageable.getPageNumber(), + pageable.getPageSize()); + return converter.toRestPage(witems, pageable, total, utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Projection projection = utils.obtainProjection(true); - Page page = new PageImpl<>(witems, pageable, total) - .map((object) -> converter.toRest(object, projection)); - return page; } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkspaceItemRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkspaceItemRestRepository.java index aad0badc03..9aa8df3492 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkspaceItemRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkspaceItemRestRepository.java @@ -24,7 +24,6 @@ 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.ConverterService; import org.dspace.app.rest.converter.WorkspaceItemConverter; import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.model.ErrorRest; @@ -63,7 +62,6 @@ 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; import org.springframework.data.domain.Pageable; import org.springframework.data.rest.webmvc.json.patch.PatchException; import org.springframework.stereotype.Component; @@ -83,22 +81,25 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { - List witems = null; - int total = 0; try { - total = wis.countTotal(context); - witems = wis.findAll(context, pageable.getPageSize(), pageable.getOffset()); + long total = wis.countTotal(context); + List witems = wis.findAll(context, pageable.getPageSize(), pageable.getOffset()); + return converter.toRestPage(witems, pageable, total, utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Projection projection = utils.obtainProjection(true); - Page page = new PageImpl<>(witems, pageable, total) - .map((object) -> converter.toRest(object, projection)); - return page; } //TODO @PreAuthorize("hasPermission(#submitterID, 'EPERSON', 'READ')") @SearchRestMethod(name = "findBySubmitter") public Page findBySubmitter(@Parameter(value = "uuid", required = true) UUID submitterID, Pageable pageable) { - List witems = null; - int total = 0; try { Context context = obtainContext(); EPerson ep = epersonService.find(context, submitterID); - witems = wis.findByEPerson(context, ep, pageable.getPageSize(), pageable.getOffset()); - total = wis.countByEPerson(context, ep); + long total = wis.countByEPerson(context, ep); + List witems = wis.findByEPerson(context, ep, pageable.getPageSize(), pageable.getOffset()); + return converter.toRestPage(witems, pageable, total, utils.obtainProjection(true)); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } - Projection projection = utils.obtainProjection(true); - Page page = new PageImpl<>(witems, pageable, total) - .map((object) -> converter.toRest(object, projection)); - return page; } @Override @@ -203,7 +194,6 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository!"); } - } catch (Exception e) { log.error(e.getMessage(), e); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java index 60b7b1fa5e..590eef2329 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java @@ -436,6 +436,8 @@ public class Utils { return obtainProjection(false); } + + /** * Adds embeds or links for all class-level LinkRel annotations for which embeds or links are allowed. * From c556c379f515c5e1ca32e7ebdd389f1bdfff095d Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Sat, 9 Nov 2019 09:56:50 -0500 Subject: [PATCH 09/20] DS-3533 Fix incorrect embedded page details when provided by link repo --- .../src/main/java/org/dspace/app/rest/utils/Utils.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java index 590eef2329..394ee7e2d7 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java @@ -560,9 +560,13 @@ public class Utils { private Object wrapForEmbedding(Object linkedObject, Link link) { if (linkedObject instanceof RestAddressableModel) { return converter.toResource((RestAddressableModel) linkedObject); - } else if (linkedObject instanceof Page || linkedObject instanceof List) { - List list = linkedObject instanceof Page ? ((Page) linkedObject).getContent() - : (List) linkedObject; + } else if (linkedObject instanceof Page) { + // The first page has already been constructed by a link repository and we only need to wrap it + Page page = (Page) linkedObject; + return new EmbeddedPage(link.getHref(), page.map(converter::toResource), null, link.getRel()); + } else if (linkedObject instanceof List) { + // The full list has been retrieved and we need to provide the first page for embedding + List list = (List) linkedObject; if (list.size() > 0) { PageImpl page = new PageImpl( list.subList(0, list.size() > EMBEDDED_PAGE_SIZE ? EMBEDDED_PAGE_SIZE : list.size()), From 66108a75329a67b6984a7c74d1bbca61ac6453d3 Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Sat, 9 Nov 2019 10:39:50 -0500 Subject: [PATCH 10/20] DS-3533 Fix failure to link when embedding from link repo --- .../src/main/java/org/dspace/app/rest/utils/Utils.java | 1 + 1 file changed, 1 insertion(+) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java index 394ee7e2d7..dab39a11d0 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java @@ -449,6 +449,7 @@ public class Utils { Link link = linkToSubResource(halResource.getContent(), linkRest.name()); if (!linkRest.embedOptional() || projection.allowOptionalEmbed(halResource, linkRest)) { embedRelFromRepository(halResource, linkRest.name(), link, linkRest.method()); + halResource.add(link); // unconditionally link if embedding was allowed } else if (!linkRest.linkOptional() || projection.allowOptionalLink(halResource, linkRest)) { halResource.add(link); } From d0661d144ebb8e7fafb00b554ea75a9210478ab2 Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Sat, 9 Nov 2019 23:17:27 -0500 Subject: [PATCH 11/20] DS-3533 Cache method link annotation info to improve performance --- .../link/DSpaceResourceHalLinkFactory.java | 3 +-- .../java/org/dspace/app/rest/utils/Utils.java | 24 ++++++++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/link/DSpaceResourceHalLinkFactory.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/link/DSpaceResourceHalLinkFactory.java index 4dba5aa318..79e247343c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/link/DSpaceResourceHalLinkFactory.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/link/DSpaceResourceHalLinkFactory.java @@ -21,7 +21,6 @@ import org.dspace.app.rest.model.RestModel; import org.dspace.app.rest.model.hateoas.DSpaceResource; import org.dspace.app.rest.utils.Utils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.annotation.AnnotationUtils; import org.springframework.data.domain.Pageable; import org.springframework.hateoas.Link; import org.springframework.stereotype.Component; @@ -46,7 +45,7 @@ public class DSpaceResourceHalLinkFactory extends HalLinkFactory> linkAnnotationForMethod = new HashMap<>(); + public Page getPage(List fullContents, Pageable pageable) { int total = fullContents.size(); List pageContent = null; @@ -509,6 +515,22 @@ public class Utils { } } + /** + * Gets the LinkRest annotation for the given method, if any. + * + * @param readMethod the method. + * @return the annotation, or {@code null} if not found. + */ + public @Nullable LinkRest findLinkAnnotation(Method readMethod) { + Optional optional = linkAnnotationForMethod.get(readMethod); + if (optional == null) { + LinkRest linkRest = AnnotationUtils.findAnnotation(readMethod, LinkRest.class); + optional = linkRest != null ? Optional.of(linkRest) : Optional.empty(); + linkAnnotationForMethod.put(readMethod, optional); + } + return optional.isPresent() ? optional.get() : null; + } + /** * Adds an embed for the given property read method. If the @LinkRel annotation is present and * specifies a method name, the value will come from invoking that method in the appropriate link @@ -523,7 +545,7 @@ public class Utils { Method readMethod, String propertyName) { String rel = propertyName; - LinkRest linkRest = AnnotationUtils.findAnnotation(readMethod, LinkRest.class); + LinkRest linkRest = findLinkAnnotation(readMethod); try { if (linkRest != null) { if (linkRest.embedOptional() From 5e4ddcdeb94f23bb8adbbe7a3eae5360f844fc37 Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Sun, 10 Nov 2019 08:45:33 -0500 Subject: [PATCH 12/20] DS-3533 Fix typo --- .../java/org/dspace/app/rest/converter/DSpaceConverter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceConverter.java index 2f53980673..208904eee4 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceConverter.java @@ -11,7 +11,7 @@ import org.dspace.app.rest.projection.Projection; public interface DSpaceConverter { - R convert(M restObject, Projection projection); + R convert(M modelObject, Projection projection); Class getModelClass(); } From 1ca24c1eba1a6b59e0d0799a3da375b7971d0263 Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Sun, 10 Nov 2019 23:49:57 -0500 Subject: [PATCH 13/20] DS-3533 Begin projection/converter tests --- .../app/rest/converter/ConverterService.java | 44 +++-- .../rest/converter/ConverterServiceIT.java | 168 ++++++++++++++++++ .../rest/converter/MockObjectConverter.java | 34 ++++ .../org/dspace/app/rest/model/MockObject.java | 36 ++++ .../dspace/app/rest/model/MockObjectRest.java | 88 +++++++++ .../model/hateoas/MockObjectResource.java | 18 ++ .../app/rest/projection/MockProjection.java | 101 +++++++++++ 7 files changed, 475 insertions(+), 14 deletions(-) create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/converter/ConverterServiceIT.java create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/converter/MockObjectConverter.java create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/model/MockObject.java create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/model/MockObjectRest.java create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/model/hateoas/MockObjectResource.java create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/projection/MockProjection.java diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java index fb85a68f71..9e4f6c00f1 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ConverterService.java @@ -72,14 +72,13 @@ public class ConverterService { * {@link Projection#transformRest(RestModel)} method will be automatically called after conversion. *

* - * @param modelObject the model object, which may be a JPA entity or other class provided by the DSpace - * service layer. + * @param modelObject the model object, which may be a JPA entity any other class for which a converter exists. * @param projection the projection to use. * @param the type of model object. A converter {@link Component} must exist that takes this as input. * @param the inferred return type. * @return the converted object. If it's a {@link RestAddressableModel}, its - * {@link RestAddressableModel#getProjection()} will be set to the named projection. - * @throws IllegalArgumentException if there is no compatible converter or no such projection. + * {@link RestAddressableModel#getProjection()} will be set to the given projection. + * @throws IllegalArgumentException if there is no compatible converter. * @throws ClassCastException if the converter's return type is not compatible with the inferred return type. */ public R toRest(M modelObject, Projection projection) { @@ -95,19 +94,32 @@ public class ConverterService { /** * Converts a list of model objects to a page of rest objects using the given {@link Projection}. * - * @param modelObjects - * @param pageable - * @param total - * @param projection - * @param - * @param - * @return + * @param modelObjects the list of model objects. + * @param pageable the pageable. + * @param total the total number of items. + * @param projection the projection to use. + * @param the model object class. + * @param the rest object class. + * @return the page. + * @throws IllegalArgumentException if there is no compatible converter. + * @throws ClassCastException if the converter's return type is not compatible with the inferred return type. */ - public Page toRestPage(List modelObjects, Pageable pageable, long total, Projection projection) { + public Page toRestPage(List modelObjects, Pageable pageable, long total, Projection projection) { return new PageImpl<>(modelObjects, pageable, total).map((object) -> toRest(object, projection)); } - public Page toRestPage(Page modelObjects, Projection projection) { + /** + * Converts a list of model objects to a page of rest objects using the given {@link Projection}. + * + * @param modelObjects the page of model objects. + * @param projection the projection to use. + * @param the model object class. + * @param the rest object class. + * @return the page. + * @throws IllegalArgumentException if there is no compatible converter. + * @throws ClassCastException if the converter's return type is not compatible with the inferred return type. + */ + public Page toRestPage(Page modelObjects, Projection projection) { return modelObjects.map((object) -> toRest(object, projection)); } @@ -139,7 +151,8 @@ public class ConverterService { * @param restObject the input rest object. * @param the return type, a subclass of {@link HALResource}. * @return the fully converted resource, with all automatic links and embeds applied. - * @throws IllegalArgumentException if there is no such projection. + * @throws IllegalArgumentException if there is no compatible resource constructor. + * @throws ClassCastException if the resource type is not compatible with the inferred return type. */ public T toResource(RestModel restObject) { T halResource = getResource(restObject); @@ -180,6 +193,9 @@ public class ConverterService { */ private T getResource(RestModel restObject) { Constructor constructor = resourceConstructors.get(restObject.getClass()); + if (constructor == null) { + throw new IllegalArgumentException("No constructor found to get resource class from " + restObject); + } try { if (constructor.getParameterCount() == 2) { return (T) constructor.newInstance(restObject, utils); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/converter/ConverterServiceIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/converter/ConverterServiceIT.java new file mode 100644 index 0000000000..9b39adfb46 --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/converter/ConverterServiceIT.java @@ -0,0 +1,168 @@ +/** + * 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.converter; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.startsWith; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.dspace.app.rest.model.MockObject; +import org.dspace.app.rest.model.MockObjectRest; +import org.dspace.app.rest.model.RestAddressableModel; +import org.dspace.app.rest.model.RestModel; +import org.dspace.app.rest.model.hateoas.HALResource; +import org.dspace.app.rest.model.hateoas.MockObjectResource; +import org.dspace.app.rest.projection.MockProjection; +import org.dspace.app.rest.projection.Projection; +import org.dspace.app.rest.test.AbstractControllerIntegrationTest; +import org.junit.Test; +import org.mockito.Mock; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.hateoas.Link; +import org.springframework.hateoas.Resource; + +/** + * Tests functionality of {@link ConverterService}. + */ +public class ConverterServiceIT extends AbstractControllerIntegrationTest { + + @Autowired + private ConverterService converter; + + @Mock + private Object mockObjectWithNoConverter; + + @Mock + private RestModel mockObjectRestWithNoResource; + + @Mock + private Link mockLink; + + @Mock + private Object mockEmbeddedResource; + + private static final Long ORIG_ID = 0L; + + private static final String ORIG_VALUE = "value0"; + + private final MockObject mockObject = mockObject(ORIG_ID); + + @Test + public void toRestNoConverterFound() { + try { + converter.toRest(mockObjectWithNoConverter, Projection.DEFAULT); + fail(); + } catch (IllegalArgumentException e) { + assertThat(e.getMessage(), startsWith("No converter found")); + } + } + + @Test(expected = ClassCastException.class) + public void toRestWrongReturnType() { + @SuppressWarnings("unused") + String restObject = converter.toRest(mockObject(0), Projection.DEFAULT); + } + + @Test + public void toRestWithDefaultProjection() { + MockObjectRest restObject = converter.toRest(mockObject(0), Projection.DEFAULT); + assertEquals(ORIG_ID, restObject.getId()); + assertEquals(ORIG_VALUE, restObject.getValue()); + } + + @Test + public void toRestWithMockProjection() { + MockProjection mockProjection = new MockProjection(mockLink, mockEmbeddedResource); + MockObjectRest restObject = converter.toRest(mockObject, mockProjection); + assertThat(restObject.getId(), equalTo((ORIG_ID + 1) * 3)); + assertThat(restObject.getValue(), equalTo(ORIG_VALUE + "?!")); + } + + @Test + public void toResourceNoConstructorFound() { + try { + converter.toResource(mockObjectRestWithNoResource); + fail(); + } catch (IllegalArgumentException e) { + assertThat(e.getMessage(), startsWith("No constructor found")); + } + } + + @Test(expected = ClassCastException.class) + public void toResourceWrongReturnType() { + @SuppressWarnings("unused") + MockHalResource mockHalResource = converter.toResource(mockObjectRest(0)); + } + + @Test + public void toResourceWithDefaultProjection() { + MockObjectRest r0 = mockObjectRest(0); + MockObjectRest r1 = mockObjectRest(1); + r0.setRestProp1(r1); + MockObjectResource resource = converter.toResource(r0); + assertEquals(ORIG_ID, resource.getContent().getId()); + assertEquals(ORIG_VALUE, resource.getContent().getValue()); + assertEquals(5, resource.getLinks().size()); + assertEquals("restProp1", resource.getLinks().get(0).getRel()); + assertEquals("restProp2", resource.getLinks().get(1).getRel()); + assertEquals("restProp3", resource.getLinks().get(2).getRel()); + assertEquals("restPropFour", resource.getLinks().get(3).getRel()); + assertEquals("self", resource.getLinks().get(4).getRel()); + assertEquals(4, resource.getEmbeddedResources().size()); + assertTrue(resource.getEmbeddedResources().containsKey("restProp1")); + assertTrue(resource.getEmbeddedResources().containsKey("restProp2")); + assertTrue(resource.getEmbeddedResources().containsKey("restProp3")); + assertTrue(resource.getEmbeddedResources().containsKey("restPropFour")); + assertEquals(r1, ((Resource) resource.getEmbeddedResources().get("restProp1")).getContent()); + assertNull(resource.getEmbeddedResources().get("restProp2")); + assertNull(resource.getEmbeddedResources().get("restProp3")); + assertNull(resource.getEmbeddedResources().get("restPropFour")); + } + + private static MockObject mockObject(long id) { + MockObject mockObject = new MockObject(); + mockObject.setStoredId(id); + mockObject.setStoredValue("value" + id); + return mockObject; + } + + private static MockObjectRest mockObjectRest(long id) { + MockObjectRest mockObjectRest = new MockObjectRest(); + mockObjectRest.setProjection(Projection.DEFAULT); + mockObjectRest.setId(id); + mockObjectRest.setValue("value" + id); + return mockObjectRest; + } + + class MockRestAddressableModel extends RestAddressableModel { + @Override + public String getCategory() { + return null; + } + + @Override + public Class getController() { + return null; + } + + @Override + public String getType() { + return null; + } + } + + class MockHalResource extends HALResource { + public MockHalResource(MockRestAddressableModel content) { + super(content); + } + } +} diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/converter/MockObjectConverter.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/converter/MockObjectConverter.java new file mode 100644 index 0000000000..d8e12602ae --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/converter/MockObjectConverter.java @@ -0,0 +1,34 @@ +/** + * 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.converter; + +import org.dspace.app.rest.model.MockObject; +import org.dspace.app.rest.model.MockObjectRest; +import org.dspace.app.rest.projection.Projection; +import org.springframework.stereotype.Component; + +/** + * A simple {@link DSpaceConverter} for use with tests. + */ +@Component +public class MockObjectConverter implements DSpaceConverter { + + @Override + public MockObjectRest convert(MockObject modelObject, Projection projection) { + MockObjectRest restObject = new MockObjectRest(); + restObject.setProjection(projection); + restObject.setId(modelObject.getStoredId()); + restObject.setValue(modelObject.getStoredValue()); + return restObject; + } + + @Override + public Class getModelClass() { + return MockObject.class; + } +} diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/model/MockObject.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/model/MockObject.java new file mode 100644 index 0000000000..5e774987a9 --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/model/MockObject.java @@ -0,0 +1,36 @@ +/** + * 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.model; + +/** + * A simple model object for use with tests. + * + * Simulates a typical JPA object obtained through the DSpace service layer. + */ +public class MockObject { + + private Long storedId; + + private String storedValue; + + public Long getStoredId() { + return storedId; + } + + public void setStoredId(Long storedId) { + this.storedId = storedId; + } + + public String getStoredValue() { + return storedValue; + } + + public void setStoredValue(String storedValue) { + this.storedValue = storedValue; + } +} diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/model/MockObjectRest.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/model/MockObjectRest.java new file mode 100644 index 0000000000..ea1a4c6311 --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/model/MockObjectRest.java @@ -0,0 +1,88 @@ +/** + * 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.model; + +import org.dspace.app.rest.RestResourceController; + +/** + * A simple rest object for use with tests. + */ +public class MockObjectRest extends BaseObjectRest { + + public static final String CATEGORY = "test"; + + public static final String NAME = "testobject"; + + private String value; + + private MockObjectRest restProp1; + + private MockObjectRest restProp2; + + private MockObjectRest restProp3; + + private MockObjectRest restProp4; + + @Override + public String getCategory() { + return CATEGORY; + } + + @Override + public Class getController() { + return RestResourceController.class; + } + + @Override + public String getType() { + return NAME; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public MockObjectRest getRestProp1() { + return restProp1; + } + + public void setRestProp1(MockObjectRest restProp1) { + this.restProp1 = restProp1; + } + + @LinkRest(linkClass = MockObjectRest.class) + public MockObjectRest getRestProp2() { + return restProp2; + } + + public void setRestProp2(MockObjectRest restProp2) { + this.restProp2 = restProp2; + } + + @LinkRest(linkClass = MockObjectRest.class) + public MockObjectRest getRestProp3() { + return restProp3; + } + + public void setRestProp3(MockObjectRest restProp3) { + this.restProp3 = restProp3; + } + + @LinkRest(linkClass = MockObjectRest.class, name = "restPropFour") + public MockObjectRest getRestProp4() { + return restProp4; + } + + public void setRestProp4(MockObjectRest restProp4) { + this.restProp4 = restProp4; + } +} diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/model/hateoas/MockObjectResource.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/model/hateoas/MockObjectResource.java new file mode 100644 index 0000000000..00733b65bf --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/model/hateoas/MockObjectResource.java @@ -0,0 +1,18 @@ +/** + * 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.model.hateoas; + +import org.dspace.app.rest.model.MockObjectRest; +import org.dspace.app.rest.utils.Utils; + +public class MockObjectResource extends DSpaceResource { + + public MockObjectResource(MockObjectRest data, Utils utils) { + super(data, utils); + } +} diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/projection/MockProjection.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/projection/MockProjection.java new file mode 100644 index 0000000000..b11350efa4 --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/projection/MockProjection.java @@ -0,0 +1,101 @@ +/** + * 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.projection; + +import javax.annotation.Nullable; + +import org.dspace.app.rest.model.LinkRest; +import org.dspace.app.rest.model.MockObject; +import org.dspace.app.rest.model.MockObjectRest; +import org.dspace.app.rest.model.RestModel; +import org.dspace.app.rest.model.hateoas.HALResource; +import org.springframework.hateoas.Link; + +/** + * A projection for use in tests. + */ +public class MockProjection implements Projection { + + public static final String NAME = "mock"; + + private final Link linkToAdd; + + private final Object resourceToEmbed; + + public MockProjection(@Nullable Link linkToAdd, @Nullable Object resourceToEmbed) { + this.linkToAdd = linkToAdd; + this.resourceToEmbed = resourceToEmbed; + } + + public String getName() { + return NAME; + } + + /** + * When given a {@link MockObject}, adds one to the id and appends "?" to the value, if not null. + * Otherwise, returns the original object. + */ + @Override + public T transformModel(T modelObject) { + if (modelObject instanceof MockObject) { + MockObject mockObject = (MockObject) modelObject; + if (mockObject.getStoredId() != null) { + mockObject.setStoredId(mockObject.getStoredId() + 1); + } + if (mockObject.getStoredValue() != null) { + mockObject.setStoredValue(mockObject.getStoredValue() + "?"); + } + } + return modelObject; + } + + /** + * When given a {@link MockObjectRest}, multiplies the id by 3 and appends "!" to the value, if not null. + * Otherwise, returns the original object. + */ + @Override + public T transformRest(T restObject) { + if (restObject instanceof MockObjectRest) { + MockObjectRest mockObjectRest = (MockObjectRest) restObject; + if (mockObjectRest.getId() != null) { + mockObjectRest.setId(mockObjectRest.getId() * 3); + } + if (mockObjectRest.getValue() != null) { + mockObjectRest.setValue(mockObjectRest.getValue() + "!"); + } + } + return restObject; + } + + /** + * Adds link: {@code linkToAdd} if given as non-null in the constructor and adds "resource" embed: + * {@code resourceToEmbed} if given as non-null in the constructor. + */ + @Override + public T transformResource(T halResource) { + if (linkToAdd != null) { + halResource.add(linkToAdd); + } + if (resourceToEmbed != null) { + halResource.embedResource("resource", resourceToEmbed); + } + return halResource; + } + + /** Disallows all optional embeds. */ + @Override + public boolean allowOptionalEmbed(HALResource halResource, LinkRest linkRest) { + return false; + } + + /** Disallows all optional links. */ + @Override + public boolean allowOptionalLink(HALResource halResource, LinkRest linkRest) { + return false; + } +} From 18ea0a2434e82b44276a94513884ccea855d08c5 Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Thu, 14 Nov 2019 08:39:26 -0500 Subject: [PATCH 14/20] DS-3533 Add projection-related tests, resolve minor functional issues, and improve javadocs --- .../link/DSpaceResourceHalLinkFactory.java | 18 +- .../org/dspace/app/rest/model/LinkRest.java | 67 +++++- .../java/org/dspace/app/rest/utils/Utils.java | 42 +++- .../rest/converter/ConverterServiceIT.java | 226 ++++++++++++++---- .../org/dspace/app/rest/model/MockObject.java | 7 + .../dspace/app/rest/model/MockObjectRest.java | 63 ++++- ...AbstractMockObjectChildLinkRepository.java | 40 ++++ ...kObjectAlwaysEmbedChildLinkRepository.java | 18 ++ ...ckObjectNeverEmbedChildLinkRepository.java | 22 ++ ...ectOptionallyEmbedChildLinkRepository.java | 18 ++ 10 files changed, 452 insertions(+), 69 deletions(-) create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/repository/AbstractMockObjectChildLinkRepository.java create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/repository/MockObjectAlwaysEmbedChildLinkRepository.java create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/repository/MockObjectNeverEmbedChildLinkRepository.java create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/repository/MockObjectOptionallyEmbedChildLinkRepository.java diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/link/DSpaceResourceHalLinkFactory.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/link/DSpaceResourceHalLinkFactory.java index 79e247343c..4aa7b508de 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/link/DSpaceResourceHalLinkFactory.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/link/DSpaceResourceHalLinkFactory.java @@ -45,30 +45,30 @@ public class DSpaceResourceHalLinkFactory extends HalLinkFactory + * This is optional if the annotation is used at the method level. If unspecified at the method level, + * the bean name (inferred by the the name of the method) will be used as the name. + *

+ *

+ * This is required if the annotation is used at the class level. + *

+ * + * @return the name, or the empty string if unspecified by the annotation. + */ String name() default ""; + /** + * The name of the method to invoke in the associated link repository. + *

+ * When this is specified, whether at the class or method level, the value of the resource must be provided + * by a {@link LinkRestRepository}, which is found by its {@link Component} name. See + * {@link Utils#getResourceRepository(String, String)}} for details. + *

+ * + * @return the method name, or the empty string if unspecified by the annotation. + */ String method() default ""; + /** + * The class of object returned by invoking the link method. If a list or page is returned, this should + * specify the inner type. + * + * @return the class. + */ Class linkClass(); + /** + * Tells whether embedding the resource indicated by this link is optional. + *

+ * If false (the default), it means the resource will always be embedded unless the {@link LinkRestRepository} + * forbids it via {@link LinkRestRepository#isEmbeddableRelation(Object, String)}. + *

+ *

+ * If true, it means the resource will be embedded normally, unless forbidden by the {@link LinkRestRepository} + * or the projection, in use, via {@link Projection#allowOptionalEmbed(HALResource, LinkRest)}. + *

+ * + * @return whether embedding is optional. + */ boolean embedOptional() default false; + /** + * Tells whether linking the resource indicated by this link is optional. + *

+ * If false (the default), it means the resource will always be linked. + *

+ *

+ * If true, it means the resource will only be linked if: + *

    + *
  • The resource is embedded, or
  • + *
  • The value returned by the link method is not null and linking is not forbidden by the + * projection in use, via {@link Projection#allowOptionalLink(HALResource, LinkRest)}
  • + *
+ *

+ * + * @return whether linking is optional. + */ boolean linkOptional() default false; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java index a7ca5992e6..922a79225a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/Utils.java @@ -454,7 +454,7 @@ public class Utils { getLinkRests(halResource.getContent().getClass()).stream().forEach((linkRest) -> { Link link = linkToSubResource(halResource.getContent(), linkRest.name()); if (!linkRest.embedOptional() || projection.allowOptionalEmbed(halResource, linkRest)) { - embedRelFromRepository(halResource, linkRest.name(), link, linkRest.method()); + embedRelFromRepository(halResource, linkRest.name(), link, linkRest); halResource.add(link); // unconditionally link if embedding was allowed } else if (!linkRest.linkOptional() || projection.allowOptionalLink(halResource, linkRest)) { halResource.add(link); @@ -472,25 +472,44 @@ public class Utils { } /** - * Embeds a rel whose value comes from a {@LinkRestRepository}. + * Embeds a rel whose value comes from a {@link LinkRestRepository}. + *

+ * The embed will be skipped if 1) the link repository reports that it is not embeddable or 2) the returned + * value is null and the LinkRest annotation has embedOptional = true. + *

+ * Implementation note: The caller is responsible for ensuring that the projection allows the embed + * before calling this method. + *

* * @param resource the resource. * @param rel the name of the rel. * @param link the link. - * @param methodName the method name in the link repository. + * @param linkRest the LinkRest annotation (must have method defined). + * @throws RepositoryNotFoundException if the link repository could not be found. + * @throws IllegalArgumentException if the method specified by the LinkRest could not be found in the + * link repository. + * @throws RuntimeException if any other problem occurs when trying to invoke the method. */ private void embedRelFromRepository(HALResource resource, - String rel, Link link, String methodName) { + String rel, Link link, LinkRest linkRest) { + Projection projection = resource.getContent().getProjection(); LinkRestRepository linkRepository = getLinkResourceRepository(resource.getContent().getCategory(), resource.getContent().getType(), rel); - Projection projection = resource.getContent().getProjection(); if (linkRepository.isEmbeddableRelation(resource.getContent(), rel)) { - Method method = requireMethod(linkRepository.getClass(), methodName); + Method method = requireMethod(linkRepository.getClass(), linkRest.method()); Object contentId = getContentIdForLinkMethod(resource.getContent(), method); try { Object linkedObject = method.invoke(linkRepository, null, contentId, null, projection); - resource.embedResource(rel, wrapForEmbedding(linkedObject, link)); - } catch (IllegalAccessException | InvocationTargetException e) { + if (linkedObject != null || !linkRest.embedOptional()) { + resource.embedResource(rel, wrapForEmbedding(linkedObject, link)); + } + } catch (InvocationTargetException e) { + if (e.getTargetException() instanceof RuntimeException) { + throw (RuntimeException) e.getTargetException(); + } else { + throw new RuntimeException(e); + } + } catch (IllegalAccessException e) { throw new RuntimeException(e); } } @@ -557,9 +576,12 @@ public class Utils { } Link link = linkToSubResource(resource.getContent(), rel); if (StringUtils.isBlank(linkRest.method())) { - resource.embedResource(rel, wrapForEmbedding(readMethod.invoke(resource.getContent()), link)); + Object linkedObject = readMethod.invoke(resource.getContent()); + if (linkedObject != null || !linkRest.embedOptional()) { + resource.embedResource(rel, wrapForEmbedding(linkedObject, link)); + } } else { - embedRelFromRepository(resource, rel, link, linkRest.method()); + embedRelFromRepository(resource, rel, link, linkRest); } } else if (RestAddressableModel.class.isAssignableFrom(readMethod.getReturnType())) { RestAddressableModel linkedObject = (RestAddressableModel) readMethod.invoke(resource.getContent()); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/converter/ConverterServiceIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/converter/ConverterServiceIT.java index 9b39adfb46..50069f0366 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/converter/ConverterServiceIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/converter/ConverterServiceIT.java @@ -10,15 +10,22 @@ package org.dspace.app.rest.converter; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.startsWith; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.mockito.Mockito.when; +import java.util.HashMap; +import java.util.Map; +import java.util.TreeSet; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.Sets; import org.dspace.app.rest.model.MockObject; import org.dspace.app.rest.model.MockObjectRest; import org.dspace.app.rest.model.RestAddressableModel; import org.dspace.app.rest.model.RestModel; +import org.dspace.app.rest.model.hateoas.EmbeddedPage; import org.dspace.app.rest.model.hateoas.HALResource; import org.dspace.app.rest.model.hateoas.MockObjectResource; import org.dspace.app.rest.projection.MockProjection; @@ -50,12 +57,10 @@ public class ConverterServiceIT extends AbstractControllerIntegrationTest { @Mock private Object mockEmbeddedResource; - private static final Long ORIG_ID = 0L; - - private static final String ORIG_VALUE = "value0"; - - private final MockObject mockObject = mockObject(ORIG_ID); - + /** + * When calling {@code toRest} with an object for which an appropriate {@link DSpaceConverter} can't be found, + * it should throw an {@link IllegalArgumentException}. + */ @Test public void toRestNoConverterFound() { try { @@ -66,27 +71,45 @@ public class ConverterServiceIT extends AbstractControllerIntegrationTest { } } + /** + * When calling {@code toRest} and the inferred return type is incompatible with the converter's output, + * it should throw a {@link ClassCastException}. + */ @Test(expected = ClassCastException.class) public void toRestWrongReturnType() { @SuppressWarnings("unused") - String restObject = converter.toRest(mockObject(0), Projection.DEFAULT); + String restObject = converter.toRest(MockObject.create(0), Projection.DEFAULT); } + /** + * When calling {@code toRest} with the default projection, the converter should run and no changes should be made. + */ @Test public void toRestWithDefaultProjection() { - MockObjectRest restObject = converter.toRest(mockObject(0), Projection.DEFAULT); - assertEquals(ORIG_ID, restObject.getId()); - assertEquals(ORIG_VALUE, restObject.getValue()); + long id = 0; + MockObjectRest restObject = converter.toRest(MockObject.create(id), Projection.DEFAULT); + assertThat(restObject.getId(), equalTo(id)); + assertThat(restObject.getValue(), equalTo("value" + id)); } + /** + * When calling {@code toRest} with a custom projection, {@link Projection#transformModel(Object)} should + * be called before conversion, then {@link Projection#transformRest(RestModel)} should be called before + * returning. + */ @Test public void toRestWithMockProjection() { + long id = 0; MockProjection mockProjection = new MockProjection(mockLink, mockEmbeddedResource); - MockObjectRest restObject = converter.toRest(mockObject, mockProjection); - assertThat(restObject.getId(), equalTo((ORIG_ID + 1) * 3)); - assertThat(restObject.getValue(), equalTo(ORIG_VALUE + "?!")); + MockObjectRest restObject = converter.toRest(MockObject.create(id), mockProjection); + assertThat(restObject.getId(), equalTo((id + 1) * 3)); + assertThat(restObject.getValue(), equalTo("value" + id + "?!")); } + /** + * When calling {@code toResource}, if an appropriate constructor could not be found, + * it should throw an {@link IllegalArgumentException}. + */ @Test public void toResourceNoConstructorFound() { try { @@ -97,50 +120,161 @@ public class ConverterServiceIT extends AbstractControllerIntegrationTest { } } + /** + * When calling {@code toResource} and the inferred return type is incompatible with the resource constructor, + * it should throw a {@link ClassCastException}. + */ @Test(expected = ClassCastException.class) public void toResourceWrongReturnType() { @SuppressWarnings("unused") - MockHalResource mockHalResource = converter.toResource(mockObjectRest(0)); + MockHalResource mockHalResource = converter.toResource(MockObjectRest.create(0)); } + /** + * When calling {@code toResource} with the default projection, the result should have all + * the expected links and embeds with no changes introduced by the projection. + */ @Test - public void toResourceWithDefaultProjection() { - MockObjectRest r0 = mockObjectRest(0); - MockObjectRest r1 = mockObjectRest(1); + public void toResourceWithDefaultProjection() throws Exception { + MockObjectRest r0 = MockObjectRest.create(0); + MockObjectRest r1 = MockObjectRest.create(1); + MockObjectRest r2 = MockObjectRest.create(2); + MockObjectRest r6 = MockObjectRest.create(6); r0.setRestProp1(r1); + r0.setRestProp2(r2); + r0.setRestProp6(r6); + String r0json = new ObjectMapper().writeValueAsString(r0); + MockObjectResource resource = converter.toResource(r0); - assertEquals(ORIG_ID, resource.getContent().getId()); - assertEquals(ORIG_VALUE, resource.getContent().getValue()); - assertEquals(5, resource.getLinks().size()); - assertEquals("restProp1", resource.getLinks().get(0).getRel()); - assertEquals("restProp2", resource.getLinks().get(1).getRel()); - assertEquals("restProp3", resource.getLinks().get(2).getRel()); - assertEquals("restPropFour", resource.getLinks().get(3).getRel()); - assertEquals("self", resource.getLinks().get(4).getRel()); - assertEquals(4, resource.getEmbeddedResources().size()); - assertTrue(resource.getEmbeddedResources().containsKey("restProp1")); - assertTrue(resource.getEmbeddedResources().containsKey("restProp2")); - assertTrue(resource.getEmbeddedResources().containsKey("restProp3")); - assertTrue(resource.getEmbeddedResources().containsKey("restPropFour")); - assertEquals(r1, ((Resource) resource.getEmbeddedResources().get("restProp1")).getContent()); - assertNull(resource.getEmbeddedResources().get("restProp2")); - assertNull(resource.getEmbeddedResources().get("restProp3")); - assertNull(resource.getEmbeddedResources().get("restPropFour")); + + // The default projection should not modify the wrapped object + assertThat(new ObjectMapper().writeValueAsString(r0), equalTo(r0json)); + + assertHasEmbeds(resource, new String[] { + "restProp1", // restProp1 embedded; value != null, embedOptional == false + "restProp2", // restProp2 embedded; value != null, embedOptional == true + // restProp3 not embedded; value == null, embedOptional == true + // restProp4 not embedded; value == null, embedOptional == true + "restPropFive", // restPropFive embedded; value == null, embedOptional == false + "restProp6", // restProp6 embedded; value != null, embedOptional == false + "oChildren", // oChildren embedded; value != null, embedOptional == true + "aChildren" // aChildren embedded; value != null, embedOptional == false + // nChildren not embedded; value != null, linkOptional == false, embedOptional == false + // (embed disallowed by link repository) + }, new Class[] { + Resource.class, + Resource.class, + null, + Resource.class, + EmbeddedPage.class, + EmbeddedPage.class + }); + + assertEmbeddedPageSize(resource, "oChildren", 2); + assertEmbeddedPageSize(resource, "aChildren", 2); + + assertHasLinks(resource, new String[] { + "self", // self linked; (added by DSpaceResourceHalLinkFactory) + "restProp1", // restProp1 linked; value != null, linkOptional == true, embedOptional == false + "restProp2", // restProp2 linked; value != null, linkOptional == true, embedOptional == true + // restProp3 not linked; value == null, linkOptional == true, embedOptional == true + "restProp4", // restProp4 linked; value == null, linkOptional == false, embedOptional == true + "restPropFive", // restPropFive linked; value == null, linkOptional == false, embedOptional == false + "restProp6", // restProp6 linked; value != null, linkOptional == false, embedOptional == false + "oChildren", // oChildren linked; value != null, linkOptional == true, embedOptional == true + "aChildren", // aChildren linked; value != null, linkOptional == true, embedOptional == false + "nChildren" // nChildren linked; value != null, linkOptional == false, embedOptional == false + }); } - private static MockObject mockObject(long id) { - MockObject mockObject = new MockObject(); - mockObject.setStoredId(id); - mockObject.setStoredValue("value" + id); - return mockObject; + /** + * When calling {@code toResource} with a custom projection, the result should have all + * the expected links and embeds, including/excluding any changes introduced by the projection. + */ + @Test + public void toResourceWithMockProjection() throws Exception { + MockObjectRest r0 = MockObjectRest.create(0); + MockObjectRest r1 = MockObjectRest.create(1); + MockObjectRest r2 = MockObjectRest.create(2); + MockObjectRest r6 = MockObjectRest.create(6); + r0.setRestProp1(r1); + r0.setRestProp2(r2); + r0.setRestProp6(r6); + String r0json = new ObjectMapper().writeValueAsString(r0); + + when(mockLink.getRel()).thenReturn("mockLink"); + r0.setProjection(new MockProjection(mockLink, mockEmbeddedResource)); + + MockObjectResource resource = converter.toResource(r0); + + // The mock projection should not modify the wrapped object + assertThat(new ObjectMapper().writeValueAsString(r0), equalTo(r0json)); + + assertHasEmbeds(resource, new String[] { + "restProp1", // restProp1 embedded; value != null, embedOptional == false + // restProp2 not embedded; value != null, embedOptional == true + // restProp3 not embedded; value == null, embedOptional == true + // restProp4 not embedded; value == null, embedOptional == true + "restPropFive", // restPropFive embedded; value == null, embedOptional == false + "restProp6", // restProp6 embedded; value != null, embedOptional == false + // oChildren not embedded; value != null, embedOptional == true + "aChildren", // aChildren embedded; value != null, embedOptional == false + // nChildren not embedded; value != null, linkOptional == false, embedOptional == false + // (embed disallowed by link repository) + "resource" // resource embedded (added by MockProjection) + }, new Class[] { + Resource.class, + null, + Resource.class, + EmbeddedPage.class, + Object.class + }); + + assertEmbeddedPageSize(resource, "aChildren", 2); + + assertHasLinks(resource, new String[] { + "self", // self linked; (added by DSpaceResourceHalLinkFactory) + "restProp1", // restProp1 linked; value != null, linkOptional == true, embedOptional == false + // restProp2 not linked; value != null, linkOptional == true, embedOptional == true + // restProp3 not linked; value == null, linkOptional == true, embedOptional == true + "restProp4", // restProp4 linked; value == null, linkOptional == false, embedOptional == true + "restPropFive", // restPropFive linked; value == null, linkOptional == false, embedOptional == false + "restProp6", // restProp6 linked; value != null, linkOptional == false, embedOptional == false + // oChildren not linked; value != null, linkOptional == true, embedOptional == true + "aChildren", // aChildren linked; value != null, linkOptional == true, embedOptional == false + "nChildren", // nChildren linked; value != null, linkOptional == false, embedOptional == false + "mockLink" // mockLink linked; (added by MockProjection) + }); } - private static MockObjectRest mockObjectRest(long id) { - MockObjectRest mockObjectRest = new MockObjectRest(); - mockObjectRest.setProjection(Projection.DEFAULT); - mockObjectRest.setId(id); - mockObjectRest.setValue("value" + id); - return mockObjectRest; + private void assertHasLinks(Resource resource, String[] rels) { + Map map = new HashMap<>(); + resource.getLinks().stream().forEach((link) -> map.put(link.getRel(), link)); + assertThat(new TreeSet(map.keySet()), equalTo(new TreeSet(Sets.newHashSet(rels)))); + } + + private void assertHasEmbeds(HALResource resource, String[] rels, Class[] classes) { + assertThat(new TreeSet(resource.getEmbeddedResources().keySet()), equalTo(new TreeSet(Sets.newHashSet(rels)))); + for (int i = 0; i < rels.length; i++) { + String rel = rels[i]; + Class expectedClass = classes[i]; + Object value = resource.getEmbeddedResources().get(rel); + if (expectedClass == null) { + if (value != null) { + fail("expected null value for embed: " + rel); + } + } else if (value == null) { + fail("got null value, but expected a " + expectedClass + " for embed: " + rel); + } else { + assertTrue("got a " + value.getClass() + " value, but expected a " + + expectedClass + " for embed: " + rel, expectedClass.isAssignableFrom(value.getClass())); + } + } + } + + private void assertEmbeddedPageSize(HALResource resource, String rel, int expectedSize) { + assertEquals(expectedSize, ((EmbeddedPage) resource.getEmbeddedResources() + .get(rel)).getPageContent().get(rel).size()); } class MockRestAddressableModel extends RestAddressableModel { diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/model/MockObject.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/model/MockObject.java index 5e774987a9..5268b0b253 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/model/MockObject.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/model/MockObject.java @@ -18,6 +18,13 @@ public class MockObject { private String storedValue; + public static MockObject create(long id) { + MockObject mockObject = new MockObject(); + mockObject.setStoredId(id); + mockObject.setStoredValue("value" + id); + return mockObject; + } + public Long getStoredId() { return storedId; } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/model/MockObjectRest.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/model/MockObjectRest.java index ea1a4c6311..f335177993 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/model/MockObjectRest.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/model/MockObjectRest.java @@ -8,16 +8,43 @@ package org.dspace.app.rest.model; import org.dspace.app.rest.RestResourceController; +import org.dspace.app.rest.projection.Projection; /** * A simple rest object for use with tests. */ +@LinksRest(links = { + @LinkRest( + name = MockObjectRest.O_CHILDREN, + linkClass = MockObjectRest.class, + method = "getMockObjectChildren", + embedOptional = true, + linkOptional = true + ), + @LinkRest( + name = MockObjectRest.A_CHILDREN, + linkClass = MockObjectRest.class, + method = "getMockObjectChildren", + linkOptional = true + ), + @LinkRest( + name = MockObjectRest.N_CHILDREN, + linkClass = MockObjectRest.class, + method = "getMockObjectChildren" + ) +}) public class MockObjectRest extends BaseObjectRest { public static final String CATEGORY = "test"; public static final String NAME = "testobject"; + public static final String O_CHILDREN = "oChildren"; + + public static final String A_CHILDREN = "aChildren"; + + public static final String N_CHILDREN = "nChildren"; + private String value; private MockObjectRest restProp1; @@ -28,6 +55,18 @@ public class MockObjectRest extends BaseObjectRest { private MockObjectRest restProp4; + private MockObjectRest restProp5; + + private MockObjectRest restProp6; + + public static MockObjectRest create(long id) { + MockObjectRest mockObjectRest = new MockObjectRest(); + mockObjectRest.setProjection(Projection.DEFAULT); + mockObjectRest.setId(id); + mockObjectRest.setValue("value" + id); + return mockObjectRest; + } + @Override public String getCategory() { return CATEGORY; @@ -51,6 +90,7 @@ public class MockObjectRest extends BaseObjectRest { this.value = value; } + @LinkRest(linkClass = MockObjectRest.class, linkOptional = true) public MockObjectRest getRestProp1() { return restProp1; } @@ -59,7 +99,7 @@ public class MockObjectRest extends BaseObjectRest { this.restProp1 = restProp1; } - @LinkRest(linkClass = MockObjectRest.class) + @LinkRest(linkClass = MockObjectRest.class, embedOptional = true, linkOptional = true) public MockObjectRest getRestProp2() { return restProp2; } @@ -68,7 +108,7 @@ public class MockObjectRest extends BaseObjectRest { this.restProp2 = restProp2; } - @LinkRest(linkClass = MockObjectRest.class) + @LinkRest(linkClass = MockObjectRest.class, embedOptional = true, linkOptional = true) public MockObjectRest getRestProp3() { return restProp3; } @@ -77,7 +117,7 @@ public class MockObjectRest extends BaseObjectRest { this.restProp3 = restProp3; } - @LinkRest(linkClass = MockObjectRest.class, name = "restPropFour") + @LinkRest(linkClass = MockObjectRest.class, embedOptional = true) public MockObjectRest getRestProp4() { return restProp4; } @@ -85,4 +125,21 @@ public class MockObjectRest extends BaseObjectRest { public void setRestProp4(MockObjectRest restProp4) { this.restProp4 = restProp4; } + + @LinkRest(linkClass = MockObjectRest.class, name = "restPropFive") + public MockObjectRest getRestProp5() { + return restProp5; + } + + public void setRestProp5(MockObjectRest restProp5) { + this.restProp5 = restProp5; + } + + public MockObjectRest getRestProp6() { + return restProp6; + } + + public void setRestProp6(MockObjectRest restProp6) { + this.restProp6 = restProp6; + } } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/repository/AbstractMockObjectChildLinkRepository.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/repository/AbstractMockObjectChildLinkRepository.java new file mode 100644 index 0000000000..8d7e174057 --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/repository/AbstractMockObjectChildLinkRepository.java @@ -0,0 +1,40 @@ +/** + * 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.util.ArrayList; +import java.util.List; +import javax.annotation.Nullable; +import javax.servlet.http.HttpServletRequest; + +import org.dspace.app.rest.model.MockObject; +import org.dspace.app.rest.model.MockObjectRest; +import org.dspace.app.rest.projection.Projection; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; + +/** + * Abstract link repository for use with tests. + */ +abstract class AbstractMockObjectChildLinkRepository + extends AbstractDSpaceRestRepository implements LinkRestRepository { + + public Page getMockObjectChildren(@Nullable HttpServletRequest request, + Long itemId, + @Nullable Pageable optionalPageable, + Projection projection) { + List children = new ArrayList<>(); + if (itemId == 0) { + children.add(MockObject.create(101)); + children.add(MockObject.create(102)); + } + Pageable pageable = optionalPageable != null ? optionalPageable : new PageRequest(0, 20); + return converter.toRestPage(children, pageable, children.size(), projection); + } +} diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/repository/MockObjectAlwaysEmbedChildLinkRepository.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/repository/MockObjectAlwaysEmbedChildLinkRepository.java new file mode 100644 index 0000000000..1b209c0e54 --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/repository/MockObjectAlwaysEmbedChildLinkRepository.java @@ -0,0 +1,18 @@ +/** + * 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 org.dspace.app.rest.model.MockObjectRest; +import org.springframework.stereotype.Component; + +/** + * Link repository used by {@link MockObjectRest} to test that always-embedded subresources work correctly. + */ +@Component(MockObjectRest.CATEGORY + "." + MockObjectRest.NAME + "." + MockObjectRest.A_CHILDREN) +public class MockObjectAlwaysEmbedChildLinkRepository extends AbstractMockObjectChildLinkRepository { +} diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/repository/MockObjectNeverEmbedChildLinkRepository.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/repository/MockObjectNeverEmbedChildLinkRepository.java new file mode 100644 index 0000000000..7d82938ae8 --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/repository/MockObjectNeverEmbedChildLinkRepository.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.repository; + +import org.dspace.app.rest.model.MockObjectRest; +import org.springframework.stereotype.Component; + +/** + * Link repository used by {@link MockObjectRest} to test that never-embedded subresources work correctly. + */ +@Component(MockObjectRest.CATEGORY + "." + MockObjectRest.NAME + "." + MockObjectRest.N_CHILDREN) +public class MockObjectNeverEmbedChildLinkRepository extends AbstractMockObjectChildLinkRepository { + @Override + public boolean isEmbeddableRelation(Object data, String name) { + return false; + } +} diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/repository/MockObjectOptionallyEmbedChildLinkRepository.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/repository/MockObjectOptionallyEmbedChildLinkRepository.java new file mode 100644 index 0000000000..e75351a78e --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/repository/MockObjectOptionallyEmbedChildLinkRepository.java @@ -0,0 +1,18 @@ +/** + * 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 org.dspace.app.rest.model.MockObjectRest; +import org.springframework.stereotype.Component; + +/** + * Link repository used by {@link MockObjectRest} to test that optionally-embedded subresources work correctly. + */ +@Component(MockObjectRest.CATEGORY + "." + MockObjectRest.NAME + "." + MockObjectRest.O_CHILDREN) +public class MockObjectOptionallyEmbedChildLinkRepository extends AbstractMockObjectChildLinkRepository { +} From 0a36fc13f106a60b3ecff35cd236bc03f50c4b46 Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Tue, 19 Nov 2019 11:43:17 -0500 Subject: [PATCH 15/20] DS-3533 Make MetadataConverter a DSpaceCoverter, supporting projections --- .../rest/converter/DSpaceObjectConverter.java | 6 ++- .../app/rest/converter/ItemConverter.java | 7 ++-- .../app/rest/converter/MetadataConverter.java | 22 +++++------ .../app/rest/model/MetadataValueList.java | 39 +++++++++++++++++++ 4 files changed, 58 insertions(+), 16 deletions(-) create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MetadataValueList.java diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceObjectConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceObjectConverter.java index d57d02ba5b..7d3d89ad0c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceObjectConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DSpaceObjectConverter.java @@ -7,6 +7,7 @@ */ package org.dspace.app.rest.converter; +import org.dspace.app.rest.model.MetadataValueList; import org.dspace.app.rest.projection.Projection; import org.dspace.content.DSpaceObject; import org.springframework.beans.factory.annotation.Autowired; @@ -23,7 +24,7 @@ public abstract class DSpaceObjectConverter implements DSpaceConverter { @Autowired - private MetadataConverter metadataConverter; + ConverterService converter; @Override public R convert(M obj, Projection projection) { @@ -34,7 +35,8 @@ public abstract class DSpaceObjectConverter fullList = itemService.getMetadata(obj, Item.ANY, Item.ANY, Item.ANY, Item.ANY, true); - item.setMetadata(metadataConverter.convert(fullList)); + MetadataValueList metadataValues = new MetadataValueList(fullList); + item.setMetadata(converter.toRest(metadataValues, projection)); return item; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataConverter.java index 6e33f842fb..9a8f368add 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataConverter.java @@ -17,6 +17,7 @@ import java.util.TreeSet; import java.util.stream.Collectors; import org.dspace.app.rest.model.MetadataRest; +import org.dspace.app.rest.model.MetadataValueList; import org.dspace.app.rest.model.MetadataValueRest; import org.dspace.app.rest.projection.Projection; import org.dspace.authorize.AuthorizeException; @@ -27,14 +28,13 @@ import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.DSpaceObjectService; import org.dspace.core.Context; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component; /** * Converter to translate between lists of domain {@link MetadataValue}s and {@link MetadataRest} representations. */ @Component -public class MetadataConverter implements Converter, MetadataRest> { +public class MetadataConverter implements DSpaceConverter { @Autowired private ContentServiceFactory contentServiceFactory; @@ -42,24 +42,19 @@ public class MetadataConverter implements Converter, Metadat @Autowired private ConverterService converter; - /** - * Gets a rest representation of the given list of domain metadata values. - * - * @param metadataValueList the domain values. - * @return the rest representation. - */ @Override - public MetadataRest convert(List metadataValueList) { + public MetadataRest convert(MetadataValueList metadataValues, + Projection projection) { // Convert each value to a DTO while retaining place order in a map of key -> SortedSet Map> mapOfSortedSets = new HashMap<>(); - for (MetadataValue metadataValue : metadataValueList) { + for (MetadataValue metadataValue : metadataValues) { String key = metadataValue.getMetadataField().toString('.'); SortedSet set = mapOfSortedSets.get(key); if (set == null) { set = new TreeSet<>(Comparator.comparingInt(MetadataValueRest::getPlace)); mapOfSortedSets.put(key, set); } - set.add(converter.toRest(metadataValue, Projection.DEFAULT)); + set.add(converter.toRest(metadataValue, projection)); } MetadataRest metadataRest = new MetadataRest(); @@ -73,6 +68,11 @@ public class MetadataConverter implements Converter, Metadat return metadataRest; } + @Override + public Class getModelClass() { + return MetadataValueList.class; + } + /** * Sets a DSpace object's domain metadata values from a rest representation. * diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MetadataValueList.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MetadataValueList.java new file mode 100644 index 0000000000..cb0f474420 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MetadataValueList.java @@ -0,0 +1,39 @@ +/** + * 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.model; + +import java.util.AbstractList; +import java.util.List; + +import org.dspace.app.rest.converter.ConverterService; +import org.dspace.app.rest.converter.MetadataConverter; +import org.dspace.app.rest.projection.Projection; +import org.dspace.content.MetadataValue; + +/** + * Type-safe wrapper for a list of {@link MetadataValue}s for use with {@link MetadataConverter}, + * so it can be invoked properly via calls to {@link ConverterService#toRest(Object, Projection)}. + */ +public class MetadataValueList extends AbstractList { + + private final List list; + + public MetadataValueList(List list) { + this.list = list; + } + + @Override + public MetadataValue get(int index) { + return list.get(index); + } + + @Override + public int size() { + return list.size(); + } +} From 71b1360cbf201cc802f2a6cbbd054dfe1a1d8619 Mon Sep 17 00:00:00 2001 From: Raf Ponsaerts Date: Fri, 22 Nov 2019 11:06:12 +0100 Subject: [PATCH 16/20] [DS-4390] rewrote ScriptLauncher to include scripts from other config to be checked as well as fixing tests --- .../dspace/app/launcher/ScriptLauncher.java | 51 +++++++++++++++++-- .../AbstractIntegrationTestWithDatabase.java | 18 +++++-- .../impl/TestDSpaceRunnableHandler.java | 36 +++++++++++++ 3 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/scripts/handler/impl/TestDSpaceRunnableHandler.java diff --git a/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java b/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java index 435c28bcb9..2c9ce32988 100644 --- a/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java +++ b/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java @@ -13,9 +13,16 @@ import java.lang.reflect.Method; import java.util.List; import java.util.TreeMap; +import org.apache.commons.cli.ParseException; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import org.dspace.scripts.DSpaceRunnable; +import org.dspace.scripts.handler.DSpaceRunnableHandler; +import org.dspace.scripts.handler.impl.CommandLineDSpaceRunnableHandler; import org.dspace.servicemanager.DSpaceKernelImpl; import org.dspace.servicemanager.DSpaceKernelInit; import org.dspace.services.RequestService; +import org.dspace.utils.DSpace; import org.jdom.Document; import org.jdom.Element; import org.jdom.input.SAXBuilder; @@ -27,6 +34,9 @@ import org.jdom.input.SAXBuilder; * @author Mark Diggory */ public class ScriptLauncher { + + private static final Logger log = Logger.getLogger(ScriptLauncher.class); + /** * The service manager kernel */ @@ -76,8 +86,10 @@ public class ScriptLauncher { } // Look up command in the configuration, and execute. - int status; - status = runOneCommand(commandConfigs, args); + Integer status; + + CommandLineDSpaceRunnableHandler commandLineDSpaceRunnableHandler = new CommandLineDSpaceRunnableHandler(); + status = handleScript(args, commandConfigs, commandLineDSpaceRunnableHandler, kernelImpl); // Destroy the service kernel if it is still alive if (kernelImpl != null) { @@ -86,6 +98,39 @@ public class ScriptLauncher { } System.exit(status); + + } + + public static Integer handleScript(String[] args, Document commandConfigs, + DSpaceRunnableHandler dSpaceRunnableHandler, + DSpaceKernelImpl kernelImpl) { + Integer status; + status = runDSpaceScriptWithArgs(args, dSpaceRunnableHandler); + if (status == null) { + status = runOneCommand(commandConfigs, args, kernelImpl); + } + return status; + } + + private static Integer runDSpaceScriptWithArgs(String[] args, DSpaceRunnableHandler dSpaceRunnableHandler) { + List scripts = new DSpace().getServiceManager().getServicesByType(DSpaceRunnable.class); + String command = args[0]; + for (DSpaceRunnable script : scripts) { + if (StringUtils.equalsIgnoreCase(script.getName(), command)) { + try { + script.initialize(args, dSpaceRunnableHandler); + script.run(); + return 0; + } catch (ParseException e) { + script.printHelp(); + log.error(e.getMessage(), e); + System.out.println(e.getMessage()); + e.printStackTrace(); + return 1; + } + } + } + return null; } protected static int runOneCommand(Document commandConfigs, String[] args) { @@ -98,7 +143,7 @@ public class ScriptLauncher { * @param commandConfigs Document * @param args the command line arguments given */ - public static int runOneCommand(Document commandConfigs, String[] args, DSpaceKernelImpl kernelImpl) { + protected static int runOneCommand(Document commandConfigs, String[] args, DSpaceKernelImpl kernelImpl) { String request = args[0]; Element root = commandConfigs.getRootElement(); List commands = root.getChildren("command"); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractIntegrationTestWithDatabase.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractIntegrationTestWithDatabase.java index af5134e868..02bbbadf36 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractIntegrationTestWithDatabase.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractIntegrationTestWithDatabase.java @@ -15,6 +15,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.dspace.app.launcher.ScriptLauncher; import org.dspace.app.rest.builder.AbstractBuilder; +import org.dspace.app.scripts.handler.impl.TestDSpaceRunnableHandler; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Community; import org.dspace.core.Context; @@ -41,7 +42,7 @@ public class AbstractIntegrationTestWithDatabase extends AbstractDSpaceIntegrati * log4j category */ private static final Logger log = LogManager - .getLogger(AbstractIntegrationTestWithDatabase.class); + .getLogger(AbstractIntegrationTestWithDatabase.class); /** * Context mock object to use in the tests. @@ -179,8 +180,9 @@ public class AbstractIntegrationTestWithDatabase extends AbstractDSpaceIntegrati // Clear the search core. MockSolrServiceImpl searchService = DSpaceServicesFactory.getInstance() - .getServiceManager() - .getServiceByName(SearchService.class.getName(), MockSolrServiceImpl.class); + .getServiceManager() + .getServiceByName(SearchService.class.getName(), + MockSolrServiceImpl.class); searchService.reset(); // Reload our ConfigurationService (to reset configs to defaults again) @@ -227,11 +229,17 @@ public class AbstractIntegrationTestWithDatabase extends AbstractDSpaceIntegrati } // Look up command in the configuration, and execute. - return ScriptLauncher.runOneCommand(commandConfigs, args, kernelImpl); + TestDSpaceRunnableHandler testDSpaceRunnableHandler = new TestDSpaceRunnableHandler(); + int status = ScriptLauncher.handleScript(args, commandConfigs, testDSpaceRunnableHandler, kernelImpl); + if (testDSpaceRunnableHandler.getException() != null) { + throw testDSpaceRunnableHandler.getException(); + } else { + return status; + } } finally { if (!context.isValid()) { setUp(); } } } -} +} \ No newline at end of file diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/scripts/handler/impl/TestDSpaceRunnableHandler.java b/dspace-server-webapp/src/test/java/org/dspace/app/scripts/handler/impl/TestDSpaceRunnableHandler.java new file mode 100644 index 0000000000..74e2a56668 --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/scripts/handler/impl/TestDSpaceRunnableHandler.java @@ -0,0 +1,36 @@ +/** + * 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.scripts.handler.impl; + +import org.dspace.scripts.handler.impl.CommandLineDSpaceRunnableHandler; + +/** + * This class will be used as a DSpaceRunnableHandler for the Tests so that we can stop the handler + * from calling System.exit() when a script would throw an exception + */ +public class TestDSpaceRunnableHandler extends CommandLineDSpaceRunnableHandler { + + private Exception exception = null; + + /** + * We're overriding this method so that we can stop the script from doing the System.exit() if + * an exception within the script is thrown + */ + @Override + public void handleException(String message, Exception e) { + exception = e; + } + + /** + * Generic getter for the exception + * @return the exception value of this TestDSpaceRunnableHandler + */ + public Exception getException() { + return exception; + } +} \ No newline at end of file From 9be226e6d305733602b3e255669a1a51084387d5 Mon Sep 17 00:00:00 2001 From: Raf Ponsaerts Date: Fri, 22 Nov 2019 13:24:46 +0100 Subject: [PATCH 17/20] [DS-4390] cleanup retrieval of DSpaceRunnable by name and cleanup in ScriptLauncher.java --- .../dspace/app/launcher/ScriptLauncher.java | 58 +++++++++++-------- .../factory/ProcessServiceFactory.java | 34 ----------- .../org/dspace/scripts/ScriptServiceImpl.java | 31 ++++++++++ .../scripts/factory/ScriptServiceFactory.java | 41 +++++++++++++ .../impl/ScriptServiceFactoryImpl.java} | 17 ++++-- .../dspace/scripts/service/ScriptService.java | 23 ++++++++ .../DSpaceApiExceptionControllerAdvice.java | 5 +- .../rest/repository/ScriptRestRepository.java | 32 +++++----- .../impl/RestDSpaceRunnableHandler.java | 4 +- .../app/rest/builder/AbstractBuilder.java | 4 +- .../spring/api/core-factory-services.xml | 2 +- dspace/config/spring/api/core-services.xml | 1 + 12 files changed, 164 insertions(+), 88 deletions(-) delete mode 100644 dspace-api/src/main/java/org/dspace/content/factory/ProcessServiceFactory.java create mode 100644 dspace-api/src/main/java/org/dspace/scripts/ScriptServiceImpl.java create mode 100644 dspace-api/src/main/java/org/dspace/scripts/factory/ScriptServiceFactory.java rename dspace-api/src/main/java/org/dspace/{content/factory/impl/ProcessServiceFactoryImpl.java => scripts/factory/impl/ScriptServiceFactoryImpl.java} (53%) create mode 100644 dspace-api/src/main/java/org/dspace/scripts/service/ScriptService.java diff --git a/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java b/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java index 2c9ce32988..a2ef3144a8 100644 --- a/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java +++ b/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java @@ -14,15 +14,14 @@ import java.util.List; import java.util.TreeMap; import org.apache.commons.cli.ParseException; -import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.dspace.scripts.DSpaceRunnable; +import org.dspace.scripts.factory.ScriptServiceFactory; import org.dspace.scripts.handler.DSpaceRunnableHandler; import org.dspace.scripts.handler.impl.CommandLineDSpaceRunnableHandler; import org.dspace.servicemanager.DSpaceKernelImpl; import org.dspace.servicemanager.DSpaceKernelInit; import org.dspace.services.RequestService; -import org.dspace.utils.DSpace; import org.jdom.Document; import org.jdom.Element; import org.jdom.input.SAXBuilder; @@ -101,36 +100,47 @@ public class ScriptLauncher { } - public static Integer handleScript(String[] args, Document commandConfigs, + /** + * This method will take the arguments from a commandline input and it'll find the script that the first argument + * refers to and it'll execute this script. + * It can return a 1 or a 0 depending on whether the script failed or passed respectively + * @param args The arguments for the script and the script as first one in the array + * @param commandConfigs The Document + * @param dSpaceRunnableHandler The DSpaceRunnableHandler for this execution + * @param kernelImpl The relevant DSpaceKernelImpl + * @return A 1 or 0 depending on whether the script failed or passed respectively + */ + public static int handleScript(String[] args, Document commandConfigs, DSpaceRunnableHandler dSpaceRunnableHandler, DSpaceKernelImpl kernelImpl) { - Integer status; - status = runDSpaceScriptWithArgs(args, dSpaceRunnableHandler); - if (status == null) { + int status; + DSpaceRunnable script = ScriptServiceFactory.getInstance().getScriptService().getScriptForName(args[0]); + if (script != null) { + status = executeScript(args, dSpaceRunnableHandler, script); + } else { status = runOneCommand(commandConfigs, args, kernelImpl); } return status; } - private static Integer runDSpaceScriptWithArgs(String[] args, DSpaceRunnableHandler dSpaceRunnableHandler) { - List scripts = new DSpace().getServiceManager().getServicesByType(DSpaceRunnable.class); - String command = args[0]; - for (DSpaceRunnable script : scripts) { - if (StringUtils.equalsIgnoreCase(script.getName(), command)) { - try { - script.initialize(args, dSpaceRunnableHandler); - script.run(); - return 0; - } catch (ParseException e) { - script.printHelp(); - log.error(e.getMessage(), e); - System.out.println(e.getMessage()); - e.printStackTrace(); - return 1; - } - } + /** + * This method will simply execute the script + * @param args The arguments of the script with the script name as first place in the array + * @param dSpaceRunnableHandler The relevant DSpaceRunnableHandler + * @param script The script to be executed + * @return A 1 or 0 depending on whether the script failed or passed respectively + */ + private static int executeScript(String[] args, DSpaceRunnableHandler dSpaceRunnableHandler, + DSpaceRunnable script) { + try { + script.initialize(args, dSpaceRunnableHandler); + script.run(); + return 0; + } catch (ParseException e) { + script.printHelp(); + e.printStackTrace(); + return 1; } - return null; } protected static int runOneCommand(Document commandConfigs, String[] args) { diff --git a/dspace-api/src/main/java/org/dspace/content/factory/ProcessServiceFactory.java b/dspace-api/src/main/java/org/dspace/content/factory/ProcessServiceFactory.java deleted file mode 100644 index a9022a59a8..0000000000 --- a/dspace-api/src/main/java/org/dspace/content/factory/ProcessServiceFactory.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.content.factory; - -import org.dspace.scripts.service.ProcessService; -import org.dspace.services.factory.DSpaceServicesFactory; - -/** - * Abstract factory to get services for the Process workload, use ProcessServiceFactory.getInstance() to retrieve an - * implementation - * - */ -public abstract class ProcessServiceFactory { - - /** - * This method will return an instance of the ProcessService - * @return An instance of the ProcessService - */ - public abstract ProcessService getProcessService(); - - /** - * Use this method to retrieve an implementation of the ProcessServiceFactory to use to retrieve the different beans - * @return An implementation of the ProcessServiceFactory - */ - public static ProcessServiceFactory getInstance() { - return DSpaceServicesFactory.getInstance().getServiceManager() - .getServiceByName("processServiceFactory", ProcessServiceFactory.class); - } -} diff --git a/dspace-api/src/main/java/org/dspace/scripts/ScriptServiceImpl.java b/dspace-api/src/main/java/org/dspace/scripts/ScriptServiceImpl.java new file mode 100644 index 0000000000..ef67473327 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/scripts/ScriptServiceImpl.java @@ -0,0 +1,31 @@ +/** + * 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.scripts; + +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.dspace.scripts.service.ScriptService; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * The implementation for the {@link ScriptService} + */ +public class ScriptServiceImpl implements ScriptService { + + @Autowired + private List dSpaceRunnables; + + @Override + public DSpaceRunnable getScriptForName(String name) { + return dSpaceRunnables.stream() + .filter(dSpaceRunnable -> StringUtils.equalsIgnoreCase(dSpaceRunnable.getName(), name)) + .findFirst() + .orElse(null); + } +} diff --git a/dspace-api/src/main/java/org/dspace/scripts/factory/ScriptServiceFactory.java b/dspace-api/src/main/java/org/dspace/scripts/factory/ScriptServiceFactory.java new file mode 100644 index 0000000000..8f24728625 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/scripts/factory/ScriptServiceFactory.java @@ -0,0 +1,41 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.scripts.factory; + +import org.dspace.scripts.service.ProcessService; +import org.dspace.scripts.service.ScriptService; +import org.dspace.services.factory.DSpaceServicesFactory; + +/** + * Abstract factory to get services for the Script workload, use ScriptServiceFactory.getInstance() to retrieve an + * implementation + * + */ +public abstract class ScriptServiceFactory { + + /** + * This method will return an instance of the ScriptService + * @return An instance of the ScriptService + */ + public abstract ScriptService getScriptService(); + + /** + * This method will return an instance of the ProcessService + * @return An instance of the ProcessService + */ + public abstract ProcessService getProcessService(); + + /** + * Use this method to retrieve an implementation of the ScriptServiceFactory to use to retrieve the different beans + * @return An implementation of the ScriptServiceFactory + */ + public static ScriptServiceFactory getInstance() { + return DSpaceServicesFactory.getInstance().getServiceManager() + .getServiceByName("scriptServiceFactory", ScriptServiceFactory.class); + } +} diff --git a/dspace-api/src/main/java/org/dspace/content/factory/impl/ProcessServiceFactoryImpl.java b/dspace-api/src/main/java/org/dspace/scripts/factory/impl/ScriptServiceFactoryImpl.java similarity index 53% rename from dspace-api/src/main/java/org/dspace/content/factory/impl/ProcessServiceFactoryImpl.java rename to dspace-api/src/main/java/org/dspace/scripts/factory/impl/ScriptServiceFactoryImpl.java index f9e02a0302..ba8cd1a784 100644 --- a/dspace-api/src/main/java/org/dspace/content/factory/impl/ProcessServiceFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/scripts/factory/impl/ScriptServiceFactoryImpl.java @@ -5,20 +5,29 @@ * * http://www.dspace.org/license/ */ -package org.dspace.content.factory.impl; +package org.dspace.scripts.factory.impl; -import org.dspace.content.factory.ProcessServiceFactory; +import org.dspace.scripts.factory.ScriptServiceFactory; import org.dspace.scripts.service.ProcessService; +import org.dspace.scripts.service.ScriptService; import org.springframework.beans.factory.annotation.Autowired; /** - * The implementation for the {@link ProcessServiceFactory} + * The implementation for the {@link ScriptServiceFactory} */ -public class ProcessServiceFactoryImpl extends ProcessServiceFactory { +public class ScriptServiceFactoryImpl extends ScriptServiceFactory { + + @Autowired(required = true) + private ScriptService scriptService; @Autowired(required = true) private ProcessService processService; + @Override + public ScriptService getScriptService() { + return scriptService; + } + @Override public ProcessService getProcessService() { return processService; diff --git a/dspace-api/src/main/java/org/dspace/scripts/service/ScriptService.java b/dspace-api/src/main/java/org/dspace/scripts/service/ScriptService.java new file mode 100644 index 0000000000..99296fe7f3 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/scripts/service/ScriptService.java @@ -0,0 +1,23 @@ +/** + * 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.scripts.service; + +import org.dspace.scripts.DSpaceRunnable; + +/** + * This service will deal with logic to handle DSpaceRunnable objects + */ +public interface ScriptService { + + /** + * This method will return the DSpaceRunnable that has the name that's equal to the name given in the parameters + * @param name The name that the script has to match + * @return The matching DSpaceRunnable script + */ + DSpaceRunnable getScriptForName(String name); +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java index a0b033d8c6..88cb58ae2b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java @@ -29,6 +29,7 @@ import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.context.request.WebRequest; +import org.springframework.web.multipart.MultipartException; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; /** @@ -54,8 +55,8 @@ public class DSpaceApiExceptionControllerAdvice extends ResponseEntityExceptionH } } - @ExceptionHandler(IllegalArgumentException.class) - protected void handleIllegalArgumentException(HttpServletRequest request, HttpServletResponse response, + @ExceptionHandler({IllegalArgumentException.class, MultipartException.class}) + protected void handleWrongRequestException(HttpServletRequest request, HttpServletResponse response, Exception ex) throws IOException { sendErrorResponse(request, response, ex, ex.getMessage(), HttpServletResponse.SC_BAD_REQUEST); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ScriptRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ScriptRestRepository.java index 12b33d441c..1709696c4b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ScriptRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ScriptRestRepository.java @@ -35,6 +35,7 @@ import org.dspace.core.Context; import org.dspace.scripts.DSpaceCommandLineParameter; import org.dspace.scripts.DSpaceRunnable; import org.dspace.scripts.service.ProcessService; +import org.dspace.scripts.service.ScriptService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -61,18 +62,22 @@ public class ScriptRestRepository extends DSpaceRestRepository dSpaceCommandLineParameters = processPropertiesToDSpaceCommandLineParameters(properties); - DSpaceRunnable scriptToExecute = getdSpaceRunnableForName(scriptName); + DSpaceRunnable scriptToExecute = scriptService.getScriptForName(scriptName); if (scriptToExecute == null) { throw new DSpaceBadRequestException("The script for name: " + scriptName + " wasn't found"); } @@ -145,17 +150,6 @@ public class ScriptRestRepository extends DSpaceRestRepository constructArgs(List dSpaceCommandLineParameters) { List args = new ArrayList<>(); for (DSpaceCommandLineParameter parameter : dSpaceCommandLineParameters) { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/scripts/handler/impl/RestDSpaceRunnableHandler.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/scripts/handler/impl/RestDSpaceRunnableHandler.java index dd549a5873..6fd1aa10fc 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/scripts/handler/impl/RestDSpaceRunnableHandler.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/scripts/handler/impl/RestDSpaceRunnableHandler.java @@ -17,12 +17,12 @@ import org.apache.commons.cli.Options; import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.logging.log4j.Logger; import org.dspace.content.ProcessStatus; -import org.dspace.content.factory.ProcessServiceFactory; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.scripts.DSpaceCommandLineParameter; import org.dspace.scripts.DSpaceRunnable; import org.dspace.scripts.Process; +import org.dspace.scripts.factory.ScriptServiceFactory; import org.dspace.scripts.handler.DSpaceRunnableHandler; import org.dspace.scripts.service.ProcessService; @@ -33,7 +33,7 @@ public class RestDSpaceRunnableHandler implements DSpaceRunnableHandler { private static final Logger log = org.apache.logging.log4j.LogManager .getLogger(RestDSpaceRunnableHandler.class); - private ProcessService processService = ProcessServiceFactory.getInstance().getProcessService(); + private ProcessService processService = ScriptServiceFactory.getInstance().getProcessService(); private Integer processId; private String scriptName; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/builder/AbstractBuilder.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/builder/AbstractBuilder.java index e0591da1f1..403e623c3c 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/builder/AbstractBuilder.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/builder/AbstractBuilder.java @@ -19,7 +19,6 @@ import org.dspace.authorize.service.AuthorizeService; import org.dspace.authorize.service.ResourcePolicyService; import org.dspace.content.Bitstream; import org.dspace.content.factory.ContentServiceFactory; -import org.dspace.content.factory.ProcessServiceFactory; import org.dspace.content.service.BitstreamFormatService; import org.dspace.content.service.BitstreamService; import org.dspace.content.service.BundleService; @@ -40,6 +39,7 @@ import org.dspace.eperson.factory.EPersonServiceFactory; import org.dspace.eperson.service.EPersonService; import org.dspace.eperson.service.GroupService; import org.dspace.eperson.service.RegistrationDataService; +import org.dspace.scripts.factory.ScriptServiceFactory; import org.dspace.scripts.service.ProcessService; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.versioning.factory.VersionServiceFactory; @@ -134,7 +134,7 @@ public abstract class AbstractBuilder { relationshipService = ContentServiceFactory.getInstance().getRelationshipService(); relationshipTypeService = ContentServiceFactory.getInstance().getRelationshipTypeService(); entityTypeService = ContentServiceFactory.getInstance().getEntityTypeService(); - processService = ProcessServiceFactory.getInstance().getProcessService(); + processService = ScriptServiceFactory.getInstance().getProcessService(); // Temporarily disabled claimedTaskService = XmlWorkflowServiceFactory.getInstance().getClaimedTaskService(); diff --git a/dspace/config/spring/api/core-factory-services.xml b/dspace/config/spring/api/core-factory-services.xml index 1b5525c941..a4d7ca08c0 100644 --- a/dspace/config/spring/api/core-factory-services.xml +++ b/dspace/config/spring/api/core-factory-services.xml @@ -22,7 +22,7 @@ - + diff --git a/dspace/config/spring/api/core-services.xml b/dspace/config/spring/api/core-services.xml index f1ce9103b0..e7e28884c2 100644 --- a/dspace/config/spring/api/core-services.xml +++ b/dspace/config/spring/api/core-services.xml @@ -57,6 +57,7 @@ + From 959dacad6a50a4cae5cb16c16bd01949909be540 Mon Sep 17 00:00:00 2001 From: Raf Ponsaerts Date: Fri, 22 Nov 2019 13:27:15 +0100 Subject: [PATCH 18/20] [DS-4390] cleaned up Integer in scriptlauncher --- .../src/main/java/org/dspace/app/launcher/ScriptLauncher.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java b/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java index a2ef3144a8..ef6b0b538e 100644 --- a/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java +++ b/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java @@ -85,10 +85,9 @@ public class ScriptLauncher { } // Look up command in the configuration, and execute. - Integer status; CommandLineDSpaceRunnableHandler commandLineDSpaceRunnableHandler = new CommandLineDSpaceRunnableHandler(); - status = handleScript(args, commandConfigs, commandLineDSpaceRunnableHandler, kernelImpl); + int status = handleScript(args, commandConfigs, commandLineDSpaceRunnableHandler, kernelImpl); // Destroy the service kernel if it is still alive if (kernelImpl != null) { From 02d98b2760219a4f7e35b5595ad19d5686c745e8 Mon Sep 17 00:00:00 2001 From: Raf Ponsaerts Date: Fri, 22 Nov 2019 13:35:33 +0100 Subject: [PATCH 19/20] [DS-4390] undid MultipartFileException --- .../rest/exception/DSpaceApiExceptionControllerAdvice.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java index 88cb58ae2b..a0b033d8c6 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java @@ -29,7 +29,6 @@ import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.context.request.WebRequest; -import org.springframework.web.multipart.MultipartException; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; /** @@ -55,8 +54,8 @@ public class DSpaceApiExceptionControllerAdvice extends ResponseEntityExceptionH } } - @ExceptionHandler({IllegalArgumentException.class, MultipartException.class}) - protected void handleWrongRequestException(HttpServletRequest request, HttpServletResponse response, + @ExceptionHandler(IllegalArgumentException.class) + protected void handleIllegalArgumentException(HttpServletRequest request, HttpServletResponse response, Exception ex) throws IOException { sendErrorResponse(request, response, ex, ex.getMessage(), HttpServletResponse.SC_BAD_REQUEST); } From e87dd5a8b746a71b64187be292f1c59fd2dddcf5 Mon Sep 17 00:00:00 2001 From: Raf Ponsaerts Date: Fri, 22 Nov 2019 14:15:26 +0100 Subject: [PATCH 20/20] [DS-4390] fixed test failure and cleaned up ScriptRestRepository from DSpaceRunnable logic, moved to ScriptService instead --- .../java/org/dspace/scripts/ScriptServiceImpl.java | 8 ++++++++ .../java/org/dspace/scripts/service/ScriptService.java | 10 ++++++++++ .../app/rest/repository/ScriptRestRepository.java | 10 +++------- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/scripts/ScriptServiceImpl.java b/dspace-api/src/main/java/org/dspace/scripts/ScriptServiceImpl.java index ef67473327..e2a6acf3a8 100644 --- a/dspace-api/src/main/java/org/dspace/scripts/ScriptServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/scripts/ScriptServiceImpl.java @@ -8,8 +8,10 @@ package org.dspace.scripts; import java.util.List; +import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; +import org.dspace.core.Context; import org.dspace.scripts.service.ScriptService; import org.springframework.beans.factory.annotation.Autowired; @@ -28,4 +30,10 @@ public class ScriptServiceImpl implements ScriptService { .findFirst() .orElse(null); } + + @Override + public List getDSpaceRunnables(Context context) { + return dSpaceRunnables.stream().filter( + dSpaceRunnable -> dSpaceRunnable.isAllowedToExecute(context)).collect(Collectors.toList()); + } } diff --git a/dspace-api/src/main/java/org/dspace/scripts/service/ScriptService.java b/dspace-api/src/main/java/org/dspace/scripts/service/ScriptService.java index 99296fe7f3..fc680bd612 100644 --- a/dspace-api/src/main/java/org/dspace/scripts/service/ScriptService.java +++ b/dspace-api/src/main/java/org/dspace/scripts/service/ScriptService.java @@ -7,6 +7,9 @@ */ package org.dspace.scripts.service; +import java.util.List; + +import org.dspace.core.Context; import org.dspace.scripts.DSpaceRunnable; /** @@ -20,4 +23,11 @@ public interface ScriptService { * @return The matching DSpaceRunnable script */ DSpaceRunnable getScriptForName(String name); + + /** + * This method will return a list of DSpaceRunnable objects for which the given Context is authorized to use them + * @param context The relevant DSpace context + * @return The list of accessible DSpaceRunnable scripts for this context + */ + List getDSpaceRunnables(Context context); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ScriptRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ScriptRestRepository.java index 1709696c4b..3fa8a22132 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ScriptRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ScriptRestRepository.java @@ -50,9 +50,6 @@ public class ScriptRestRepository extends DSpaceRestRepository dspaceRunnables; - @Autowired private ScriptConverter scriptConverter; @@ -73,7 +70,7 @@ public class ScriptRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { - return utils.getPage(dspaceRunnables.stream().filter( - dSpaceRunnable -> dSpaceRunnable.isAllowedToExecute(context)).collect(Collectors.toList()), pageable) - .map(scriptConverter); + List dSpaceRunnables = scriptService.getDSpaceRunnables(context); + return utils.getPage(dSpaceRunnables, pageable).map(scriptConverter); } @Override