Merge pull request #2625 from atmire/DS-3533_Projections-Continued

DS-3533 Projections continued
This commit is contained in:
Tim Donohue
2020-02-13 10:41:01 -06:00
committed by GitHub
136 changed files with 2233 additions and 1670 deletions

View File

@@ -82,7 +82,7 @@ public class AuthenticationRestController implements InitializingBean {
EPersonRest ePersonRest = null;
Projection projection = utils.obtainProjection();
if (context.getCurrentUser() != null) {
ePersonRest = ePersonConverter.fromModelWithGroups(context, context.getCurrentUser(), projection);
ePersonRest = converter.toRest(context.getCurrentUser(), projection);
}
AuthenticationStatusRest authenticationStatusRest = new AuthenticationStatusRest(ePersonRest);

View File

@@ -22,7 +22,6 @@ import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.link.HalLinkService;
import org.dspace.app.rest.model.BitstreamRest;
import org.dspace.app.rest.model.BundleRest;
import org.dspace.app.rest.model.hateoas.BundleResource;
import org.dspace.app.rest.repository.BitstreamRestRepository;
import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.app.rest.utils.Utils;
@@ -33,12 +32,7 @@ import org.dspace.content.DSpaceObject;
import org.dspace.content.service.BitstreamService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.ControllerUtils;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.hateoas.ResourceSupport;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
@@ -48,12 +42,10 @@ import org.springframework.web.bind.annotation.RestController;
/**
* Controller to access bitstreams and the bundles they're in
* Controller to manage bundle of bitstreams.
* Endpoint: /api/core/bitstreams/{uuid}
* This controller can:
* - request bundle a bitstream is in (GET /api/core/bitstreams/{uuid}/bundle)
* - move bitstreams between bundles (POST /api/core/bitstreams/{uuid}/bundle (text/uri-list) -d link-to-new-bundle)
*
*/
@RestController
@RequestMapping("/api/" + BitstreamRest.CATEGORY + "/" + BitstreamRest.PLURAL_NAME
@@ -75,44 +67,6 @@ public class BitstreamBundleController {
@Autowired
BitstreamRestRepository bitstreamRestRepository;
/**
* This method gets the bundle of the bitstream that corresponds to to the provided bitstream uuid. When multiple
* bundles are present, only the first will be returned.
*
* @param uuid The UUID of the bitstream for which the bundle will be retrieved
* @param response The response object
* @param request The request object
* @return The wrapped resource containing the first bundle of the bitstream
* @throws IOException
* @throws SQLException
* @throws AuthorizeException
*/
@PreAuthorize("hasPermission(#uuid, 'BITSTREAM', 'READ')")
@RequestMapping(method = {RequestMethod.GET, RequestMethod.HEAD})
public ResponseEntity<ResourceSupport> getBundle(@PathVariable UUID uuid, HttpServletResponse response,
HttpServletRequest request)
throws IOException, SQLException, AuthorizeException {
Context context = ContextUtil.obtainContext(request);
Bitstream bitstream = bitstreamService.find(context, uuid);
if (bitstream == null) {
throw new ResourceNotFoundException(
BitstreamRest.CATEGORY + "." + BitstreamRest.NAME + " with id: " + uuid + " not found");
}
List<Bundle> bundles = bitstream.getBundles();
if (bundles.isEmpty()) {
return ControllerUtils.toEmptyResponse(HttpStatus.NO_CONTENT);
}
BundleResource bundleResource = converter.toResource(
converter.toRest(bundles.get(0), utils.obtainProjection()));
return ControllerUtils.toResponseEntity(HttpStatus.OK, new HttpHeaders(), bundleResource);
}
/**
* This method moves the bitstream to the bundle corresponding the the link provided in the body of the put request
*

View File

@@ -19,7 +19,9 @@ import com.fasterxml.jackson.databind.JsonNode;
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.projection.Projection;
import org.dspace.app.rest.repository.ItemRestRepository;
import org.dspace.app.rest.repository.ItemTemplateItemOfLinkRepository;
import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.app.rest.utils.Utils;
import org.dspace.authorize.AuthorizeException;
@@ -57,6 +59,9 @@ public class ItemtemplateRestController {
@Autowired
private ItemRestRepository itemRestRepository;
@Autowired
private ItemTemplateItemOfLinkRepository itemTemplateItemOfLinkRepository;
/**
* This method gets a template Item based on its uuid
*
@@ -83,7 +88,7 @@ public class ItemtemplateRestController {
throw new ResourceNotFoundException("Item with id: " + uuid + " not found");
}
if (templateItem.getTemplateItemOf() == null) {
if (itemTemplateItemOfLinkRepository.getTemplateItemOf(request, uuid, null, Projection.DEFAULT) == null) {
throw new ResourceNotFoundException("The item with id " + uuid + " is not a template item");
}

View File

@@ -12,20 +12,14 @@ import static org.dspace.core.Constants.COLLECTION;
import java.io.IOException;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
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.ConverterService;
import org.dspace.app.rest.exception.MethodNotAllowedException;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.link.HalLinkService;
import org.dspace.app.rest.model.CollectionRest;
import org.dspace.app.rest.model.MappedCollectionRestWrapper;
import org.dspace.app.rest.model.hateoas.MappedCollectionResourceWrapper;
import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.app.rest.utils.Utils;
import org.dspace.authorize.AuthorizeException;
@@ -36,14 +30,15 @@ import org.dspace.content.service.CollectionService;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
/**
* This RestController takes care of the retrieval, creation and deletion of MappedCollections
* This RestController takes care of the creation and deletion of MappedCollections.
* This class will typically receive a UUID that resolves to an Item and it'll perform logic on its collections
*/
@RestController
@@ -55,65 +50,12 @@ public class MappedCollectionRestController {
@Autowired
private ItemService itemService;
@Autowired
private ConverterService converter;
@Autowired
private CollectionService collectionService;
@Autowired
Utils utils;
@Autowired
private HalLinkService halLinkService;
/**
* This method will retrieve a List of Collections in which the item, that corresponds to the given UUID, resides
* The owning collection is not included in this list. It will transform the list of Collections to a list of
* CollectionRest objects and it'll then encapsulate these into a MappedCollectionResourceWrapper object
*
* curl -X GET http://<dspace.baseUrl>/api/core/item/{uuid}/mappedCollections
*
* Example:
* <pre>
* {@code
* curl -X GET http://<dspace.baseUrl>/api/core/items/8b632938-77c2-487c-81f0-e804f63e68e6/mappedCollections
* }
* </pre>
*
* @param uuid The UUID of the Item
* @param response The HttpServletResponse
* @param request The HttpServletRequest
* @param pageable The pagination object
* @return The Mapping CollectionResourceWrapper containing the appropriate CollectionRest objects
* @throws SQLException If something goes wrong
*/
@RequestMapping(method = {RequestMethod.GET, RequestMethod.HEAD})
public MappedCollectionResourceWrapper retrieve(@PathVariable UUID uuid, HttpServletResponse response,
HttpServletRequest request, Pageable pageable)
throws SQLException {
Context context = ContextUtil.obtainContext(request);
Item item = itemService.find(context, uuid);
List<Collection> collections = item.getCollections();
UUID owningCollectionUuid = item.getOwningCollection().getID();
List<CollectionRest> mappingCollectionRest = new LinkedList<>();
for (Collection collection : collections) {
if (collection.getID() != owningCollectionUuid) {
mappingCollectionRest.add(converter.toRest(collection, utils.obtainProjection()));
}
}
MappedCollectionRestWrapper mappingCollectionRestWrapper = new MappedCollectionRestWrapper();
mappingCollectionRestWrapper.setProjection(utils.obtainProjection());
mappingCollectionRestWrapper.setMappedCollectionRestList(mappingCollectionRest);
mappingCollectionRestWrapper.setItem(item);
MappedCollectionResourceWrapper mappingCollectionResourceWrapper =
converter.toResource(mappingCollectionRestWrapper);
return mappingCollectionResourceWrapper;
}
/**
* This method will add an Item to a Collection. The Collection object is encapsulated in the request due to the
* text/uri-list consumer and the Item UUID comes from the path in the URL
@@ -137,6 +79,7 @@ public class MappedCollectionRestController {
* @throws AuthorizeException If something goes wrong
*/
@RequestMapping(method = RequestMethod.POST, consumes = {"text/uri-list"})
@ResponseStatus(HttpStatus.NO_CONTENT)
public void createCollectionToItemRelation(@PathVariable UUID uuid,
HttpServletResponse response, HttpServletRequest request)
throws SQLException, AuthorizeException {
@@ -191,6 +134,7 @@ public class MappedCollectionRestController {
* @throws IOException If something goes wrong
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{collectionUuid}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteCollectionToItemRelation(@PathVariable UUID uuid, @PathVariable UUID collectionUuid,
HttpServletResponse response, HttpServletRequest request)
throws SQLException, AuthorizeException, IOException {

View File

@@ -1,113 +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;
import static org.dspace.app.rest.utils.RegexUtils.REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
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.ConverterService;
import org.dspace.app.rest.link.HalLinkService;
import org.dspace.app.rest.model.ItemRest;
import org.dspace.app.rest.model.MappedItemRestWrapper;
import org.dspace.app.rest.model.hateoas.MappedItemResourceWrapper;
import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.app.rest.utils.Utils;
import org.dspace.content.Collection;
import org.dspace.content.Item;
import org.dspace.content.service.CollectionService;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* This Controller will deal with request about the items that are mapped to the collection given in the request url
* Currently this only includes a GET method for all the items that are mapped to the given collection that do not
* have the given collection as their owning collection
*/
@RestController
@RequestMapping("/api/core/collections" + REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID + "/mappedItems")
public class MappedItemRestController {
private static final Logger log = Logger.getLogger(MappedItemRestController.class);
@Autowired
private CollectionService collectionService;
@Autowired
private ItemService itemService;
@Autowired
private ConverterService converter;
@Autowired
Utils utils;
@Autowired
private HalLinkService halLinkService;
/**
* This method will retrieve a List of Item objects that are mapped to the Collection given in the URL.
* These Item objects will be filtered out of their owning collection is the given collection, resulting in
* returning only items that belong to a different collection but are mapped to the given one.
* These Items are then encapsulated in a MappedItemResourceWrapper and returned
*
* curl -X GET http://<dspace.baseUrl>/api/core/collections/{uuid}/mappedItems
*
* Example:
* <pre>
* {@code
* curl -X GET http://<dspace.baseUrl>/api/core/collections/8b632938-77c2-487c-81f0-e804f63e68e6/mappedItems
* }
* </pre>
*
* @param uuid The UUID of the collection
* @param response The HttpServletResponse
* @param request The HttpServletRequest
* @param pageable The pagination object
* @return
* @throws Exception
*/
@RequestMapping(method = {RequestMethod.GET, RequestMethod.HEAD})
public MappedItemResourceWrapper retrieve(@PathVariable UUID uuid, HttpServletResponse response,
HttpServletRequest request, Pageable pageable) throws Exception {
Context context = ContextUtil.obtainContext(request);
Collection collection = collectionService.find(context, uuid);
Iterator<Item> itemIterator = itemService.findByCollectionMapping(context, collection, pageable.getPageSize(),
Math.toIntExact(pageable.getOffset()));
int totalElements = itemService.countByCollectionMapping(context, collection);
List<ItemRest> mappedItemRestList = new LinkedList<>();
while (itemIterator.hasNext()) {
Item item = itemIterator.next();
if (item.getOwningCollection().getID() != uuid) {
mappedItemRestList.add(converter.toRest(item, utils.obtainProjection()));
}
}
MappedItemRestWrapper mappedItemRestWrapper = new MappedItemRestWrapper();
mappedItemRestWrapper.setProjection(utils.obtainProjection());
mappedItemRestWrapper.setMappedItemRestList(mappedItemRestList);
mappedItemRestWrapper.setCollectionUuid(uuid);
MappedItemResourceWrapper mappedItemResourceWrapper =
new MappedItemResourceWrapper(mappedItemRestWrapper, utils, totalElements);
halLinkService.addLinks(mappedItemResourceWrapper, pageable);
return mappedItemResourceWrapper;
}
}

View File

@@ -81,7 +81,7 @@ public class RelationshipTypeRestController {
List<RelationshipType> list = relationshipTypeService.findByEntityType(context, entityType, -1, -1);
Page<RelationshipTypeRest> relationshipTypeRestPage = converter
.toRestPage(list, pageable, list.size(), utils.obtainProjection(true));
.toRestPage(list, pageable, list.size(), utils.obtainProjection());
Page<RelationshipTypeResource> relationshipTypeResources = relationshipTypeRestPage
.map(relationshipTypeRest -> new RelationshipTypeResource(relationshipTypeRest, utils));

View File

@@ -67,6 +67,7 @@ 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;
@@ -793,7 +794,16 @@ public class RestResourceController implements InitializingBean {
try {
if (Page.class.isAssignableFrom(linkMethod.getReturnType())) {
Page<? extends RestModel> pageResult = (Page<? extends RestAddressableModel>) linkMethod
.invoke(linkRepository, request, uuid, page, utils.obtainProjection(true));
.invoke(linkRepository, request, uuid, page, utils.obtainProjection());
if (pageResult == null) {
// Link repositories may throw an exception or return an empty page,
// but must never return null for a paged subresource.
log.error("Paged subresource link repository " + linkRepository.getClass()
+ " incorrectly returned null for request with id " + uuid);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return null;
}
Link link = null;
String querystring = request.getQueryString();
@@ -804,19 +814,30 @@ public class RestResourceController implements InitializingBean {
link = linkTo(this.getClass(), apiCategory, model).slash(uuid).slash(subpath).withSelfRel();
}
Page<HALResource> halResources = pageResult.map(object -> converter.toResource(object));
return assembler.toResource(halResources, link);
return new Resource(new EmbeddedPage(link.getHref(),
pageResult.map(converter::toResource), null, subpath));
} else {
RestModel object = (RestModel) linkMethod.invoke(linkRepository, request, uuid, page,
utils.obtainProjection());
Link link = linkTo(this.getClass(), apiCategory, model).slash(uuid).slash(subpath)
.withSelfRel();
HALResource tmpresult = converter.toResource(object);
tmpresult.add(link);
return tmpresult;
if (object == null) {
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
return null;
} else {
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);
} catch (InvocationTargetException e) {
if (e.getTargetException() instanceof RuntimeException) {
throw (RuntimeException) e.getTargetException();
} else {
throw new RuntimeException(e);
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
RestAddressableModel modelObject = repository.findById(uuid).orElse(null);

View File

@@ -48,11 +48,6 @@ public class BitstreamConverter extends DSpaceObjectConverter<Bitstream, Bitstre
checksum.setCheckSumAlgorithm(obj.getChecksumAlgorithm());
checksum.setValue(obj.getChecksum());
b.setCheckSum(checksum);
try {
b.setFormat(converter.toRest(obj.getFormat(null), projection));
} catch (SQLException e) {
throw new RuntimeException(e);
}
b.setSizeBytes(obj.getSizeBytes());
return b;
}

View File

@@ -7,11 +7,7 @@
*/
package org.dspace.app.rest.converter;
import java.util.stream.Collectors;
import org.dspace.app.rest.model.BitstreamRest;
import org.dspace.app.rest.model.BundleRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Bundle;
import org.springframework.stereotype.Component;
@@ -19,23 +15,6 @@ import org.springframework.stereotype.Component;
public class BundleConverter
extends DSpaceObjectConverter<Bundle, BundleRest> {
@Override
public BundleRest convert(Bundle bundle, Projection projection) {
BundleRest bundleRest = super.convert(bundle, projection);
bundleRest.setBitstreams(bundle.getBitstreams()
.stream()
.map(x -> (BitstreamRest) converter.toRest(x, projection))
.collect(Collectors.toList()));
if (bundle.getPrimaryBitstream() != null) {
BitstreamRest primaryBitstreamRest = converter.toRest(bundle.getPrimaryBitstream(), projection);
bundleRest.setPrimaryBitstream(primaryBitstreamRest);
}
return bundleRest;
}
@Override
protected BundleRest newInstance() {
return new BundleRest();

View File

@@ -7,13 +7,9 @@
*/
package org.dspace.app.rest.converter;
import org.apache.logging.log4j.Logger;
import org.dspace.app.rest.model.CollectionRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Bitstream;
import org.dspace.content.Collection;
import org.dspace.discovery.IndexableObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
@@ -23,24 +19,8 @@ import org.springframework.stereotype.Component;
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class CollectionConverter
extends DSpaceObjectConverter<org.dspace.content.Collection, org.dspace.app.rest.model.CollectionRest>
implements IndexableObjectConverter<Collection, CollectionRest> {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(CollectionConverter.class);
@Autowired
private ConverterService converter;
@Override
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, projection));
}
return col;
}
public class CollectionConverter extends DSpaceObjectConverter<Collection, CollectionRest>
implements IndexableObjectConverter<Collection, CollectionRest> {
@Override
protected CollectionRest newInstance() {

View File

@@ -7,17 +7,9 @@
*/
package org.dspace.app.rest.converter;
import java.util.ArrayList;
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;
import org.dspace.discovery.IndexableObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
@@ -28,40 +20,8 @@ import org.springframework.stereotype.Component;
*/
@Component
public class CommunityConverter
extends DSpaceObjectConverter<org.dspace.content.Community, org.dspace.app.rest.model.CommunityRest>
implements IndexableObjectConverter<Community, CommunityRest> {
@Autowired
private ConverterService converter;
@Override
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, projection));
}
List<Collection> collections = obj.getCollections();
List<CollectionRest> collectionsRest = new ArrayList<>();
if (collections != null) {
for (Collection col : collections) {
collectionsRest.add(converter.toRest(col, projection));
}
}
com.setCollections(collectionsRest);
List<Community> subCommunities = obj.getSubcommunities();
List<CommunityRest> communityRest = new ArrayList<>();
if (subCommunities != null) {
for (Community scom : subCommunities) {
CommunityRest scomrest = this.convert(scom, projection);
communityRest.add(scomrest);
}
}
com.setSubCommunities(communityRest);
return com;
}
extends DSpaceObjectConverter<Community, CommunityRest>
implements IndexableObjectConverter<Community, CommunityRest> {
@Override
protected CommunityRest newInstance() {
@@ -69,8 +29,8 @@ public class CommunityConverter
}
@Override
public Class<org.dspace.content.Community> getModelClass() {
return org.dspace.content.Community.class;
public Class<Community> getModelClass() {
return Community.class;
}
@Override

View File

@@ -7,19 +7,9 @@
*/
package org.dspace.app.rest.converter;
import java.sql.SQLException;
import java.util.ArrayList;
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;
import org.dspace.eperson.service.GroupService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
@@ -31,14 +21,6 @@ import org.springframework.stereotype.Component;
@Component
public class EPersonConverter extends DSpaceObjectConverter<EPerson, org.dspace.app.rest.model.EPersonRest> {
@Autowired
private ConverterService converter;
@Autowired
private GroupService groupService;
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(EPersonConverter.class);
@Override
public EPersonRest convert(EPerson obj, Projection projection) {
EPersonRest eperson = super.convert(obj, projection);
@@ -52,19 +34,6 @@ public class EPersonConverter extends DSpaceObjectConverter<EPerson, org.dspace.
return eperson;
}
public EPersonRest fromModelWithGroups(Context context, EPerson ePerson, Projection projection)
throws SQLException {
EPersonRest eperson = convert(ePerson, projection);
List<GroupRest> groups = new ArrayList<>();
for (Group g : groupService.allMemberGroups(context, ePerson)) {
groups.add(converter.toRest(g, projection));
}
eperson.setGroups(groups);
return eperson;
}
@Override
protected EPersonRest newInstance() {
return new EPersonRest();

View File

@@ -7,10 +7,6 @@
*/
package org.dspace.app.rest.converter;
import java.util.ArrayList;
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;
@@ -23,20 +19,12 @@ import org.springframework.stereotype.Component;
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class GroupConverter extends DSpaceObjectConverter<Group, org.dspace.app.rest.model.GroupRest> {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(GroupConverter.class);
public class GroupConverter extends DSpaceObjectConverter<Group, GroupRest> {
@Override
public GroupRest convert(Group obj, Projection projection) {
GroupRest epersongroup = super.convert(obj, projection);
epersongroup.setPermanent(obj.isPermanent());
List<GroupRest> groups = new ArrayList<GroupRest>();
for (Group g : obj.getMemberGroups()) {
groups.add(convert(g, projection));
}
epersongroup.setGroups(groups);
return epersongroup;
}

View File

@@ -8,14 +8,11 @@
package org.dspace.app.rest.converter;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.logging.log4j.Logger;
import org.dspace.app.rest.model.BundleRest;
import org.dspace.app.rest.model.ItemRest;
import org.dspace.app.rest.model.MetadataValueList;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Collection;
import org.dspace.content.Item;
import org.dspace.content.MetadataValue;
import org.dspace.content.service.ItemService;
@@ -49,19 +46,6 @@ public class ItemConverter
item.setDiscoverable(obj.isDiscoverable());
item.setWithdrawn(obj.isWithdrawn());
item.setLastModified(obj.getLastModified());
Collection owningCollection = obj.getOwningCollection();
if (owningCollection != null) {
item.setOwningCollection(converter.toRest(owningCollection, projection));
}
Collection templateItemOf = obj.getTemplateItemOf();
if (templateItemOf != null) {
item.setTemplateItemOf(converter.toRest(templateItemOf, projection));
}
item.setBundles(obj.getBundles()
.stream()
.map(x -> (BundleRest) converter.toRest(x, projection))
.collect(Collectors.toList()));
List<MetadataValue> fullList = itemService.getMetadata(obj, Item.ANY, Item.ANY, Item.ANY, Item.ANY, true);
MetadataValueList metadataValues = new MetadataValueList(fullList);

View File

@@ -57,23 +57,17 @@ public class DSpaceResourceHalLinkFactory extends HalLinkFactory<DSpaceResource,
if (StringUtils.isBlank(linkRest.method())) {
Object linkedObject = readMethod.invoke(data);
if (linkedObject instanceof RestAddressableModel
&& linkRest.linkClass().isAssignableFrom(linkedObject.getClass())) {
if (linkedObject instanceof RestAddressableModel) {
linkToSubResource = utils
.linkToSingleResource((RestAddressableModel) linkedObject, name);
}
if (linkedObject != null || !linkRest.linkOptional() || !linkRest.embedOptional()) {
if (linkRest.linkOptional() && linkRest.embedOptional()
&& !halResource.getContent().getProjection()
.allowOptionalLink(halResource, linkRest)) {
continue; // projection disallows this optional method-level link
}
halResource.add(linkToSubResource);
if (!halResource.getContent().getProjection().allowLinking(halResource, linkRest)) {
continue; // projection disallows this optional method-level link
}
halResource.add(linkToSubResource);
}
} else if (RestModel.class.isAssignableFrom(readMethod.getReturnType())) {

View File

@@ -1,44 +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.link;
import java.util.LinkedList;
import org.dspace.app.rest.model.MappedCollectionRestWrapper;
import org.dspace.app.rest.model.hateoas.MappedCollectionResourceWrapper;
import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.Link;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;
/**
* This class' purpose is to add links to the MappedCollectionResourceWrapper objects
*/
@Component
public class MappedCollectionResourceWrapperHalLinkFactory
extends MappedCollectionRestHalLinkFactory<MappedCollectionResourceWrapper> {
protected void addLinks(MappedCollectionResourceWrapper halResource, Pageable pageable, LinkedList<Link> list)
throws Exception {
MappedCollectionRestWrapper mappingCollectionRestWrapper = halResource.getContent();
if (mappingCollectionRestWrapper != null) {
UriComponentsBuilder uriBuilderSelfLink = uriBuilder(getMethodOn()
.retrieve(
mappingCollectionRestWrapper.getItem().getID(),
null, null, null));
list.add(buildLink(Link.REL_SELF, uriBuilderSelfLink.build().toString()));
}
}
protected Class<MappedCollectionResourceWrapper> getResourceClass() {
return MappedCollectionResourceWrapper.class;
}
}

View File

@@ -1,23 +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.link;
import org.dspace.app.rest.MappedCollectionRestController;
/**
* This class acts as an abstract class for the MappedCollectionResourceWrapperHalLinkFactory to inherit from
* so it already has the Controller defined
*/
public abstract class MappedCollectionRestHalLinkFactory<T>
extends HalLinkFactory<T, MappedCollectionRestController> {
@Override
protected Class<MappedCollectionRestController> getControllerClass() {
return MappedCollectionRestController.class;
}
}

View File

@@ -1,57 +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.link;
import java.util.LinkedList;
import org.dspace.app.rest.model.MappedItemRestWrapper;
import org.dspace.app.rest.model.hateoas.EmbeddedPageHeader;
import org.dspace.app.rest.model.hateoas.ItemResource;
import org.dspace.app.rest.model.hateoas.MappedItemResourceWrapper;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.Link;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;
/**
* This class' purpose is to add links to the MappedItemResourceWrapper objects
*/
@Component
public class MappedItemResourceWrapperHalLinkFactory
extends MappedItemRestHalLinkFactory<MappedItemResourceWrapper> {
protected void addLinks(MappedItemResourceWrapper halResource, Pageable pageable, LinkedList<Link> list)
throws Exception {
MappedItemRestWrapper mappingItemRestWrapper = halResource.getContent();
if (mappingItemRestWrapper != null) {
PageImpl<ItemResource> page = new PageImpl<>(halResource.getItemResources(), pageable,
halResource.getTotalElements());
halResource.setPageHeader(new EmbeddedPageHeader(getSelfLink(mappingItemRestWrapper, pageable),
page, true));
}
}
private String getSelfLink(MappedItemRestWrapper mappingItemRestWrapper, Pageable pageable) throws Exception {
if (mappingItemRestWrapper != null) {
UriComponentsBuilder uriBuilderSelfLink = uriBuilder(getMethodOn()
.retrieve(
mappingItemRestWrapper.getCollectionUuid(),
null, null, pageable));
return uriBuilderSelfLink.build().toString();
}
return null;
}
protected Class<MappedItemResourceWrapper> getResourceClass() {
return MappedItemResourceWrapper.class;
}
}

View File

@@ -1,22 +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.link;
import org.dspace.app.rest.MappedItemRestController;
/**
* This class acts as an abstract class for the MappedItemResourceWrapperHalLinkFactory to inherit from
* so it already has the Controller defined
*/
public abstract class MappedItemRestHalLinkFactory<T> extends HalLinkFactory<T, MappedItemRestController> {
@Override
protected Class<MappedItemRestController> getControllerClass() {
return MappedItemRestController.class;
}
}

View File

@@ -56,7 +56,7 @@ public class AuthenticationStatusRest extends BaseObjectRest<Integer> {
}
}
@LinkRest(linkClass = EPersonRest.class, name = "eperson", linkOptional = true)
@LinkRest(name = "eperson")
@JsonIgnore
public EPersonRest getEPersonRest() {
return ePersonRest;

View File

@@ -16,17 +16,11 @@ import org.dspace.app.rest.RestResourceController;
*/
@LinksRest(links = {
@LinkRest(name = AuthorityRest.ENTRIES,
linkClass = AuthorityEntryRest.class,
method = "query",
embedOptional = true,
linkOptional = true
method = "query"
),
@LinkRest(
name = AuthorityRest.ENTRY,
linkClass = AuthorityEntryRest.class,
method = "getResource",
embedOptional = true,
linkOptional = true
method = "getResource"
)
})
public class AuthorityRest extends BaseObjectRest<String> {

View File

@@ -15,17 +15,26 @@ import com.fasterxml.jackson.annotation.JsonProperty.Access;
*
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@LinksRest(links = {
@LinkRest(
name = BitstreamRest.BUNDLE,
method = "getBundle"
),
@LinkRest(
name = BitstreamRest.FORMAT,
method = "getFormat"
)
})
public class BitstreamRest extends DSpaceObjectRest {
public static final String PLURAL_NAME = "bitstreams";
public static final String NAME = "bitstream";
public static final String CATEGORY = RestAddressableModel.CORE;
public static final String BUNDLE = "bundle";
public static final String FORMAT = "format";
private String bundleName;
// avoid to serialize this object inline as we want a full resource embedded
// TODO extends this annotation to provide information about lazy loading
// and projection behavior
@JsonProperty(access = Access.WRITE_ONLY)
private BitstreamFormatRest format;
private Long sizeBytes;
private CheckSumRest checkSum;
// sequenceId is READ_ONLY because it is assigned by the ItemService (as it must be unique within an Item)
@@ -40,14 +49,6 @@ public class BitstreamRest extends DSpaceObjectRest {
this.bundleName = bundleName;
}
public BitstreamFormatRest getFormat() {
return format;
}
public void setFormat(BitstreamFormatRest format) {
this.format = format;
}
public Long getSizeBytes() {
return sizeBytes;
}

View File

@@ -21,16 +21,11 @@ import org.dspace.app.rest.RestResourceController;
@LinksRest(links = {
@LinkRest(
name = BrowseIndexRest.ITEMS,
linkClass = ItemRest.class,
method = "listBrowseItems",
embedOptional = true
method = "listBrowseItems"
),
@LinkRest(
name = BrowseIndexRest.ENTRIES,
linkClass = BrowseEntryRest.class,
method = "listBrowseEntries",
embedOptional = true,
linkOptional = true
method = "listBrowseEntries"
)
})
public class BrowseIndexRest extends BaseObjectRest<String> {

View File

@@ -7,25 +7,31 @@
*/
package org.dspace.app.rest.model;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.dspace.content.Bitstream;
/**
* The Bundle REST Resource
*
* @author Jelle Pelgrims (jelle.pelgrims at atmire.com)
*/
@LinksRest(links = {
@LinkRest(
name = BundleRest.BITSTREAMS,
method = "getBitstreams"
),
@LinkRest(
name = BundleRest.PRIMARY_BITSTREAM,
method = "getPrimaryBitstream"
)
})
public class BundleRest extends DSpaceObjectRest {
public static final String NAME = "bundle";
public static final String PLURAL_NAME = "bundles";
public static final String CATEGORY = RestAddressableModel.CORE;
private BitstreamRest primaryBitstream;
private List<BitstreamRest> bitstreams;
public static final String BITSTREAMS = "bitstreams";
public static final String PRIMARY_BITSTREAM = "primaryBitstream";
@Override
@JsonIgnore
@@ -41,25 +47,4 @@ public class BundleRest extends DSpaceObjectRest {
public String getType() {
return NAME;
}
@JsonIgnore
@LinkRest(linkClass = Bitstream.class)
public BitstreamRest getPrimaryBitstream() {
return primaryBitstream;
}
public void setPrimaryBitstream(BitstreamRest primaryBitstream) {
this.primaryBitstream = primaryBitstream;
}
@LinkRest(linkClass = Bitstream.class)
@JsonIgnore
public List<BitstreamRest> getBitstreams() {
return bitstreams;
}
public void setBitstreams(List<BitstreamRest> bitstreams) {
this.bitstreams = bitstreams;
}
}

View File

@@ -7,7 +7,6 @@
*/
package org.dspace.app.rest.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
@@ -16,31 +15,28 @@ 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",
embedOptional = true,
linkOptional = true
)
@LinkRest(
name = CollectionRest.LICENSE,
method = "getLicense"
),
@LinkRest(
name = CollectionRest.LOGO,
method = "getLogo"
),
@LinkRest(
name = CollectionRest.MAPPED_ITEMS,
method = "getMappedItems"
)
})
public class CollectionRest extends DSpaceObjectRest {
public static final String NAME = "collection";
public static final String PLURAL_NAME = "collections";
public static final String CATEGORY = RestAddressableModel.CORE;
public static final String LICENSE = "license";
public static final String HARVEST = "harvester";
public static final String DEFAULT_ACCESS_CONDITIONS = "defaultAccessConditions";
@JsonIgnore
private BitstreamRest logo;
public BitstreamRest getLogo() {
return logo;
}
public void setLogo(BitstreamRest logo) {
this.logo = logo;
}
public static final String LICENSE = "license";
public static final String LOGO = "logo";
public static final String MAPPED_ITEMS = "mappedItems";
@Override
public String getCategory() {
@@ -52,5 +48,4 @@ public class CollectionRest extends DSpaceObjectRest {
public String getType() {
return NAME;
}
}

View File

@@ -7,9 +7,6 @@
*/
package org.dspace.app.rest.model;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
@@ -17,45 +14,28 @@ import com.fasterxml.jackson.annotation.JsonProperty;
*
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@LinksRest(links = {
@LinkRest(
name = CommunityRest.COLLECTIONS,
method = "getCollections"
),
@LinkRest(
name = CommunityRest.LOGO,
method = "getLogo"
),
@LinkRest(
name = CommunityRest.SUBCOMMUNITIES,
method = "getSubcommunities"
)
})
public class CommunityRest extends DSpaceObjectRest {
public static final String NAME = "community";
public static final String PLURAL_NAME = "communities";
public static final String CATEGORY = RestAddressableModel.CORE;
@JsonIgnore
private BitstreamRest logo;
private List<CollectionRest> collections;
@LinkRest(linkClass = CollectionRest.class)
@JsonIgnore
public List<CollectionRest> getCollections() {
return collections;
}
public void setCollections(List<CollectionRest> collections) {
this.collections = collections;
}
private List<CommunityRest> subcommunities;
@LinkRest(linkClass = CommunityRest.class)
@JsonIgnore
public List<CommunityRest> getSubcommunities() {
return subcommunities;
}
public void setSubCommunities(List<CommunityRest> subcommunities) {
this.subcommunities = subcommunities;
}
public BitstreamRest getLogo() {
return logo;
}
public void setLogo(BitstreamRest logo) {
this.logo = logo;
}
public static final String COLLECTIONS = "collections";
public static final String LOGO = "logo";
public static final String SUBCOMMUNITIES = "subcommunities";
@Override
public String getCategory() {
@@ -67,5 +47,4 @@ public class CommunityRest extends DSpaceObjectRest {
public String getType() {
return NAME;
}
}

View File

@@ -8,9 +8,7 @@
package org.dspace.app.rest.model;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonProperty.Access;
import org.dspace.app.rest.RestResourceController;
@@ -21,9 +19,18 @@ import org.dspace.app.rest.RestResourceController;
*
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@LinksRest(links = {
@LinkRest(
name = EPersonRest.GROUPS,
method = "getGroups"
)
})
public class EPersonRest extends DSpaceObjectRest {
public static final String NAME = "eperson";
public static final String CATEGORY = RestAddressableModel.EPERSON;
public static final String GROUPS = "groups";
private String netid;
private Date lastActive;
@@ -39,8 +46,6 @@ public class EPersonRest extends DSpaceObjectRest {
@JsonProperty(access = Access.WRITE_ONLY)
private String password;
private List<GroupRest> groups;
@Override
@JsonProperty(access = Access.READ_ONLY)
public String getType() {
@@ -103,16 +108,6 @@ public class EPersonRest extends DSpaceObjectRest {
this.password = password;
}
@LinkRest(linkClass = GroupRest.class)
@JsonIgnore
public List<GroupRest> getGroups() {
return groups;
}
public void setGroups(List<GroupRest> groups) {
this.groups = groups;
}
@Override
public String getCategory() {
return CATEGORY;

View File

@@ -7,8 +7,6 @@
*/
package org.dspace.app.rest.model;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.dspace.app.rest.RestResourceController;
@@ -19,17 +17,22 @@ import org.dspace.app.rest.RestResourceController;
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@LinksRest(links = {
@LinkRest(
name = GroupRest.GROUPS,
method = "getGroups"
)
})
public class GroupRest extends DSpaceObjectRest {
public static final String NAME = "group";
public static final String CATEGORY = RestAddressableModel.EPERSON;
public static final String GROUPS = "groups";
private String name;
private boolean permanent;
private List<GroupRest> groups;
@Override
public String getCategory() {
return CATEGORY;
@@ -56,16 +59,6 @@ public class GroupRest extends DSpaceObjectRest {
this.permanent = permanent;
}
@JsonIgnore
@LinkRest(linkClass = GroupRest.class)
public List<GroupRest> getGroups() {
return groups;
}
public void setGroups(List<GroupRest> groups) {
this.groups = groups;
}
@Override
@JsonIgnore
public Class getController() {

View File

@@ -156,7 +156,7 @@ public class HarvestedCollectionRest extends BaseObjectRest<Integer> {
this.lastHarvested = lastHarvested;
}
@LinkRest(linkClass = HarvesterMetadataRest.class, name = "harvestermetadata", linkOptional = true)
@LinkRest(name = "harvestermetadata")
@JsonIgnore
public HarvesterMetadataRest getMetadataConfigs() {
return metadata_configs;

View File

@@ -8,9 +8,7 @@
package org.dspace.app.rest.model;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
@@ -19,28 +17,42 @@ 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
)
@LinkRest(
name = ItemRest.BUNDLES,
method = "getBundles"
),
@LinkRest(
name = ItemRest.MAPPED_COLLECTIONS,
method = "getMappedCollections"
),
@LinkRest(
name = ItemRest.OWNING_COLLECTION,
method = "getOwningCollection"
),
@LinkRest(
name = ItemRest.RELATIONSHIPS,
method = "getRelationships"
),
@LinkRest(
name = ItemRest.TEMPLATE_ITEM_OF,
method = "getTemplateItemOf"
)
})
public class ItemRest extends DSpaceObjectRest {
public static final String NAME = "item";
public static final String PLURAL_NAME = "items";
public static final String CATEGORY = RestAddressableModel.CORE;
public static final String BUNDLES = "bundles";
public static final String MAPPED_COLLECTIONS = "mappedCollections";
public static final String OWNING_COLLECTION = "owningCollection";
public static final String RELATIONSHIPS = "relationships";
public static final String TEMPLATE_ITEM_OF = "templateItemOf";
private boolean inArchive = false;
private boolean discoverable = false;
private boolean withdrawn = false;
private Date lastModified = new Date();
@JsonIgnore
private CollectionRest owningCollection;
@JsonIgnore
private CollectionRest templateItemOf;
List<BundleRest> bundles;
@Override
public String getCategory() {
@@ -84,30 +96,4 @@ public class ItemRest extends DSpaceObjectRest {
public void setLastModified(Date lastModified) {
this.lastModified = lastModified;
}
public CollectionRest getOwningCollection() {
return owningCollection;
}
public void setOwningCollection(CollectionRest owningCollection) {
this.owningCollection = owningCollection;
}
public CollectionRest getTemplateItemOf() {
return templateItemOf;
}
public void setTemplateItemOf(CollectionRest templateItemOf) {
this.templateItemOf = templateItemOf;
}
@LinkRest(linkClass = BundleRest.class)
@JsonIgnore
public List<BundleRest> getBundles() {
return bundles;
}
public void setBundles(List<BundleRest> bundles) {
this.bundles = bundles;
}
}

View File

@@ -13,15 +13,12 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.dspace.app.rest.model.hateoas.HALResource;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.LinkRestRepository;
import org.dspace.app.rest.utils.Utils;
import org.springframework.stereotype.Component;
/**
* Class or method-level annotation to control linking/embedding behavior when a {@link RestModel}
* is wrapped as a {@link HALResource}
* Class or method-level annotation to provide information about linked/embedded subresources of a {@link RestModel}.
*
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@@ -55,45 +52,4 @@ public @interface LinkRest {
* @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.
* <p>
* If false (the default), it means the resource will always be embedded unless the {@link LinkRestRepository}
* forbids it via {@link LinkRestRepository#isEmbeddableRelation(Object, String)}.
* </p>
* <p>
* 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)}.
* </p>
*
* @return whether embedding is optional.
*/
boolean embedOptional() default false;
/**
* Tells whether linking the resource indicated by this link is optional.
* <p>
* If false (the default), it means the resource will always be linked.
* </p>
* <p>
* If true, it means the resource will only be linked if:
* <ul>
* <li> The resource is embedded, or</li>
* <li> 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)}</li>
* </ul>
* </p>
*
* @return whether linking is optional.
*/
boolean linkOptional() default false;
}

View File

@@ -1,53 +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.model;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.dspace.app.rest.MappedCollectionRestController;
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 extends RestAddressableModel {
@JsonIgnore
private List<CollectionRest> mappedCollectionRestList;
@JsonIgnore
private Item item;
public List<CollectionRest> getMappedCollectionRestList() {
return mappedCollectionRestList;
}
public void setMappedCollectionRestList(List<CollectionRest> mappedCollectionRestList) {
this.mappedCollectionRestList = mappedCollectionRestList;
}
public String getCategory() {
return "core";
}
public Class getController() {
return MappedCollectionRestController.class;
}
public String getType() {
return "collection";
}
public Item getItem() {
return item;
}
public void setItem(Item item) {
this.item = item;
}
}

View File

@@ -1,53 +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.model;
import java.util.List;
import java.util.UUID;
import com.fasterxml.jackson.annotation.JsonIgnore;
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 extends RestAddressableModel {
@JsonIgnore
private List<ItemRest> mappedItemRestList;
private UUID collectionUuid;
public UUID getCollectionUuid() {
return collectionUuid;
}
public void setCollectionUuid(UUID collectionUuid) {
this.collectionUuid = collectionUuid;
}
public List<ItemRest> getMappedItemRestList() {
return mappedItemRestList;
}
public void setMappedItemRestList(List<ItemRest> mappedItemRestList) {
this.mappedItemRestList = mappedItemRestList;
}
public String getCategory() {
return "core";
}
public Class getController() {
return MappedItemRestController.class;
}
public String getType() {
return "collection";
}
}

View File

@@ -56,7 +56,7 @@ public class RelationshipRest extends BaseObjectRest<Integer> {
this.leftId = leftId;
}
@LinkRest(linkClass = RelationshipTypeRest.class)
@LinkRest
@JsonIgnore
public RelationshipTypeRest getRelationshipType() {
return relationshipType;

View File

@@ -123,7 +123,7 @@ public class RelationshipTypeRest extends BaseObjectRest<Integer> {
this.rightMaxCardinality = rightMaxCardinality;
}
@LinkRest(linkClass = EntityTypeRest.class)
@LinkRest
@JsonIgnore
public EntityTypeRest getLeftType() {
return leftType;
@@ -133,7 +133,7 @@ public class RelationshipTypeRest extends BaseObjectRest<Integer> {
this.leftType = leftType;
}
@LinkRest(linkClass = EntityTypeRest.class)
@LinkRest
@JsonIgnore
public EntityTypeRest getRightType() {
return rightType;

View File

@@ -17,6 +17,8 @@ import org.dspace.app.rest.projection.Projection;
*/
public abstract class RestAddressableModel implements RestModel {
private int embedLevel = 0;
private Projection projection = Projection.DEFAULT;
@JsonIgnore
@@ -25,6 +27,15 @@ public abstract class RestAddressableModel implements RestModel {
@JsonIgnore
public abstract Class getController();
@JsonIgnore
public int getEmbedLevel() {
return embedLevel;
}
public void setEmbedLevel(int embedLevel) {
this.embedLevel = embedLevel;
}
@JsonIgnore
public Projection getProjection() {
return projection;

View File

@@ -48,7 +48,7 @@ public class SubmissionDefinitionRest extends BaseObjectRest<String> {
this.panels = panels;
}
@LinkRest(name = SubmissionSectionRest.ATTRIBUTE_NAME, linkClass = SubmissionSectionRest.class)
@LinkRest(name = SubmissionSectionRest.ATTRIBUTE_NAME)
@JsonIgnore
public List<SubmissionSectionRest> getPanels() {
return panels;
@@ -77,7 +77,7 @@ public class SubmissionDefinitionRest extends BaseObjectRest<String> {
return CATEGORY;
}
@LinkRest(linkClass = CollectionRest.class)
@LinkRest
@JsonIgnore
public List<CollectionRest> getCollections() {
return collections;

View File

@@ -22,6 +22,5 @@ public class BitstreamResource extends DSpaceResource<BitstreamRest> {
public BitstreamResource(BitstreamRest bs, Utils utils) {
super(bs, utils);
add(utils.linkToSubResource(bs, "content"));
add(utils.linkToSubResource(bs, "bundle"));
}
}

View File

@@ -21,9 +21,7 @@ import org.dspace.app.rest.utils.Utils;
public class CollectionResource extends DSpaceResource<CollectionRest> {
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"));
add(utils.linkToSubResource(collection, "itemtemplate"));
}
}

View File

@@ -21,6 +21,5 @@ import org.dspace.app.rest.utils.Utils;
public class ItemResource extends DSpaceResource<ItemRest> {
public ItemResource(ItemRest item, Utils utils) {
super(item, utils);
add(utils.linkToSubResource(item, "mappedCollections"));
}
}

View File

@@ -1,38 +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.model.hateoas;
import java.util.LinkedList;
import java.util.List;
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;
/**
* This class will act as a HALResource object for the MappedCollectionRestWrapper data object and will transform
* this REST data object into a proper HAL Resource to be returned by the endpoint
*/
public class MappedCollectionResourceWrapper extends HALResource<MappedCollectionRestWrapper> {
@JsonIgnore
private List<CollectionResource> collectionResources = new LinkedList<>();
public MappedCollectionResourceWrapper(MappedCollectionRestWrapper content, Utils utils) {
super(content);
addEmbeds(content, utils);
}
private void addEmbeds(final MappedCollectionRestWrapper data, final Utils utils) {
for (CollectionRest collectionRest : data.getMappedCollectionRestList()) {
collectionResources.add(new CollectionResource(collectionRest, utils));
}
embedResource("mappedCollections", collectionResources);
}
}

View File

@@ -1,55 +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.model.hateoas;
import java.util.LinkedList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.dspace.app.rest.model.ItemRest;
import org.dspace.app.rest.model.MappedItemRestWrapper;
import org.dspace.app.rest.utils.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class will act as a HALResource object for the MappedItemRestWrapper data object and will transform
* this REST data object into a proper HAL Resource to be returned by the endpoint
*/
public class MappedItemResourceWrapper extends HALResource<MappedItemRestWrapper> {
private static final Logger log = LoggerFactory.getLogger(MappedItemResourceWrapper.class);
@JsonIgnore
private List<ItemResource> itemResources;
@JsonIgnore
private Integer totalElements;
public MappedItemResourceWrapper(MappedItemRestWrapper content, Utils utils,
Integer totalElements) {
super(content);
embed(utils);
this.totalElements = totalElements;
}
private void embed(Utils utils) {
List<ItemResource> itemResources = new LinkedList<>();
for (ItemRest itemRest : getContent().getMappedItemRestList()) {
itemResources.add(new ItemResource(itemRest, utils));
}
this.itemResources = itemResources;
embedResource("mappedItems", itemResources);
}
public List<ItemResource> getItemResources() {
return itemResources;
}
public Integer getTotalElements() {
return totalElements;
}
}

View File

@@ -12,7 +12,9 @@ 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.
* Abstract base class for projections.
*
* By default, this does no transformation, and allows linking but not embedding of all subresources.
*/
public abstract class AbstractProjection implements Projection {
@@ -32,12 +34,12 @@ public abstract class AbstractProjection implements Projection {
}
@Override
public boolean allowOptionalEmbed(HALResource halResource, LinkRest linkRest) {
return true;
public boolean allowEmbedding(HALResource halResource, LinkRest linkRest) {
return false;
}
@Override
public boolean allowOptionalLink(HALResource halResource, LinkRest linkRest) {
public boolean allowLinking(HALResource halResource, LinkRest linkRest) {
return true;
}
}

View File

@@ -8,7 +8,9 @@
package org.dspace.app.rest.projection;
/**
* The default projection, which has no effect.
* The default projection.
*
* This does no transformation, and allows linking but not embedding of all subresources.
*/
public class DefaultProjection extends AbstractProjection {

View File

@@ -12,20 +12,24 @@ 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.
* Catch-all projection that allows embedding of all subresources.
*/
@Component
public class ListProjection extends AbstractProjection {
public class FullProjection extends AbstractProjection {
public final static String NAME = "list";
public final static String NAME = "full";
@Override
public String getName() {
return NAME;
}
@Override
public boolean allowOptionalEmbed(HALResource halResource, LinkRest linkRest) {
return false;
public boolean allowEmbedding(HALResource halResource, LinkRest linkRest) {
return true;
}
@Override
public boolean allowLinking(HALResource halResource, LinkRest linkRest) {
return true;
}
}

View File

@@ -43,19 +43,17 @@ import org.springframework.web.bind.annotation.RestController;
* via {@link #transformModel(Object)}.</li>
* <li> After it is converted to a {@link RestModel}, the projection may modify it
* via {@link #transformRest(RestModel)}.</li>
* <li> 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)}.</li>
* <li> During conversion to a {@link HALResource}, the projection may opt in to certain annotation-discovered
* HAL embeds and links via {@link #allowEmbedding(HALResource, LinkRest)}
* and {@link #allowLinking(HALResource, LinkRest)}</li>
* <li> After conversion to a {@link HALResource}, the projection may modify it
* via {@link #transformResource(HALResource)}.</li>
* </ul>
*
* <h2>How a projection is chosen</h2>
*
* 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.
* When a REST request is made, the projection argument, if present, is used to look up the projection to use,
* by name. If no argument is present, {@link DefaultProjection} will be used.
*/
public interface Projection {
@@ -108,28 +106,30 @@ public interface Projection {
<T extends HALResource> T transformResource(T halResource);
/**
* Tells whether this projection permits the embedding of a particular optionally-embeddable related resource.
* Tells whether this projection permits the embedding of a particular embeddable subresource.
*
* 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}.
* This gives the projection an opportunity to opt in to to certain embeds, by returning {@code true}.
*
* Note: If this method returns {@code true} for a given subresource,
* it will be automatically linked regardless of what {@link #allowLinking(HALResource, LinkRest)} returns.
*
* @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);
boolean allowEmbedding(HALResource halResource, LinkRest linkRest);
/**
* Tells whether this projection permits the linking of a particular optionally-linkable related resource.
* Tells whether this projection permits the linking of a particular linkable subresource.
*
* 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}.
* This gives the projection an opportunity to opt in to to certain links, by returning {@code true}.
*
* @param halResource the resource from which the embed may or may not be made.
* Note: If {@link #allowEmbedding(HALResource, LinkRest)} returns {@code true} for a given subresource,
* it will be automatically linked regardless of what this method returns.
*
* @param halResource the resource from which the link 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);
boolean allowLinking(HALResource halResource, LinkRest linkRest);
}

View File

@@ -11,6 +11,7 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
@@ -50,12 +51,12 @@ public class AuthorityEntryLinkRepository extends AbstractDSpaceRestRepository
private AuthorityUtils authorityUtils;
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public Page<AuthorityEntryRest> query(HttpServletRequest request, String name,
Pageable pageable, Projection projection) {
public Page<AuthorityEntryRest> query(@Nullable HttpServletRequest request, String name,
@Nullable Pageable optionalPageable, Projection projection) {
Context context = obtainContext();
String query = request.getParameter("query");
String metadata = request.getParameter("metadata");
String uuidCollectìon = request.getParameter("uuid");
String query = request == null ? null : request.getParameter("query");
String metadata = request == null ? null : request.getParameter("metadata");
String uuidCollectìon = request == null ? null : request.getParameter("uuid");
Collection collection = null;
if (StringUtils.isNotBlank(uuidCollectìon)) {
try {
@@ -65,6 +66,7 @@ public class AuthorityEntryLinkRepository extends AbstractDSpaceRestRepository
}
}
List<AuthorityEntryRest> results = new ArrayList<>();
Pageable pageable = utils.getPageable(optionalPageable);
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], "_");
@@ -77,5 +79,4 @@ public class AuthorityEntryLinkRepository extends AbstractDSpaceRestRepository
}
return new PageImpl<>(results, pageable, results.size());
}
}

View File

@@ -50,4 +50,11 @@ public class AuthorityEntryValueLinkRepository extends AbstractDSpaceRestReposit
return authorityUtils.convertEntry(choice, name, projection);
}
/**
* Not embeddable because this is not currently a pageable subresource.
*/
@Override
public boolean isEmbeddableRelation(Object data, String name) {
return false;
}
}

View File

@@ -50,7 +50,7 @@ public class AuthorityRestRepository extends DSpaceRestRepository<AuthorityRest,
public Page<AuthorityRest> findAll(Context context, Pageable pageable) {
Set<String> authoritiesName = cas.getChoiceAuthoritiesNames();
List<AuthorityRest> results = new ArrayList<>();
Projection projection = utils.obtainProjection(true);
Projection projection = utils.obtainProjection();
for (String authorityName : authoritiesName) {
ChoiceAuthority source = cas.getChoiceAuthorityByAuthorityName(authorityName);
AuthorityRest result = authorityUtils.convertAuthority(source, authorityName, projection);

View File

@@ -0,0 +1,56 @@
/**
* 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.UUID;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.BitstreamRest;
import org.dspace.app.rest.model.BundleRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Bitstream;
import org.dspace.content.service.BitstreamService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "bundle" subresource of an individual bitstream.
*/
@Component(BitstreamRest.CATEGORY + "." + BitstreamRest.NAME + "." + BitstreamRest.BUNDLE)
public class BitstreamBundleLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
BitstreamService bitstreamService;
@PreAuthorize("hasPermission(#bitstreamId, 'BITSTREAM', 'READ')")
public BundleRest getBundle(@Nullable HttpServletRequest request,
UUID bitstreamId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
Bitstream bitstream = bitstreamService.find(context, bitstreamId);
if (bitstream == null) {
throw new ResourceNotFoundException("No such bitstream: " + bitstreamId);
}
if (bitstream.getBundles().isEmpty()) {
return null;
}
return converter.toRest(bitstream.getBundles().get(0), projection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,56 @@
/**
* 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.UUID;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.BitstreamFormatRest;
import org.dspace.app.rest.model.BitstreamRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Bitstream;
import org.dspace.content.service.BitstreamService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "format" subresource of an individual bitstream.
*/
@Component(BitstreamRest.CATEGORY + "." + BitstreamRest.NAME + "." + BitstreamRest.FORMAT)
public class BitstreamFormatLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
BitstreamService bitstreamService;
@PreAuthorize("hasPermission(#bitstreamId, 'BITSTREAM', 'READ')")
public BitstreamFormatRest getFormat(@Nullable HttpServletRequest request,
UUID bitstreamId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
Bitstream bitstream = bitstreamService.find(context, bitstreamId);
if (bitstream == null) {
throw new ResourceNotFoundException("No such bitstream: " + bitstreamId);
}
if (bitstream.getFormat(context) == null) {
return null;
}
return converter.toRest(bitstream.getFormat(context), projection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -60,7 +60,7 @@ public class BitstreamFormatRestRepository extends DSpaceRestRepository<Bitstrea
public Page<BitstreamFormatRest> findAll(Context context, Pageable pageable) {
try {
List<BitstreamFormat> bit = bitstreamFormatService.findAll(context);
return converter.toRestPage(utils.getPage(bit, pageable), utils.obtainProjection(true));
return converter.toRestPage(utils.getPage(bit, pageable), utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}

View File

@@ -108,7 +108,7 @@ public class BitstreamRestRepository extends DSpaceObjectRestRepository<Bitstrea
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
Projection projection = utils.obtainProjection(true);
Projection projection = utils.obtainProjection();
Page<BitstreamRest> page = new PageImpl<>(bit, pageable, total)
.map((bitstream) -> converter.toRest(bitstream, projection));
return page;

View File

@@ -45,7 +45,7 @@ public class BrowseIndexRestRepository extends DSpaceRestRepository<BrowseIndexR
public Page<BrowseIndexRest> findAll(Context context, Pageable pageable) {
try {
List<BrowseIndex> indexes = Arrays.asList(BrowseIndex.getBrowseIndices());
return converter.toRestPage(indexes, pageable, indexes.size(), utils.obtainProjection(true));
return converter.toRestPage(indexes, pageable, indexes.size(), utils.obtainProjection());
} catch (BrowseException e) {
throw new RuntimeException(e.getMessage(), e);
}

View File

@@ -0,0 +1,61 @@
/**
* 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.UUID;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.BitstreamRest;
import org.dspace.app.rest.model.BundleRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Bitstream;
import org.dspace.content.Bundle;
import org.dspace.content.service.BitstreamService;
import org.dspace.content.service.BundleService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "bitstreams" subresource of an individual bundle.
*/
@Component(BundleRest.CATEGORY + "." + BundleRest.NAME + "." + BundleRest.BITSTREAMS)
public class BundleBitstreamLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
BitstreamService bitstreamService;
@Autowired
BundleService bundleService;
@PreAuthorize("hasPermission(#bundleId, 'BUNDLE', 'READ')")
public Page<BitstreamRest> getBitstreams(@Nullable HttpServletRequest request,
UUID bundleId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
Bundle bundle = bundleService.find(context, bundleId);
if (bundle == null) {
throw new ResourceNotFoundException("No such bundle: " + bundleId);
}
Pageable pageable = utils.getPageable(optionalPageable);
Page<Bitstream> page = utils.getPage(bundle.getBitstreams(), pageable);
return converter.toRestPage(page, projection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,56 @@
/**
* 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.UUID;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.BitstreamRest;
import org.dspace.app.rest.model.BundleRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Bundle;
import org.dspace.content.service.BundleService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "primaryBitstream" subresource of an individual bundle.
*/
@Component(BundleRest.CATEGORY + "." + BundleRest.NAME + "." + BundleRest.PRIMARY_BITSTREAM)
public class BundlePrimaryBitstreamLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
BundleService bundleService;
@PreAuthorize("hasPermission(#bundleId, 'BUNDLE', 'READ')")
public BitstreamRest getPrimaryBitstream(@Nullable HttpServletRequest request,
UUID bundleId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
Bundle bundle = bundleService.find(context, bundleId);
if (bundle == null) {
throw new ResourceNotFoundException("No such bundle: " + bundleId);
}
if (bundle.getPrimaryBitstream() == null) {
return null;
}
return converter.toRest(bundle.getPrimaryBitstream(), projection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -107,7 +107,7 @@ public class ClaimedTaskRestRepository extends DSpaceRestRepository<ClaimedTaskR
if (authorizeService.isAdmin(context) || userID.equals(currentUser.getID())) {
EPerson ep = epersonService.find(context, userID);
List<ClaimedTask> tasks = claimedTaskService.findByEperson(context, ep);
return converter.toRestPage(utils.getPage(tasks, pageable), utils.obtainProjection(true));
return converter.toRestPage(utils.getPage(tasks, pageable), utils.obtainProjection());
} else {
throw new RESTAuthorizationException("Only administrators can search for claimed tasks of other users");
}

View File

@@ -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.UUID;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.CollectionRest;
import org.dspace.app.rest.model.LicenseRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Collection;
import org.dspace.content.service.CollectionService;
import org.dspace.core.Context;
import org.dspace.core.service.LicenseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "license" subresource of an individual collection.
*
* @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it)
*/
@Component(CollectionRest.CATEGORY + "." + CollectionRest.NAME + "." + CollectionRest.LICENSE)
public class CollectionLicenseLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
CollectionService collectionService;
@Autowired
LicenseService licenseService;
@PreAuthorize("hasPermission(#collectionId, 'COLLECTION', 'READ')")
public LicenseRest getLicense(@Nullable HttpServletRequest request,
UUID collectionId,
@Nullable Pageable pageable,
Projection projection) {
try {
Context context = obtainContext();
Collection collection = collectionService.find(context, collectionId);
if (collection == null) {
throw new ResourceNotFoundException("No such collection: " + collectionId);
}
LicenseRest licenseRest = new LicenseRest();
String text = collection.getLicenseCollection();
if (StringUtils.isNotBlank(text)) {
licenseRest.setCustom(true);
licenseRest.setText(text);
} else {
licenseRest.setText(licenseService.getDefaultSubmissionLicense());
}
return licenseRest;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,56 @@
/**
* 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.UUID;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.BitstreamRest;
import org.dspace.app.rest.model.CollectionRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Collection;
import org.dspace.content.service.CollectionService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "logo" subresource of an individual collection.
*/
@Component(CollectionRest.CATEGORY + "." + CollectionRest.NAME + "." + CollectionRest.LOGO)
public class CollectionLogoLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
CollectionService collectionService;
@PreAuthorize("hasPermission(#collectionId, 'COLLECTION', 'READ')")
public BitstreamRest getLogo(@Nullable HttpServletRequest request,
UUID collectionId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
Collection collection = collectionService.find(context, collectionId);
if (collection == null) {
throw new ResourceNotFoundException("No such collection: " + collectionId);
}
if (collection.getLogo() == null) {
return null;
}
return converter.toRest(collection.getLogo(), projection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,66 @@
/**
* 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.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.CollectionRest;
import org.dspace.app.rest.model.ItemRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Collection;
import org.dspace.content.Item;
import org.dspace.content.service.CollectionService;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "mappedItems" subresource of an individual collection.
*/
@Component(CollectionRest.CATEGORY + "." + CollectionRest.NAME + "." + CollectionRest.MAPPED_ITEMS)
public class CollectionMappedItemLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
CollectionService collectionService;
@Autowired
ItemService itemService;
@PreAuthorize("hasPermission(#collectionId, 'COLLECTION', 'READ')")
public Page<ItemRest> getMappedItems(@Nullable HttpServletRequest request,
UUID collectionId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
Collection collection = collectionService.find(context, collectionId);
if (collection == null) {
throw new ResourceNotFoundException("No such collection: " + collectionId);
}
int total = itemService.countByCollectionMapping(context, collection);
Pageable pageable = utils.getPageable(optionalPageable);
List<Item> items = new ArrayList<>();
itemService.findByCollectionMapping(context, collection, pageable.getPageSize(),
Math.toIntExact(pageable.getOffset())).forEachRemaining(items::add);
return converter.toRestPage(items, pageable, total, projection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -97,7 +97,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
long total = cs.countTotal(context);
List<Collection> collections = cs.findAll(context, pageable.getPageSize(),
Math.toIntExact(pageable.getOffset()));
return converter.toRestPage(collections, pageable, total, utils.obtainProjection(true));
return converter.toRestPage(collections, pageable, total, utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
@@ -115,7 +115,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
+ " not found");
}
List<Collection> collections = cs.findAuthorized(context, com, Constants.ADD);
return converter.toRestPage(utils.getPage(collections, pageable), utils.obtainProjection(true));
return converter.toRestPage(utils.getPage(collections, pageable), utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
@@ -126,7 +126,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
try {
Context context = obtainContext();
List<Collection> collections = cs.findAuthorizedOptimized(context, Constants.ADD);
return converter.toRestPage(utils.getPage(collections, pageable), utils.obtainProjection(true));
return converter.toRestPage(utils.getPage(collections, pageable), utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}

View File

@@ -0,0 +1,57 @@
/**
* 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.model.CollectionRest;
import org.dspace.app.rest.model.CommunityRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Collection;
import org.dspace.content.Community;
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.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "collections" subresource of an individual community.
*/
@Component(CommunityRest.CATEGORY + "." + CommunityRest.NAME + "." + CommunityRest.COLLECTIONS)
public class CommunityCollectionLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
CommunityService communityService;
@PreAuthorize("hasPermission(#communityId, 'COMMUNITY', 'READ')")
public Page<CollectionRest> getCollections(@Nullable HttpServletRequest request,
UUID communityId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
Community community = communityService.find(context, communityId);
if (community == null) {
throw new ResourceNotFoundException("No such community: " + communityId);
}
List<Collection> collections = community.getCollections();
return converter.toRestPage(utils.getPage(collections, optionalPageable), projection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,56 @@
/**
* 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.UUID;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.BitstreamRest;
import org.dspace.app.rest.model.CommunityRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Community;
import org.dspace.content.service.CommunityService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "logo" subresource of an individual community.
*/
@Component(CommunityRest.CATEGORY + "." + CommunityRest.NAME + "." + CommunityRest.LOGO)
public class CommunityLogoLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
CommunityService communityService;
@PreAuthorize("hasPermission(#communityId, 'COMMUNITY', 'READ')")
public BitstreamRest getLogo(@Nullable HttpServletRequest request,
UUID communityId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
Community community = communityService.find(context, communityId);
if (community == null) {
throw new ResourceNotFoundException("No such community: " + communityId);
}
if (community.getLogo() == null) {
return null;
}
return converter.toRest(community.getLogo(), projection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -151,7 +151,7 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
long total = cs.countTotal(context);
List<Community> communities = cs.findAll(context, pageable.getPageSize(),
Math.toIntExact(pageable.getOffset()));
return converter.toRestPage(communities, pageable, total, utils.obtainProjection(true));
return converter.toRestPage(communities, pageable, total, utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
@@ -163,7 +163,7 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
public Page<CommunityRest> findAllTop(Pageable pageable) {
try {
List<Community> communities = cs.findAllTop(obtainContext());
return converter.toRestPage(utils.getPage(communities, pageable), utils.obtainProjection(true));
return converter.toRestPage(utils.getPage(communities, pageable), utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
@@ -182,7 +182,7 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
CommunityRest.CATEGORY + "." + CommunityRest.NAME + " with id: " + parentCommunity + " not found");
}
List<Community> subCommunities = community.getSubcommunities();
return converter.toRestPage(utils.getPage(subCommunities, pageable), utils.obtainProjection(true));
return converter.toRestPage(utils.getPage(subCommunities, pageable), utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}

View File

@@ -0,0 +1,55 @@
/**
* 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.model.CommunityRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Community;
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.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "subcommunities" subresource of an individual community.
*/
@Component(CommunityRest.CATEGORY + "." + CommunityRest.NAME + "." + CommunityRest.SUBCOMMUNITIES)
public class CommunitySubcommunityLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
CommunityService communityService;
@PreAuthorize("hasPermission(#communityId, 'COMMUNITY', 'READ')")
public Page<CommunityRest> getSubcommunities(@Nullable HttpServletRequest request,
UUID communityId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
Community community = communityService.find(context, communityId);
if (community == null) {
throw new ResourceNotFoundException("No such community: " + communityId);
}
List<Community> subcommunities = community.getSubcommunities();
return converter.toRestPage(utils.getPage(subcommunities, optionalPageable), projection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,60 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.repository;
import java.sql.SQLException;
import java.util.UUID;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
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;
import org.dspace.eperson.service.EPersonService;
import org.dspace.eperson.service.GroupService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "groups" subresource of an individual eperson.
*/
@Component(EPersonRest.CATEGORY + "." + EPersonRest.NAME + "." + EPersonRest.GROUPS)
public class EPersonGroupLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
EPersonService epersonService;
@Autowired
GroupService groupService;
@PreAuthorize("hasPermission(#epersonId, 'EPERSON', 'READ')")
public Page<GroupRest> getGroups(@Nullable HttpServletRequest request,
UUID epersonId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
EPerson eperson = epersonService.find(context, epersonId);
if (eperson == null) {
throw new ResourceNotFoundException("No such eperson: " + epersonId);
}
Page<Group> groups = utils.getPage(groupService.allMemberGroups(context, eperson), optionalPageable);
return converter.toRestPage(groups, projection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -114,7 +114,7 @@ public class EPersonRestRepository extends DSpaceObjectRestRepository<EPerson, E
long total = es.countTotal(context);
List<EPerson> epersons = es.findAll(context, EPerson.EMAIL, pageable.getPageSize(),
Math.toIntExact(pageable.getOffset()));
return converter.toRestPage(epersons, pageable, total, utils.obtainProjection(true));
return converter.toRestPage(epersons, pageable, total, utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
@@ -138,7 +138,7 @@ public class EPersonRestRepository extends DSpaceObjectRestRepository<EPerson, E
long total = es.searchResultCount(context, q);
List<EPerson> epersons = es.search(context, q, Math.toIntExact(pageable.getOffset()),
Math.toIntExact(pageable.getOffset() + pageable.getPageSize()));
return converter.toRestPage(epersons, pageable, total, utils.obtainProjection(true));
return converter.toRestPage(epersons, pageable, total, utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}

View File

@@ -44,7 +44,7 @@ public class EntityTypeRestRepository extends DSpaceRestRepository<EntityTypeRes
public Page<EntityTypeRest> findAll(Context context, Pageable pageable) {
try {
List<EntityType> entityTypes = entityTypeService.findAll(context);
return converter.toRestPage(utils.getPage(entityTypes, pageable), utils.obtainProjection(true));
return converter.toRestPage(utils.getPage(entityTypes, pageable), utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}

View File

@@ -74,7 +74,7 @@ public class ExternalSourceRestRepository extends DSpaceRestRepository<ExternalS
pageable.getPageSize());
int numberOfResults = externalDataService.getNumberOfResults(externalSourceName, query);
return converter.toRestPage(externalDataObjects, pageable, numberOfResults,
utils.obtainProjection(true));
utils.obtainProjection());
}
@Override
@@ -91,7 +91,7 @@ public class ExternalSourceRestRepository extends DSpaceRestRepository<ExternalS
public Page<ExternalSourceRest> findAll(Context context, Pageable pageable) {
List<ExternalDataProvider> externalSources = externalDataService.getExternalDataProviders();
return converter.toRestPage(externalSources, pageable, externalSources.size(),
utils.obtainProjection(true));
utils.obtainProjection());
}
public Class<ExternalSourceRest> getDomainClass() {

View File

@@ -0,0 +1,54 @@
/**
* 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.UUID;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.GroupRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.core.Context;
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.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "groups" subresource of an individual group.
*/
@Component(GroupRest.CATEGORY + "." + GroupRest.NAME + "." + GroupRest.GROUPS)
public class GroupGroupLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
GroupService groupService;
@PreAuthorize("hasPermission(#groupId, 'GROUP', 'READ')")
public Page<GroupRest> getGroups(@Nullable HttpServletRequest request,
UUID groupId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
Group group = groupService.find(context, groupId);
if (group == null) {
throw new ResourceNotFoundException("No such group: " + groupId);
}
Page<Group> groups = utils.getPage(group.getMemberGroups(), optionalPageable);
return converter.toRestPage(groups, projection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -100,7 +100,7 @@ public class GroupRestRepository extends DSpaceObjectRestRepository<Group, Group
long total = gs.countTotal(context);
List<Group> groups = gs.findAll(context, null, pageable.getPageSize(),
Math.toIntExact(pageable.getOffset()));
return converter.toRestPage(groups, pageable, total, utils.obtainProjection(true));
return converter.toRestPage(groups, pageable, total, utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}

View File

@@ -0,0 +1,56 @@
/**
* 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.UUID;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.BundleRest;
import org.dspace.app.rest.model.ItemRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Bundle;
import org.dspace.content.Item;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "bundles" subresource of an individual item.
*/
@Component(ItemRest.CATEGORY + "." + ItemRest.NAME + "." + ItemRest.BUNDLES)
public class ItemBundleLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
ItemService itemService;
@PreAuthorize("hasPermission(#itemId, 'ITEM', 'READ')")
public Page<BundleRest> getBundles(@Nullable HttpServletRequest request,
UUID itemId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
Item item = itemService.find(context, itemId);
if (item == null) {
throw new ResourceNotFoundException("No such item: " + itemId);
}
Page<Bundle> bundlePage = utils.getPage(item.getBundles(), optionalPageable);
return converter.toRestPage(bundlePage, projection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,60 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.repository;
import java.sql.SQLException;
import java.util.UUID;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.CollectionRest;
import org.dspace.app.rest.model.ItemRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Collection;
import org.dspace.content.Item;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "mappedCollections" subresource of an individual item.
*/
@Component(ItemRest.CATEGORY + "." + ItemRest.NAME + "." + ItemRest.MAPPED_COLLECTIONS)
public class ItemMappedCollectionLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
ItemService itemService;
@PreAuthorize("hasPermission(#itemId, 'ITEM', 'READ')")
public Page<CollectionRest> getMappedCollections(@Nullable HttpServletRequest request,
UUID itemId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
Item item = itemService.find(context, itemId);
if (item == null) {
throw new ResourceNotFoundException("No such item: " + itemId);
}
UUID owningCollectionId = item.getOwningCollection() == null ? null : item.getOwningCollection().getID();
Page<Collection> mappedCollectionPage = utils.getPage(item.getCollections().stream()
.filter((collection) -> !collection.getID().equals(owningCollectionId))
.collect(Collectors.toList()), optionalPageable);
return converter.toRestPage(mappedCollectionPage, projection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,56 @@
/**
* 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.UUID;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.CollectionRest;
import org.dspace.app.rest.model.ItemRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Item;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "owningCollection" subresource of an individual item.
*/
@Component(ItemRest.CATEGORY + "." + ItemRest.NAME + "." + ItemRest.OWNING_COLLECTION)
public class ItemOwningCollectionLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
ItemService itemService;
@PreAuthorize("hasPermission(#itemId, 'ITEM', 'READ')")
public CollectionRest getOwningCollection(@Nullable HttpServletRequest request,
UUID itemId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
Item item = itemService.find(context, itemId);
if (item == null) {
throw new ResourceNotFoundException("No such item: " + itemId);
}
if (item.getOwningCollection() == null) {
return null;
}
return converter.toRest(item.getOwningCollection(), projection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -23,8 +23,9 @@ 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.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
@@ -40,22 +41,21 @@ public class ItemRelationshipLinkRepository extends AbstractDSpaceRestRepository
@Autowired
ItemService itemService;
//@PreAuthorize("hasPermission(#itemId, 'ITEM', 'READ')")
public Page<RelationshipRest> getItemRelationships(@Nullable HttpServletRequest request,
UUID itemId,
@Nullable Pageable optionalPageable,
Projection projection) {
@PreAuthorize("hasPermission(#itemId, 'ITEM', 'READ')")
public Page<RelationshipRest> getRelationships(@Nullable HttpServletRequest request,
UUID itemId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
Item item = itemService.find(context, itemId);
if (item == null) {
return null;
throw new ResourceNotFoundException("No such item: " + itemId);
}
Pageable pageable = optionalPageable != null ? optionalPageable : new PageRequest(0, 20);
Integer limit = pageable == null ? null : pageable.getPageSize();
Integer offset = pageable == null ? null : Math.toIntExact(pageable.getOffset());
int total = relationshipService.countByItem(context, item);
List<Relationship> relationships = relationshipService.findByItem(context, item, limit, offset);
Pageable pageable = utils.getPageable(optionalPageable);
List<Relationship> relationships = relationshipService.findByItem(context, item,
pageable.getPageSize(), Math.toIntExact(pageable.getOffset()));
return converter.toRestPage(relationships, pageable, total, projection);
} catch (SQLException e) {
throw new RuntimeException(e);

View File

@@ -128,7 +128,7 @@ public class ItemRestRepository extends DSpaceObjectRestRepository<Item, ItemRes
while (it.hasNext()) {
items.add(it.next());
}
return converter.toRestPage(items, pageable, total, utils.obtainProjection(true));
return converter.toRestPage(items, pageable, total, utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
@@ -149,12 +149,19 @@ public class ItemRestRepository extends DSpaceObjectRestRepository<Item, ItemRes
Context context = obtainContext();
if (itemRest.getWithdrawn() != item.isWithdrawn()) {
if (itemRest.getWithdrawn()) {
if (item.getTemplateItemOf() != null) {
throw new UnprocessableEntityException("A template item cannot be withdrawn.");
}
itemService.withdraw(context, item);
} else {
itemService.reinstate(context, item);
}
}
if (itemRest.getDiscoverable() != item.isDiscoverable()) {
if (itemRest.getDiscoverable() && item.getTemplateItemOf() != null) {
throw new UnprocessableEntityException("A template item cannot be discoverable.");
}
item.setDiscoverable(itemRest.getDiscoverable());
itemService.update(context, item);
}

View File

@@ -0,0 +1,56 @@
/**
* 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.UUID;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.CollectionRest;
import org.dspace.app.rest.model.ItemRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Item;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "templateItemOf" subresource of an individual item.
*/
@Component(ItemRest.CATEGORY + "." + ItemRest.NAME + "." + ItemRest.TEMPLATE_ITEM_OF)
public class ItemTemplateItemOfLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
ItemService itemService;
@PreAuthorize("hasPermission(#itemId, 'ITEM', 'READ')")
public CollectionRest getTemplateItemOf(@Nullable HttpServletRequest request,
UUID itemId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
Item item = itemService.find(context, itemId);
if (item == null) {
throw new ResourceNotFoundException("No such item: " + itemId);
}
if (item.getTemplateItemOf() == null) {
return null;
}
return converter.toRest(item.getTemplateItemOf(), projection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -1,64 +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.repository;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.CollectionRest;
import org.dspace.app.rest.model.LicenseRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Collection;
import org.dspace.content.service.CollectionService;
import org.dspace.core.Context;
import org.dspace.core.service.LicenseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Controller for exposition of license
*
* @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it)
*/
@Component(CollectionRest.CATEGORY + "." + CollectionRest.NAME + "." + CollectionRest.LICENSE)
public class LicenseRestLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
CollectionService collectionService;
@Autowired
LicenseService licenseService;
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public LicenseRest getLicenseCollection(HttpServletRequest request, UUID uuid, Pageable pageable,
Projection projection)
throws Exception {
Context context = obtainContext();
Collection collection = collectionService.find(context, uuid);
LicenseRest licenseRest = new LicenseRest();
String text = collection.getLicenseCollection();
if (StringUtils.isNotBlank(text)) {
licenseRest.setCustom(true);
licenseRest.setText(text);
} else {
licenseRest.setText(licenseService.getDefaultSubmissionLicense());
}
return licenseRest;
}
@Override
public boolean isEmbeddableRelation(Object data, String name) {
return false;
}
}

View File

@@ -71,7 +71,7 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository<MetadataFi
public Page<MetadataFieldRest> findAll(Context context, Pageable pageable) {
try {
List<MetadataField> metadataFields = metadataFieldService.findAll(context);
return converter.toRestPage(utils.getPage(metadataFields, pageable), utils.obtainProjection(true));
return converter.toRestPage(utils.getPage(metadataFields, pageable), utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
@@ -87,7 +87,7 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository<MetadataFi
return null;
}
List<MetadataField> metadataFields = metadataFieldService.findAllInSchema(context, schema);
return converter.toRestPage(utils.getPage(metadataFields, pageable), utils.obtainProjection(true));
return converter.toRestPage(utils.getPage(metadataFields, pageable), utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}

View File

@@ -63,7 +63,7 @@ public class MetadataSchemaRestRepository extends DSpaceRestRepository<MetadataS
public Page<MetadataSchemaRest> findAll(Context context, Pageable pageable) {
try {
List<MetadataSchema> metadataSchemas = metadataSchemaService.findAll(context);
return converter.toRestPage(utils.getPage(metadataSchemas, pageable), utils.obtainProjection(true));
return converter.toRestPage(utils.getPage(metadataSchemas, pageable), utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}

View File

@@ -101,7 +101,7 @@ public class PoolTaskRestRepository extends DSpaceRestRepository<PoolTaskRest, I
if (authorizeService.isAdmin(context) || userID.equals(currentUser.getID())) {
EPerson ep = epersonService.find(context, userID);
List<PoolTask> tasks = poolTaskService.findByEperson(context, ep);
return converter.toRestPage(utils.getPage(tasks, pageable), utils.obtainProjection(true));
return converter.toRestPage(utils.getPage(tasks, pageable), utils.obtainProjection());
} else {
throw new RESTAuthorizationException("Only administrators can search for pool tasks of other users");
}

View File

@@ -54,7 +54,7 @@ public class ProcessRestRepository extends DSpaceRestRepository<ProcessRest, Int
int total = processService.countTotal(context);
List<Process> processes = processService.findAll(context, pageable.getPageSize(),
Math.toIntExact(pageable.getOffset()));
return converter.toRestPage(processes, pageable, total, utils.obtainProjection(true));
return converter.toRestPage(processes, pageable, total, utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}

View File

@@ -86,7 +86,7 @@ public class RelationshipRestRepository extends DSpaceRestRepository<Relationshi
long total = relationshipService.countTotal(context);
List<Relationship> relationships = relationshipService.findAll(context,
pageable.getPageSize(), Math.toIntExact(pageable.getOffset()));
return converter.toRestPage(relationships, pageable, total, utils.obtainProjection(true));
return converter.toRestPage(relationships, pageable, total, utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
@@ -367,6 +367,6 @@ public class RelationshipRestRepository extends DSpaceRestRepository<Relationshi
}
}
return converter.toRestPage(relationships, pageable, total, utils.obtainProjection(true));
return converter.toRestPage(relationships, pageable, total, utils.obtainProjection());
}
}

View File

@@ -41,7 +41,7 @@ public class RelationshipTypeRestRepository extends DSpaceRestRepository<Relatio
public Page<RelationshipTypeRest> findAll(Context context, Pageable pageable) {
try {
List<RelationshipType> relationshipTypes = relationshipTypeService.findAll(context);
return converter.toRestPage(utils.getPage(relationshipTypes, pageable), utils.obtainProjection(true));
return converter.toRestPage(utils.getPage(relationshipTypes, pageable), utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}

View File

@@ -137,7 +137,7 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository<ResourceP
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
return converter.toRestPage(resourcePolisies, pageable, total, utils.obtainProjection(true));
return converter.toRestPage(resourcePolisies, pageable, total, utils.obtainProjection());
}
/**
@@ -181,7 +181,7 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository<ResourceP
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
return converter.toRestPage(resourcePolisies, pageable, total, utils.obtainProjection(true));
return converter.toRestPage(resourcePolisies, pageable, total, utils.obtainProjection());
}
/**
@@ -228,7 +228,7 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository<ResourceP
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
return converter.toRestPage(resourcePolisies, pageable, total, utils.obtainProjection(true));
return converter.toRestPage(resourcePolisies, pageable, total, utils.obtainProjection());
}
@Override
@@ -344,4 +344,4 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository<ResourceP
throw new RuntimeException("Unable to patch ResourcePolicy with id = " + id, e);
}
}
}
}

View File

@@ -69,7 +69,7 @@ public class ScriptRestRepository extends DSpaceRestRepository<ScriptRest, Strin
@Override
public Page<ScriptRest> findAll(Context context, Pageable pageable) {
List<DSpaceRunnable> dSpaceRunnables = scriptService.getDSpaceRunnables(context);
return converter.toRestPage(utils.getPage(dSpaceRunnables, pageable), utils.obtainProjection(true));
return converter.toRestPage(utils.getPage(dSpaceRunnables, pageable), utils.obtainProjection());
}
@Override

View File

@@ -61,7 +61,7 @@ public class SiteRestRepository extends DSpaceObjectRestRepository<Site, SiteRes
public Page<SiteRest> findAll(Context context, Pageable pageable) {
try {
List<Site> sites = Arrays.asList(sitesv.findSite(context));
return converter.toRestPage(sites, pageable, 1L, utils.obtainProjection(true));
return converter.toRestPage(sites, pageable, 1L, utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}

View File

@@ -57,7 +57,7 @@ public class SubmissionDefinitionRestRepository extends DSpaceRestRepository<Sub
int total = submissionConfigReader.countSubmissionConfigs();
List<SubmissionConfig> subConfs = submissionConfigReader.getAllSubmissionConfigs(
pageable.getPageSize(), Math.toIntExact(pageable.getOffset()));
return converter.toRestPage(subConfs, pageable, total, utils.obtainProjection(true));
return converter.toRestPage(subConfs, pageable, total, utils.obtainProjection());
}
@PreAuthorize("hasAuthority('AUTHENTICATED')")

View File

@@ -25,8 +25,7 @@ import org.springframework.stereotype.Component;
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component(SubmissionFormRest.CATEGORY + "." + SubmissionFormRest.NAME)
public class SubmissionFormRestRepository extends DSpaceRestRepository<SubmissionFormRest, String>
implements LinkRestRepository {
public class SubmissionFormRestRepository extends DSpaceRestRepository<SubmissionFormRest, String> {
private DCInputsReader inputReader;
@@ -56,7 +55,7 @@ public class SubmissionFormRestRepository extends DSpaceRestRepository<Submissio
long total = inputReader.countInputs();
List<DCInputSet> subConfs = inputReader.getAllInputs(pageable.getPageSize(),
Math.toIntExact(pageable.getOffset()));
return converter.toRestPage(subConfs, pageable, total, utils.obtainProjection(true));
return converter.toRestPage(subConfs, pageable, total, utils.obtainProjection());
} catch (DCInputsReaderException e) {
throw new IllegalStateException(e.getMessage(), e);
}

View File

@@ -62,7 +62,7 @@ public class SubmissionPanelRestRepository extends DSpaceRestRepository<Submissi
stepConfs.add(step);
}
}
return converter.toRestPage(stepConfs, pageable, total, utils.obtainProjection(true));
return converter.toRestPage(stepConfs, pageable, total, utils.obtainProjection());
}
@Override

View File

@@ -40,8 +40,7 @@ import org.springframework.stereotype.Component;
* @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it)
*/
@Component(SubmissionUploadRest.CATEGORY + "." + SubmissionUploadRest.NAME)
public class SubmissionUploadRestRepository extends DSpaceRestRepository<SubmissionUploadRest, String>
implements LinkRestRepository {
public class SubmissionUploadRestRepository extends DSpaceRestRepository<SubmissionUploadRest, String> {
private static final Logger log = org.apache.logging.log4j.LogManager
.getLogger(SubmissionUploadRestRepository.class);
@@ -81,7 +80,7 @@ public class SubmissionUploadRestRepository extends DSpaceRestRepository<Submiss
List<SubmissionConfig> subConfs = new ArrayList<SubmissionConfig>();
subConfs = submissionConfigReader.getAllSubmissionConfigs(pageable.getPageSize(),
Math.toIntExact(pageable.getOffset()));
Projection projection = utils.obtainProjection(true);
Projection projection = utils.obtainProjection();
List<SubmissionUploadRest> results = new ArrayList<>();
for (SubmissionConfig config : subConfs) {
for (int i = 0; i < config.getNumberOfSteps(); i++) {

View File

@@ -116,7 +116,7 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository<WorkflowIte
try {
long total = wis.countAll(context);
List<XmlWorkflowItem> witems = wis.findAll(context, pageable.getPageNumber(), pageable.getPageSize());
return converter.toRestPage(witems, pageable, total, utils.obtainProjection(true));
return converter.toRestPage(witems, pageable, total, utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
@@ -131,7 +131,7 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository<WorkflowIte
long total = wis.countBySubmitter(context, ep);
List<XmlWorkflowItem> witems = wis.findBySubmitter(context, ep, pageable.getPageNumber(),
pageable.getPageSize());
return converter.toRestPage(witems, pageable, total, utils.obtainProjection(true));
return converter.toRestPage(witems, pageable, total, utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}

View File

@@ -142,7 +142,7 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
long total = wis.countTotal(context);
List<WorkspaceItem> witems = wis.findAll(context, pageable.getPageSize(),
Math.toIntExact(pageable.getOffset()));
return converter.toRestPage(witems, pageable, total, utils.obtainProjection(true));
return converter.toRestPage(witems, pageable, total, utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
@@ -158,7 +158,7 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
long total = wis.countByEPerson(context, ep);
List<WorkspaceItem> witems = wis.findByEPerson(context, ep, pageable.getPageSize(),
Math.toIntExact(pageable.getOffset()));
return converter.toRestPage(witems, pageable, total, utils.obtainProjection(true));
return converter.toRestPage(witems, pageable, total, utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}

View File

@@ -9,7 +9,6 @@ package org.dspace.app.rest.repository.patch.factories.impl;
import org.apache.log4j.Logger;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.ItemRest;
import org.dspace.app.rest.model.patch.Operation;
import org.springframework.stereotype.Component;
@@ -30,17 +29,10 @@ public class ItemDiscoverableReplaceOperation extends ReplacePatchOperation<Item
private static final Logger log = Logger.getLogger(ItemDiscoverableReplaceOperation.class);
@Override
public ItemRest replace(ItemRest item, Operation operation) {
Boolean discoverable = getBooleanOperationValue(operation.getValue());
if (discoverable) {
if (item.getTemplateItemOf() != null) {
throw new UnprocessableEntityException("A template item cannot be discoverable.");
}
}
item.setDiscoverable(discoverable);
item.setDiscoverable(getBooleanOperationValue(operation.getValue()));
return item;
}

View File

@@ -37,9 +37,6 @@ public class ItemWithdrawReplaceOperation extends ReplacePatchOperation<ItemRest
// This is a request to withdraw the item.
if (withdraw) {
if (item.getTemplateItemOf() != null) {
throw new UnprocessableEntityException("A template item cannot be withdrawn.");
}
// The item is currently not withdrawn and also not archived. Is this a possible situation?
if (!item.getWithdrawn() && !item.getInArchive()) {
throw new UnprocessableEntityException("Cannot withdraw item when it is not in archive.");

View File

@@ -57,7 +57,6 @@ 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.DefaultProjection;
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;
@@ -91,7 +90,15 @@ public class Utils {
private static final Logger log = Logger.getLogger(Utils.class);
private static final int EMBEDDED_PAGE_SIZE = 20;
/**
* The default page size, if unspecified in the request.
*/
private static final int DEFAULT_PAGE_SIZE = 20;
/**
* The maximum number of embed levels to allow.
*/
private static final int EMBED_MAX_LEVELS = 2;
@Autowired
ApplicationContext applicationContext;
@@ -111,7 +118,8 @@ public class Utils {
/** Cache to support fast lookups of LinkRest method annotation information. */
private Map<Method, Optional<LinkRest>> linkAnnotationForMethod = new HashMap<>();
public <T> Page<T> getPage(List<T> fullContents, Pageable pageable) {
public <T> Page<T> getPage(List<T> fullContents, @Nullable Pageable optionalPageable) {
Pageable pageable = getPageable(optionalPageable);
int total = fullContents.size();
List<T> pageContent = null;
if (pageable.getOffset() > total) {
@@ -127,6 +135,16 @@ public class Utils {
}
}
/**
* Convenience method to get a default pageable instance if needed.
*
* @param optionalPageable the existing pageable instance, may be null.
* @return the existing instance if it is not null, a default pageable instance otherwise.
*/
public Pageable getPageable(@Nullable Pageable optionalPageable) {
return optionalPageable != null ? optionalPageable : new PageRequest(0, DEFAULT_PAGE_SIZE);
}
public Link linkToSingleResource(DSpaceResource r, String rel) {
RestAddressableModel data = r.getContent();
return linkToSingleResource(data, rel);
@@ -420,22 +438,6 @@ 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.
@@ -444,11 +446,10 @@ public class Utils {
* @throws IllegalArgumentException if the request specifies an unknown projection name.
*/
public Projection obtainProjection() {
return obtainProjection(false);
String projectionName = requestService.getCurrentRequest().getServletRequest().getParameter("projection");
return converter.getProjection(projectionName);
}
/**
* Adds embeds or links for all class-level LinkRel annotations for which embeds or links are allowed.
*
@@ -458,10 +459,10 @@ public class Utils {
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)) {
if (projection.allowEmbedding(halResource, linkRest)) {
embedRelFromRepository(halResource, linkRest.name(), link, linkRest);
halResource.add(link); // unconditionally link if embedding was allowed
} else if (!linkRest.linkOptional() || projection.allowOptionalLink(halResource, linkRest)) {
} else if (projection.allowLinking(halResource, linkRest)) {
halResource.add(link);
}
});
@@ -477,7 +478,8 @@ public class Utils {
}
/**
* Embeds a rel whose value comes from a {@link LinkRestRepository}.
* Embeds a rel whose value comes from a {@link LinkRestRepository}, if the maximum embed level has not
* been exceeded yet.
* <p>
* 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.
@@ -486,7 +488,7 @@ public class Utils {
* before calling this method.
* </p>
*
* @param resource the resource.
* @param resource the resource from which the embed will be made.
* @param rel the name of the rel.
* @param link the link.
* @param linkRest the LinkRest annotation (must have method defined).
@@ -495,8 +497,11 @@ public class Utils {
* link repository.
* @throws RuntimeException if any other problem occurs when trying to invoke the method.
*/
private void embedRelFromRepository(HALResource<? extends RestAddressableModel> resource,
void embedRelFromRepository(HALResource<? extends RestAddressableModel> resource,
String rel, Link link, LinkRest linkRest) {
if (resource.getContent().getEmbedLevel() == EMBED_MAX_LEVELS) {
return;
}
Projection projection = resource.getContent().getProjection();
LinkRestRepository linkRepository = getLinkResourceRepository(resource.getContent().getCategory(),
resource.getContent().getType(), rel);
@@ -505,9 +510,7 @@ public class Utils {
Object contentId = getContentIdForLinkMethod(resource.getContent(), method);
try {
Object linkedObject = method.invoke(linkRepository, null, contentId, null, projection);
if (linkedObject != null || !linkRest.embedOptional()) {
resource.embedResource(rel, wrapForEmbedding(linkedObject, link));
}
resource.embedResource(rel, wrapForEmbedding(resource, linkedObject, link));
} catch (InvocationTargetException e) {
if (e.getTargetException() instanceof RuntimeException) {
throw (RuntimeException) e.getTargetException();
@@ -521,10 +524,13 @@ public class Utils {
}
/**
* Adds embeds for all properties annotated with {@code @LinkRel} or whose return types are
* {@link RestAddressableModel} subclasses.
* Adds embeds (if the maximum embed level has not been exceeded yet) for all properties annotated with
* {@code @LinkRel} or whose return types are {@link RestAddressableModel} subclasses.
*/
public void embedMethodLevelRels(HALResource<? extends RestAddressableModel> resource) {
if (resource.getContent().getEmbedLevel() == EMBED_MAX_LEVELS) {
return;
}
try {
for (PropertyDescriptor pd : Introspector.getBeanInfo(
resource.getContent().getClass()).getPropertyDescriptors()) {
@@ -561,6 +567,7 @@ public class Utils {
* rest repository. Otherwise, the value will come from invoking the method directly on the wrapped
* rest object.
*
* @param resource the resource from which the embed will be made.
* @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.
@@ -572,8 +579,7 @@ public class Utils {
LinkRest linkRest = findLinkAnnotation(readMethod);
try {
if (linkRest != null) {
if (linkRest.embedOptional()
&& !resource.getContent().getProjection().allowOptionalEmbed(resource, linkRest)) {
if (!resource.getContent().getProjection().allowEmbedding(resource, linkRest)) {
return; // projection disallows this optional method-level embed
}
if (StringUtils.isNotBlank(linkRest.name())) {
@@ -582,16 +588,14 @@ public class Utils {
Link link = linkToSubResource(resource.getContent(), rel);
if (StringUtils.isBlank(linkRest.method())) {
Object linkedObject = readMethod.invoke(resource.getContent());
if (linkedObject != null || !linkRest.embedOptional()) {
resource.embedResource(rel, wrapForEmbedding(linkedObject, link));
}
resource.embedResource(rel, wrapForEmbedding(resource, linkedObject, link));
} else {
embedRelFromRepository(resource, rel, link, linkRest);
}
} 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)));
wrapForEmbedding(resource, linkedObject, linkToSubResource(resource.getContent(), rel)));
}
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
@@ -600,29 +604,41 @@ public class Utils {
/**
* 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.
* in an object that is appropriate for embedding, if needed. Does not perform the actual embed; the
* caller is responsible for that.
*
* @param resource the resource from which the embed will be made.
* @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.
* @return the wrapped object, which will have an "embed level" one greater than the given parent resource.
*/
private Object wrapForEmbedding(Object linkedObject, Link link) {
private Object wrapForEmbedding(HALResource<? extends RestAddressableModel> resource,
Object linkedObject, Link link) {
int childEmbedLevel = resource.getContent().getEmbedLevel() + 1;
if (linkedObject instanceof RestAddressableModel) {
return converter.toResource((RestAddressableModel) linkedObject);
RestAddressableModel restObject = (RestAddressableModel) linkedObject;
restObject.setEmbedLevel(childEmbedLevel);
return converter.toResource(restObject);
} else if (linkedObject instanceof Page) {
// The first page has already been constructed by a link repository and we only need to wrap it
Page<RestAddressableModel> page = (Page<RestAddressableModel>) linkedObject;
return new EmbeddedPage(link.getHref(), page.map(converter::toResource), null, link.getRel());
return new EmbeddedPage(link.getHref(), page.map((restObject) -> {
restObject.setEmbedLevel(childEmbedLevel);
return converter.toResource(restObject);
}), 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<RestAddressableModel> list = (List<RestAddressableModel>) linkedObject;
if (list.size() > 0) {
PageImpl<RestAddressableModel> page = new PageImpl(
list.subList(0, list.size() > EMBEDDED_PAGE_SIZE ? EMBEDDED_PAGE_SIZE : list.size()),
new PageRequest(0, EMBEDDED_PAGE_SIZE), list.size());
list.subList(0, list.size() > DEFAULT_PAGE_SIZE ? DEFAULT_PAGE_SIZE : list.size()),
new PageRequest(0, DEFAULT_PAGE_SIZE), list.size());
return new EmbeddedPage(link.getHref(),
page.map((restObject) -> converter.toResource(restObject)),
page.map((restObject) -> {
restObject.setEmbedLevel(childEmbedLevel);
return converter.toResource(restObject);
}),
list, link.getRel());
} else {
PageImpl<RestAddressableModel> page = new PageImpl(list);

View File

@@ -23,7 +23,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import java.util.Base64;
import org.dspace.app.rest.builder.GroupBuilder;
import org.dspace.app.rest.matcher.AuthenticationStatusMatcher;
import org.dspace.app.rest.matcher.EPersonMatcher;
import org.dspace.app.rest.matcher.HalMatcher;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.eperson.Group;
import org.dspace.services.ConfigurationService;
@@ -59,10 +61,11 @@ public class AuthenticationRestControllerIT extends AbstractControllerIntegratio
public void testStatusAuthenticated() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(get("/api/authn/status"))
getClient(token).perform(get("/api/authn/status").param("projection", "full"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", AuthenticationStatusMatcher.matchFullEmbeds()))
.andExpect(jsonPath("$", AuthenticationStatusMatcher.matchLinks()))
//We expect the content type to be "application/hal+json;charset=UTF-8"
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$.okay", is(true)))
@@ -71,7 +74,13 @@ public class AuthenticationRestControllerIT extends AbstractControllerIntegratio
.andExpect(jsonPath("$._links.eperson.href", startsWith(REST_SERVER_URL)))
.andExpect(jsonPath("$._embedded.eperson",
EPersonMatcher.matchEPersonWithGroups(eperson.getEmail(), "Anonymous")));
EPersonMatcher.matchEPersonWithGroups(eperson.getEmail(), "Anonymous")))
;
getClient(token).perform(get("/api/authn/status"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", HalMatcher.matchNoEmbeds()))
;
}
@Test
@@ -99,7 +108,7 @@ public class AuthenticationRestControllerIT extends AbstractControllerIntegratio
assertNotEquals(token1, token2);
getClient(token1).perform(get("/api/authn/status"))
getClient(token1).perform(get("/api/authn/status").param("projection", "full"))
.andExpect(status().isOk())
@@ -113,7 +122,8 @@ public class AuthenticationRestControllerIT extends AbstractControllerIntegratio
.andExpect(jsonPath("$._embedded.eperson",
EPersonMatcher.matchEPersonOnEmail(eperson.getEmail())));
getClient(token2).perform(get("/api/authn/status"))
getClient(token2).perform(get("/api/authn/status")
.param("projection", "full"))
.andExpect(status().isOk())
@@ -370,7 +380,7 @@ public class AuthenticationRestControllerIT extends AbstractControllerIntegratio
.andExpect(status().isOk())
.andReturn().getResponse().getHeader(AUTHORIZATION_HEADER);
getClient(token).perform(get("/api/authn/status"))
getClient(token).perform(get("/api/authn/status").param("projection", "full"))
.andExpect(status().isOk())
//We expect the content type to be "application/hal+json;charset=UTF-8"
.andExpect(content().contentType(contentType))
@@ -403,7 +413,7 @@ public class AuthenticationRestControllerIT extends AbstractControllerIntegratio
.andExpect(status().isOk())
.andReturn().getResponse().getHeader(AUTHORIZATION_HEADER);
getClient(token).perform(get("/api/authn/status")
getClient(token).perform(get("/api/authn/status").param("projection", "full")
.with(ip("123.123.123.123")))
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())
@@ -423,7 +433,7 @@ public class AuthenticationRestControllerIT extends AbstractControllerIntegratio
.andExpect(status().isOk())
.andReturn().getResponse().getHeader(AUTHORIZATION_HEADER);
getClient(token).perform(get("/api/authn/status")
getClient(token).perform(get("/api/authn/status").param("projection", "full")
.with(ip("234.234.234.234")))
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())

View File

@@ -16,6 +16,7 @@ import java.util.UUID;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.dspace.app.rest.matcher.AuthorityEntryMatcher;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.authority.PersonAuthorityValue;
import org.dspace.authority.factory.AuthorityServiceFactory;
@@ -157,9 +158,12 @@ public class AuthorityRestRepositoryIT extends AbstractControllerIntegrationTest
@Test
public void retrieveSrscValueTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
// When full projection is requested, response should include expected properties, links, and embeds.
getClient(token).perform(
get("/api/integration/authorities/srsc/entryValues/SCB1922"))
get("/api/integration/authorities/srsc/entryValues/SCB1922").param("projection", "full"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", AuthorityEntryMatcher.matchFullEmbeds()))
.andExpect(jsonPath("$.page.totalElements", Matchers.is(1)));
}
@@ -175,9 +179,11 @@ public class AuthorityRestRepositoryIT extends AbstractControllerIntegrationTest
public void retrieveCommonTypesValueTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(
get("/api/integration/authorities/common_types/entryValues/Book"))
get("/api/integration/authorities/common_types/entryValues/Book").param("projection", "full"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.page.totalElements", Matchers.is(1)));
.andExpect(jsonPath("$.page.totalElements", Matchers.is(1)))
;
}
@Test

View File

@@ -104,7 +104,8 @@ public class BitstreamControllerIT extends AbstractControllerIntegrationTest {
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle"))
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle")
.param("projection", "full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
@@ -167,7 +168,8 @@ public class BitstreamControllerIT extends AbstractControllerIntegrationTest {
String token = getAuthToken(admin.getEmail(), password);
getClient().perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle"))
getClient().perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle")
.param("projection", "full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
@@ -334,7 +336,8 @@ public class BitstreamControllerIT extends AbstractControllerIntegrationTest {
String name = targetBundle.getName();
String handle = targetBundle.getHandle();
List<Bitstream> bitstreams = targetBundle.getBitstreams();
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle"))
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle")
.param("projection", "full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
@@ -454,7 +457,8 @@ public class BitstreamControllerIT extends AbstractControllerIntegrationTest {
String handle = targetBundle.getHandle();
List<Bitstream> bitstreams = targetBundle.getBitstreams();
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle"))
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle")
.param("projection", "full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
@@ -566,7 +570,8 @@ public class BitstreamControllerIT extends AbstractControllerIntegrationTest {
List<Bitstream> bitstreams = targetBundle.getBitstreams();
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle"))
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle")
.param("projection", "full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
@@ -666,7 +671,8 @@ public class BitstreamControllerIT extends AbstractControllerIntegrationTest {
))
.andExpect(status().isForbidden());
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle"))
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle")
.param("projection", "full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
@@ -768,8 +774,9 @@ public class BitstreamControllerIT extends AbstractControllerIntegrationTest {
.andExpect(status().isForbidden());
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle"))
.andExpect(status().isOk())
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle")
.param("projection", "full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
BundleMatcher.matchBundle(bundle1.getName(),
@@ -869,7 +876,8 @@ public class BitstreamControllerIT extends AbstractControllerIntegrationTest {
))
.andExpect(status().isForbidden());
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle"))
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle")
.param("projection", "full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
@@ -963,14 +971,15 @@ public class BitstreamControllerIT extends AbstractControllerIntegrationTest {
String token = getAuthToken(putBundlePerson.getEmail(), "test");
getClient(token)
.perform(put("/api/core/bitstreams/" + bitstream.getID() + "/bundle")
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
.perform(put("/api/core/bitstreams/" + bitstream.getID() + "/bundle").param("projection", "full")
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
.content(
"https://localhost:8080/spring-rest/api/core/bundles/" + targetBundle.getID()
))
.andExpect(status().isForbidden());
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle"))
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle")
.param("projection", "full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
@@ -1072,7 +1081,8 @@ public class BitstreamControllerIT extends AbstractControllerIntegrationTest {
.andExpect(status().isForbidden());
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle"))
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle")
.param("projection", "full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
@@ -1173,7 +1183,8 @@ public class BitstreamControllerIT extends AbstractControllerIntegrationTest {
))
.andExpect(status().isForbidden());
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle"))
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle")
.param("projection", "full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
@@ -1267,14 +1278,15 @@ public class BitstreamControllerIT extends AbstractControllerIntegrationTest {
String token = getAuthToken(putBundlePerson.getEmail(), "test");
getClient(token)
.perform(put("/api/core/bitstreams/" + bitstream.getID() + "/bundle")
.perform(put("/api/core/bitstreams/" + bitstream.getID() + "/bundle").param("projection", "full")
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
.content(
"https://localhost:8080/spring-rest/api/core/bundles/" + targetBundle.getID()
))
.andExpect(status().isForbidden());
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle"))
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/bundle")
.param("projection", "full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(

View File

@@ -26,6 +26,7 @@ import org.dspace.app.rest.builder.CommunityBuilder;
import org.dspace.app.rest.builder.ItemBuilder;
import org.dspace.app.rest.matcher.BitstreamFormatMatcher;
import org.dspace.app.rest.matcher.BitstreamMatcher;
import org.dspace.app.rest.matcher.HalMatcher;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.app.rest.test.MetadataPatchSuite;
import org.dspace.content.Bitstream;
@@ -92,7 +93,8 @@ public class BitstreamRestRepositoryIT extends AbstractControllerIntegrationTest
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/core/bitstreams/"))
getClient(token).perform(get("/api/core/bitstreams/")
.param("projection", "full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.bitstreams", Matchers.containsInAnyOrder(
@@ -150,7 +152,8 @@ public class BitstreamRestRepositoryIT extends AbstractControllerIntegrationTest
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/core/bitstreams/")
.param("size", "1"))
.param("size", "1")
.param("projection", "full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.bitstreams", Matchers.contains(
@@ -166,7 +169,8 @@ public class BitstreamRestRepositoryIT extends AbstractControllerIntegrationTest
getClient(token).perform(get("/api/core/bitstreams/")
.param("size", "1")
.param("page", "1"))
.param("page", "1")
.param("projection", "full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.bitstreams", Matchers.contains(
@@ -248,6 +252,7 @@ public class BitstreamRestRepositoryIT extends AbstractControllerIntegrationTest
//We turn off the authorization system in order to create the structure as defined below
context.turnOffAuthorisationSystem();
//** GIVEN **
//1. A community-collection structure with one parent community with sub-community and one collection.
parentCommunity = CommunityBuilder.createCommunity(context)
@@ -289,13 +294,22 @@ public class BitstreamRestRepositoryIT extends AbstractControllerIntegrationTest
.build();
}
getClient().perform(get("/api/core/bitstreams/" + bitstream.getID()))
// When full projection is requested, response should include expected properties, links, and embeds.
getClient().perform(get("/api/core/bitstreams/" + bitstream.getID())
.param("projection", "full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", BitstreamMatcher.matchFullEmbeds()))
.andExpect(jsonPath("$", BitstreamMatcher.matchBitstreamEntry(bitstream)))
.andExpect(jsonPath("$", not(BitstreamMatcher.matchBitstreamEntry(bitstream1))))
;
// When no projection is requested, response should include expected properties, links, and no embeds.
getClient().perform(get("/api/core/bitstreams/" + bitstream.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$", HalMatcher.matchNoEmbeds()))
;
}
@Test

Some files were not shown because too many files have changed in this diff Show More