Merge pull request #2720 from tdonohue/fix_security_alerts_for_spring

Upgrade backend to Spring Boot v2.2.6, Spring v5.2.5, Spring HATEOAS v1.0.3
This commit is contained in:
Tim Donohue
2020-04-30 16:23:30 -05:00
committed by GitHub
58 changed files with 515 additions and 439 deletions

View File

@@ -308,15 +308,10 @@
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
<artifactId>handle</artifactId> <artifactId>handle</artifactId>
</dependency> </dependency>
<!-- Jetty is needed to run Handle Server -->
<dependency> <dependency>
<groupId>org.eclipse.jetty.aggregate</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-all</artifactId> <artifactId>jetty-server</artifactId>
<exclusions>
<exclusion>
<artifactId>javax.servlet</artifactId>
<groupId>org.eclipse.jetty.orbit</groupId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
@@ -489,6 +484,13 @@
<groupId>org.apache.solr</groupId> <groupId>org.apache.solr</groupId>
<artifactId>solr-cell</artifactId> <artifactId>solr-cell</artifactId>
<version>${solr.client.version}</version> <version>${solr.client.version}</version>
<exclusions>
<!-- Newer version provided in our parent POM -->
<exclusion>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-commons</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>

View File

@@ -142,19 +142,22 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</exclusion> </exclusion>
<!-- More recent version is pulled in via solr-core --> <!-- More recent version is pulled in via below dependencies -->
<exclusion> <exclusion>
<groupId>org.ow2.asm</groupId> <groupId>org.parboiled</groupId>
<artifactId>asm</artifactId> <artifactId>parboiled-java</artifactId>
</exclusion>
<!-- This exclusion may be removable once we update to Spring Boot v2 -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<!-- Newer version, necessary to align with newer version of ASM in parent POM
This is needed by both jtwig-spring-boot-starter and our tests. -->
<dependency>
<groupId>org.parboiled</groupId>
<artifactId>parboiled-java</artifactId>
<version>1.3.1</version>
</dependency>
<!-- Internal --> <!-- Internal -->
<dependency> <dependency>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
@@ -190,10 +193,10 @@
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId> <artifactId>log4j-core</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId> <artifactId>log4j-web</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId> <artifactId>log4j-slf4j-impl</artifactId>
@@ -258,12 +261,6 @@
<version>${spring.version}</version> <version>${spring.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.parboiled</groupId>
<artifactId>parboiled-core</artifactId>
<version>1.1.7</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.xmlmatchers</groupId> <groupId>org.xmlmatchers</groupId>
<artifactId>xml-matchers</artifactId> <artifactId>xml-matchers</artifactId>

View File

@@ -19,7 +19,7 @@
<properties> <properties>
<!-- This is the path to the root [dspace-src] directory. --> <!-- This is the path to the root [dspace-src] directory. -->
<root.basedir>${basedir}/..</root.basedir> <root.basedir>${basedir}/..</root.basedir>
<spring-security.version>5.1.3.RELEASE</spring-security.version> <spring-security.version>5.3.1.RELEASE</spring-security.version>
</properties> </properties>
<build> <build>
<plugins> <plugins>
@@ -104,7 +104,7 @@
<version>${jackson.version}</version> <version>${jackson.version}</version>
</dependency> </dependency>
<!-- Spring 3 dependencies --> <!-- Spring dependencies -->
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId> <artifactId>spring-core</artifactId>
@@ -123,9 +123,10 @@
<!-- Jersey + Spring --> <!-- Jersey + Spring -->
<dependency> <dependency>
<groupId>org.glassfish.jersey.ext</groupId> <groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring4</artifactId> <artifactId>jersey-spring5</artifactId>
<version>${jersey.version}</version> <version>${jersey.version}</version>
<exclusions> <exclusions>
<!-- We provide our own version of Spring framework dependencies -->
<exclusion> <exclusion>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring</artifactId> <artifactId>spring</artifactId>
@@ -150,6 +151,11 @@
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId> <artifactId>spring-aop</artifactId>
</exclusion> </exclusion>
<!-- Newer version provided by jersey-server above -->
<exclusion>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
</exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency> <dependency>

View File

@@ -27,8 +27,6 @@
<resource.delimiter>@</resource.delimiter> <resource.delimiter>@</resource.delimiter>
<!-- Define our starting class for our Spring Boot Application --> <!-- Define our starting class for our Spring Boot Application -->
<start-class>org.dspace.app.rest.Application</start-class> <start-class>org.dspace.app.rest.Application</start-class>
<!-- Library for managing JSON Web Tokens (JWT): https://bitbucket.org/connect2id/nimbus-jose-jwt/wiki/Home -->
<nimbus-jose-jwt.version>7.9</nimbus-jose-jwt.version>
</properties> </properties>
<profiles> <profiles>
@@ -241,11 +239,7 @@
<dependency> <dependency>
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-hal-browser</artifactId> <artifactId>spring-data-rest-hal-browser</artifactId>
<version>3.1.10.RELEASE</version> <version>${spring-hal-browser.version}</version>
<!-- if you get a java.util.zip.ZipException: invalid LOC
header (bad signature) during the tomcat startup
force the use of the previous version as the jar file
looks corrupted in the maven repository -->
</dependency> </dependency>
<!-- Add in Spring Security for AuthN and AuthZ --> <!-- Add in Spring Security for AuthN and AuthZ -->
@@ -255,10 +249,8 @@
<version>${spring-boot.version}</version> <version>${spring-boot.version}</version>
</dependency> </dependency>
<!-- Add in log4j support by excluding default logging, and <!-- Add in log4j support by excluding default logging, and using starter-log4j -->
using starter-log4j --> <!-- See: https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto-logging -->
<!-- See: http://docs.spring.io/spring-boot/docs/current/reference
/html/howto-logging.html#howto-configure-log4j-for-logging -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId> <artifactId>spring-boot-starter</artifactId>
@@ -346,6 +338,7 @@
<dependency> <dependency>
<groupId>com.jayway.jsonpath</groupId> <groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path-assert</artifactId> <artifactId>json-path-assert</artifactId>
<version>${json-path.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>

View File

@@ -11,7 +11,7 @@ import java.util.List;
import javax.servlet.Filter; import javax.servlet.Filter;
import org.dspace.app.rest.filter.DSpaceRequestContextFilter; import org.dspace.app.rest.filter.DSpaceRequestContextFilter;
import org.dspace.app.rest.model.hateoas.DSpaceRelProvider; import org.dspace.app.rest.model.hateoas.DSpaceLinkRelationProvider;
import org.dspace.app.rest.parameter.resolver.SearchFilterResolver; import org.dspace.app.rest.parameter.resolver.SearchFilterResolver;
import org.dspace.app.rest.utils.ApplicationConfig; import org.dspace.app.rest.utils.ApplicationConfig;
import org.dspace.app.rest.utils.DSpaceConfigurationInitializer; import org.dspace.app.rest.utils.DSpaceConfigurationInitializer;
@@ -26,7 +26,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
import org.springframework.hateoas.RelProvider; import org.springframework.hateoas.server.LinkRelationProvider;
import org.springframework.lang.NonNull; import org.springframework.lang.NonNull;
import org.springframework.web.context.request.RequestContextListener; import org.springframework.web.context.request.RequestContextListener;
import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfiguration;
@@ -118,8 +118,8 @@ public class Application extends SpringBootServletInitializer {
} }
@Bean @Bean
protected RelProvider dspaceRelProvider() { protected LinkRelationProvider dspaceLinkRelationProvider() {
return new DSpaceRelProvider(); return new DSpaceLinkRelationProvider();
} }
@Bean @Bean

View File

@@ -31,7 +31,7 @@ import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.ControllerUtils; import org.springframework.data.rest.webmvc.ControllerUtils;
import org.springframework.data.rest.webmvc.ResourceNotFoundException; import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.RepresentationModel;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -86,9 +86,11 @@ public class BundleUploadBitstreamController {
*/ */
@RequestMapping(method = RequestMethod.POST, headers = "content-type=multipart/form-data") @RequestMapping(method = RequestMethod.POST, headers = "content-type=multipart/form-data")
@PreAuthorize("hasPermission(#uuid, 'BUNDLE', 'ADD') && hasPermission(#uuid, 'BUNDLE', 'WRITE')") @PreAuthorize("hasPermission(#uuid, 'BUNDLE', 'ADD') && hasPermission(#uuid, 'BUNDLE', 'WRITE')")
public ResponseEntity<ResourceSupport> uploadBitstream(HttpServletRequest request, @PathVariable UUID uuid, public ResponseEntity<RepresentationModel<?>> uploadBitstream(
@RequestParam("file") MultipartFile uploadfile, HttpServletRequest request,
@RequestParam(value = "properties", required = false) String properties) { @PathVariable UUID uuid,
@RequestParam("file") MultipartFile uploadfile,
@RequestParam(value = "properties", required = false) String properties) {
Context context = ContextUtil.obtainContext(request); Context context = ContextUtil.obtainContext(request);
Bundle bundle = null; Bundle bundle = null;

View File

@@ -36,7 +36,7 @@ import org.dspace.xmlworkflow.WorkflowUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.ControllerUtils; import org.springframework.data.rest.webmvc.ControllerUtils;
import org.springframework.data.rest.webmvc.ResourceNotFoundException; import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.RepresentationModel;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -83,7 +83,7 @@ public class CollectionGroupRestController {
*/ */
@RequestMapping(method = RequestMethod.POST, value = "/adminGroup") @RequestMapping(method = RequestMethod.POST, value = "/adminGroup")
@PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')") @PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')")
public ResponseEntity<ResourceSupport> postAdminGroup(@PathVariable UUID uuid, HttpServletResponse response, public ResponseEntity<RepresentationModel<?>> postAdminGroup(@PathVariable UUID uuid, HttpServletResponse response,
HttpServletRequest request) HttpServletRequest request)
throws SQLException, AuthorizeException { throws SQLException, AuthorizeException {
@@ -117,8 +117,9 @@ public class CollectionGroupRestController {
*/ */
@RequestMapping(method = RequestMethod.DELETE, value = "/adminGroup") @RequestMapping(method = RequestMethod.DELETE, value = "/adminGroup")
@PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')") @PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')")
public ResponseEntity<ResourceSupport> deleteAdminGroup(@PathVariable UUID uuid, HttpServletResponse response, public ResponseEntity<RepresentationModel<?>> deleteAdminGroup(@PathVariable UUID uuid,
HttpServletRequest request) HttpServletResponse response,
HttpServletRequest request)
throws SQLException, AuthorizeException, IOException { throws SQLException, AuthorizeException, IOException {
Context context = ContextUtil.obtainContext(request); Context context = ContextUtil.obtainContext(request);
@@ -149,8 +150,9 @@ public class CollectionGroupRestController {
*/ */
@RequestMapping(method = RequestMethod.POST, value = "/submittersGroup") @RequestMapping(method = RequestMethod.POST, value = "/submittersGroup")
@PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')") @PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')")
public ResponseEntity<ResourceSupport> postSubmittersGroup(@PathVariable UUID uuid, HttpServletResponse response, public ResponseEntity<RepresentationModel<?>> postSubmittersGroup(@PathVariable UUID uuid,
HttpServletRequest request) HttpServletResponse response,
HttpServletRequest request)
throws SQLException, AuthorizeException { throws SQLException, AuthorizeException {
Context context = ContextUtil.obtainContext(request); Context context = ContextUtil.obtainContext(request);
@@ -183,8 +185,9 @@ public class CollectionGroupRestController {
*/ */
@RequestMapping(method = RequestMethod.DELETE, value = "/submittersGroup") @RequestMapping(method = RequestMethod.DELETE, value = "/submittersGroup")
@PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')") @PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')")
public ResponseEntity<ResourceSupport> deleteSubmittersGroup(@PathVariable UUID uuid, HttpServletResponse response, public ResponseEntity<RepresentationModel<?>> deleteSubmittersGroup(@PathVariable UUID uuid,
HttpServletRequest request) HttpServletResponse response,
HttpServletRequest request)
throws SQLException, AuthorizeException, IOException { throws SQLException, AuthorizeException, IOException {
Context context = ContextUtil.obtainContext(request); Context context = ContextUtil.obtainContext(request);
@@ -214,8 +217,9 @@ public class CollectionGroupRestController {
*/ */
@RequestMapping(method = RequestMethod.POST, value = "/itemReadGroup") @RequestMapping(method = RequestMethod.POST, value = "/itemReadGroup")
@PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')") @PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')")
public ResponseEntity<ResourceSupport> postItemReadGroup(@PathVariable UUID uuid, HttpServletResponse response, public ResponseEntity<RepresentationModel<?>> postItemReadGroup(@PathVariable UUID uuid,
HttpServletRequest request) HttpServletResponse response,
HttpServletRequest request)
throws SQLException, AuthorizeException { throws SQLException, AuthorizeException {
Context context = ContextUtil.obtainContext(request); Context context = ContextUtil.obtainContext(request);
@@ -255,8 +259,9 @@ public class CollectionGroupRestController {
*/ */
@RequestMapping(method = RequestMethod.DELETE, value = "/itemReadGroup") @RequestMapping(method = RequestMethod.DELETE, value = "/itemReadGroup")
@PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')") @PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')")
public ResponseEntity<ResourceSupport> deleteItemReadGroup(@PathVariable UUID uuid, HttpServletResponse response, public ResponseEntity<RepresentationModel<?>> deleteItemReadGroup(@PathVariable UUID uuid,
HttpServletRequest request) HttpServletResponse response,
HttpServletRequest request)
throws SQLException, AuthorizeException, IOException { throws SQLException, AuthorizeException, IOException {
Context context = ContextUtil.obtainContext(request); Context context = ContextUtil.obtainContext(request);
@@ -294,8 +299,9 @@ public class CollectionGroupRestController {
*/ */
@RequestMapping(method = RequestMethod.POST, value = "/bitstreamReadGroup") @RequestMapping(method = RequestMethod.POST, value = "/bitstreamReadGroup")
@PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')") @PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')")
public ResponseEntity<ResourceSupport> postBitstreamReadGroup(@PathVariable UUID uuid, HttpServletResponse response, public ResponseEntity<RepresentationModel<?>> postBitstreamReadGroup(@PathVariable UUID uuid,
HttpServletRequest request) HttpServletResponse response,
HttpServletRequest request)
throws SQLException, AuthorizeException { throws SQLException, AuthorizeException {
Context context = ContextUtil.obtainContext(request); Context context = ContextUtil.obtainContext(request);
@@ -336,9 +342,9 @@ public class CollectionGroupRestController {
*/ */
@RequestMapping(method = RequestMethod.DELETE, value = "/bitstreamReadGroup") @RequestMapping(method = RequestMethod.DELETE, value = "/bitstreamReadGroup")
@PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')") @PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')")
public ResponseEntity<ResourceSupport> deleteBitstreamReadGroup(@PathVariable UUID uuid, public ResponseEntity<RepresentationModel<?>> deleteBitstreamReadGroup(@PathVariable UUID uuid,
HttpServletResponse response, HttpServletResponse response,
HttpServletRequest request) HttpServletRequest request)
throws SQLException, AuthorizeException, IOException { throws SQLException, AuthorizeException, IOException {
Context context = ContextUtil.obtainContext(request); Context context = ContextUtil.obtainContext(request);
@@ -377,10 +383,10 @@ public class CollectionGroupRestController {
*/ */
@RequestMapping(method = RequestMethod.GET, value = "/workflowGroups/{workflowRole}") @RequestMapping(method = RequestMethod.GET, value = "/workflowGroups/{workflowRole}")
@PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'READ')") @PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'READ')")
public ResponseEntity<ResourceSupport> getWorkflowGroupForRole(@PathVariable UUID uuid, public ResponseEntity<RepresentationModel<?>> getWorkflowGroupForRole(@PathVariable UUID uuid,
HttpServletResponse response, HttpServletResponse response,
HttpServletRequest request, HttpServletRequest request,
@PathVariable String workflowRole) @PathVariable String workflowRole)
throws Exception { throws Exception {
Context context = ContextUtil.obtainContext(request); Context context = ContextUtil.obtainContext(request);
Collection collection = collectionService.find(context, uuid); Collection collection = collectionService.find(context, uuid);
@@ -407,10 +413,10 @@ public class CollectionGroupRestController {
*/ */
@RequestMapping(method = RequestMethod.POST, value = "/workflowGroups/{workflowRole}") @RequestMapping(method = RequestMethod.POST, value = "/workflowGroups/{workflowRole}")
@PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'READ')") @PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'READ')")
public ResponseEntity<ResourceSupport> postWorkflowGroupForRole(@PathVariable UUID uuid, public ResponseEntity<RepresentationModel<?>> postWorkflowGroupForRole(@PathVariable UUID uuid,
HttpServletResponse response, HttpServletResponse response,
HttpServletRequest request, HttpServletRequest request,
@PathVariable String workflowRole) @PathVariable String workflowRole)
throws Exception { throws Exception {
Context context = ContextUtil.obtainContext(request); Context context = ContextUtil.obtainContext(request);
Collection collection = collectionService.find(context, uuid); Collection collection = collectionService.find(context, uuid);
@@ -446,10 +452,10 @@ public class CollectionGroupRestController {
*/ */
@RequestMapping(method = RequestMethod.DELETE, value = "/workflowGroups/{workflowRole}") @RequestMapping(method = RequestMethod.DELETE, value = "/workflowGroups/{workflowRole}")
@PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'READ')") @PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'READ')")
public ResponseEntity<ResourceSupport> deleteWorkflowGroupForRole(@PathVariable UUID uuid, public ResponseEntity<RepresentationModel<?>> deleteWorkflowGroupForRole(@PathVariable UUID uuid,
HttpServletResponse response, HttpServletResponse response,
HttpServletRequest request, HttpServletRequest request,
@PathVariable String workflowRole) @PathVariable String workflowRole)
throws Exception { throws Exception {
Context context = ContextUtil.obtainContext(request); Context context = ContextUtil.obtainContext(request);
Collection collection = collectionService.find(context, uuid); Collection collection = collectionService.find(context, uuid);

View File

@@ -32,7 +32,7 @@ import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.ControllerUtils; import org.springframework.data.rest.webmvc.ControllerUtils;
import org.springframework.data.rest.webmvc.ResourceNotFoundException; import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.RepresentationModel;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -50,7 +50,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@RequestMapping("/api/" + CollectionRest.CATEGORY + "/" + CollectionRest.PLURAL_NAME @RequestMapping("/api/" + CollectionRest.CATEGORY + "/" + CollectionRest.PLURAL_NAME
+ REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID + "/itemtemplate") + REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID + "/itemtemplate")
public class CollectionItemtemplateController { public class CollectionItemTemplateController {
@Autowired @Autowired
private Utils utils; private Utils utils;
@@ -100,9 +100,9 @@ public class CollectionItemtemplateController {
*/ */
@PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')") @PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')")
@RequestMapping(method = RequestMethod.POST) @RequestMapping(method = RequestMethod.POST)
public ResponseEntity<ResourceSupport> createTemplateItem(HttpServletRequest request, public ResponseEntity<RepresentationModel<?>> createTemplateItem(HttpServletRequest request,
@PathVariable UUID uuid, @PathVariable UUID uuid,
@RequestBody(required = false) JsonNode itemBody) @RequestBody(required = false) JsonNode itemBody)
throws SQLException, AuthorizeException { throws SQLException, AuthorizeException {
if (itemBody == null) { if (itemBody == null) {
@@ -125,7 +125,7 @@ public class CollectionItemtemplateController {
context.commit(); context.commit();
return ControllerUtils.toResponseEntity(HttpStatus.CREATED, new HttpHeaders(), return ControllerUtils.toResponseEntity(HttpStatus.CREATED, new HttpHeaders(),
converter.toResource(templateItem)); (RepresentationModel<?>) converter.toResource(templateItem));
} }
/** /**

View File

@@ -26,7 +26,7 @@ import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.ControllerUtils; import org.springframework.data.rest.webmvc.ControllerUtils;
import org.springframework.data.rest.webmvc.ResourceNotFoundException; import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.RepresentationModel;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -89,8 +89,10 @@ public class CollectionLogoController {
@PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')") @PreAuthorize("hasPermission(#uuid, 'COLLECTION', 'WRITE')")
@RequestMapping(method = RequestMethod.POST, @RequestMapping(method = RequestMethod.POST,
headers = "content-type=multipart/form-data") headers = "content-type=multipart/form-data")
public ResponseEntity<ResourceSupport> createLogo(HttpServletRequest request, @PathVariable UUID uuid, public ResponseEntity<RepresentationModel<?>> createLogo(
@RequestParam(value = "file", required = false) MultipartFile uploadfile) HttpServletRequest request,
@PathVariable UUID uuid,
@RequestParam(value = "file", required = false) MultipartFile uploadfile)
throws SQLException, IOException, AuthorizeException { throws SQLException, IOException, AuthorizeException {
if (uploadfile == null) { if (uploadfile == null) {

View File

@@ -30,7 +30,7 @@ import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.ControllerUtils; import org.springframework.data.rest.webmvc.ControllerUtils;
import org.springframework.data.rest.webmvc.ResourceNotFoundException; import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.RepresentationModel;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -73,7 +73,7 @@ public class CommunityAdminGroupRestController {
*/ */
@RequestMapping(method = RequestMethod.POST) @RequestMapping(method = RequestMethod.POST)
@PreAuthorize("hasPermission(#uuid, 'COMMUNITY', 'WRITE')") @PreAuthorize("hasPermission(#uuid, 'COMMUNITY', 'WRITE')")
public ResponseEntity<ResourceSupport> postAdminGroup(@PathVariable UUID uuid, HttpServletResponse response, public ResponseEntity<RepresentationModel<?>> postAdminGroup(@PathVariable UUID uuid, HttpServletResponse response,
HttpServletRequest request) HttpServletRequest request)
throws SQLException, AuthorizeException { throws SQLException, AuthorizeException {
@@ -107,8 +107,9 @@ public class CommunityAdminGroupRestController {
*/ */
@RequestMapping(method = RequestMethod.DELETE) @RequestMapping(method = RequestMethod.DELETE)
@PreAuthorize("hasPermission(#uuid, 'COMMUNITY', 'WRITE')") @PreAuthorize("hasPermission(#uuid, 'COMMUNITY', 'WRITE')")
public ResponseEntity<ResourceSupport> deleteAdminGroup(@PathVariable UUID uuid, HttpServletResponse response, public ResponseEntity<RepresentationModel<?>> deleteAdminGroup(@PathVariable UUID uuid,
HttpServletRequest request) HttpServletResponse response,
HttpServletRequest request)
throws SQLException, AuthorizeException, IOException { throws SQLException, AuthorizeException, IOException {
Context context = ContextUtil.obtainContext(request); Context context = ContextUtil.obtainContext(request);

View File

@@ -26,7 +26,7 @@ import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.ControllerUtils; import org.springframework.data.rest.webmvc.ControllerUtils;
import org.springframework.data.rest.webmvc.ResourceNotFoundException; import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.RepresentationModel;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -89,8 +89,9 @@ public class CommunityLogoController {
@PreAuthorize("hasPermission(#uuid, 'COMMUNITY', 'WRITE')") @PreAuthorize("hasPermission(#uuid, 'COMMUNITY', 'WRITE')")
@RequestMapping(method = RequestMethod.POST, @RequestMapping(method = RequestMethod.POST,
headers = "content-type=multipart/form-data") headers = "content-type=multipart/form-data")
public ResponseEntity<ResourceSupport> createLogo(HttpServletRequest request, @PathVariable UUID uuid, public ResponseEntity<RepresentationModel<?>> createLogo(HttpServletRequest request, @PathVariable UUID uuid,
@RequestParam(value = "file", required = false) MultipartFile uploadfile) @RequestParam(value = "file", required = false)
MultipartFile uploadfile)
throws SQLException, IOException, AuthorizeException { throws SQLException, IOException, AuthorizeException {
if (uploadfile == null) { if (uploadfile == null) {

View File

@@ -68,10 +68,11 @@ public class DiscoverableEndpointsService {
discoverableEndpoints.add(link); discoverableEndpoints.add(link);
// sanity check // sanity check
// FIXME improve logging for debugging // FIXME improve logging for debugging
if (rels.contains(link.getRel())) { if (rels.contains(link.getRel().value())) {
throw new IllegalStateException("The rel " + link.getRel() + " is defined multiple times!"); throw new IllegalStateException("The rel " + link.getRel().value()
+ " is defined multiple times!");
} }
rels.add(link.getRel()); rels.add(link.getRel().value());
} }
} }
} }
@@ -87,4 +88,4 @@ public class DiscoverableEndpointsService {
// could be used to override default implementation) // could be used to override default implementation)
return true; return true;
} }
} }

View File

@@ -34,7 +34,7 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.RepresentationModel;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
@@ -171,15 +171,15 @@ public class DiscoveryRestController implements InitializingBean {
} }
@RequestMapping(method = RequestMethod.GET, value = "/facets/{name}") @RequestMapping(method = RequestMethod.GET, value = "/facets/{name}")
public ResourceSupport getFacetValues(@PathVariable("name") String facetName, public RepresentationModel getFacetValues(@PathVariable("name") String facetName,
@RequestParam(name = "prefix", required = false) String prefix, @RequestParam(name = "prefix", required = false) String prefix,
@RequestParam(name = "query", required = false) String query, @RequestParam(name = "query", required = false) String query,
@RequestParam(name = "dsoType", required = false) String dsoType, @RequestParam(name = "dsoType", required = false) String dsoType,
@RequestParam(name = "scope", required = false) String dsoScope, @RequestParam(name = "scope", required = false) String dsoScope,
@RequestParam(name = "configuration", required = false) String @RequestParam(name = "configuration", required = false) String
configuration, configuration,
List<SearchFilter> searchFilters, List<SearchFilter> searchFilters,
Pageable page) throws Exception { Pageable page) throws Exception {
if (log.isTraceEnabled()) { if (log.isTraceEnabled()) {
log.trace("Facetting on facet " + facetName + " with scope: " + StringUtils.trimToEmpty(dsoScope) log.trace("Facetting on facet " + facetName + " with scope: " + StringUtils.trimToEmpty(dsoScope)
+ ", dsoType: " + StringUtils.trimToEmpty(dsoType) + ", dsoType: " + StringUtils.trimToEmpty(dsoType)

View File

@@ -16,7 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PagedResourcesAssembler; import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.PagedResources; import org.springframework.hateoas.PagedModel;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
@@ -54,7 +54,7 @@ public class ExternalSourcesRestController {
* @return A paginated list of ExternalSourceEntryResource objects that comply with the params * @return A paginated list of ExternalSourceEntryResource objects that comply with the params
*/ */
@RequestMapping(method = RequestMethod.GET, value = "/entries") @RequestMapping(method = RequestMethod.GET, value = "/entries")
public PagedResources<ExternalSourceEntryResource> getExternalSourceEntries( public PagedModel<ExternalSourceEntryResource> getExternalSourceEntries(
@PathVariable("externalSourceName") String externalSourceName, @PathVariable("externalSourceName") String externalSourceName,
@RequestParam(name = "query") String query, @RequestParam(name = "query") String query,
@RequestParam(name = "parent", required = false) String parent, @RequestParam(name = "parent", required = false) String parent,
@@ -65,7 +65,7 @@ public class ExternalSourcesRestController {
Page<ExternalSourceEntryResource> externalSourceEntryResources = externalSourceEntryRestPage Page<ExternalSourceEntryResource> externalSourceEntryResources = externalSourceEntryRestPage
.map(externalSourceEntryRest -> new ExternalSourceEntryResource(externalSourceEntryRest)); .map(externalSourceEntryRest -> new ExternalSourceEntryResource(externalSourceEntryRest));
externalSourceEntryResources.forEach(linkService::addLinks); externalSourceEntryResources.forEach(linkService::addLinks);
PagedResources<ExternalSourceEntryResource> result = assembler.toResource(externalSourceEntryResources); PagedModel<ExternalSourceEntryResource> result = assembler.toModel(externalSourceEntryResources);
return result; return result;
} }

View File

@@ -2,12 +2,12 @@
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.app.rest; package org.dspace.app.rest;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;

View File

@@ -33,7 +33,7 @@ import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.ControllerUtils; import org.springframework.data.rest.webmvc.ControllerUtils;
import org.springframework.data.rest.webmvc.ResourceNotFoundException; import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.RepresentationModel;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -87,9 +87,9 @@ public class ItemAddBundleController {
*/ */
@RequestMapping(method = RequestMethod.POST) @RequestMapping(method = RequestMethod.POST)
@PreAuthorize("hasPermission(#uuid, 'ITEM', 'ADD')") @PreAuthorize("hasPermission(#uuid, 'ITEM', 'ADD')")
public ResponseEntity<ResourceSupport> addBundleToItem(@PathVariable UUID uuid, public ResponseEntity<RepresentationModel<?>> addBundleToItem(@PathVariable UUID uuid,
HttpServletRequest request, HttpServletRequest request,
HttpServletResponse response) HttpServletResponse response)
throws SQLException, AuthorizeException { throws SQLException, AuthorizeException {
Context context = ContextUtil.obtainContext(request); Context context = ContextUtil.obtainContext(request);

View File

@@ -32,7 +32,7 @@ import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.ControllerUtils; import org.springframework.data.rest.webmvc.ControllerUtils;
import org.springframework.data.rest.webmvc.ResourceNotFoundException; import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.RepresentationModel;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -49,7 +49,7 @@ import org.springframework.web.bind.annotation.RestController;
*/ */
@RestController @RestController
@RequestMapping("/api/core/itemtemplates" + REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID) @RequestMapping("/api/core/itemtemplates" + REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID)
public class ItemtemplateRestController { public class ItemTemplateRestController {
@Autowired @Autowired
private Utils utils; private Utils utils;
@@ -122,8 +122,8 @@ public class ItemtemplateRestController {
*/ */
@PreAuthorize("hasPermission(#uuid, 'ITEM', 'WRITE')") @PreAuthorize("hasPermission(#uuid, 'ITEM', 'WRITE')")
@RequestMapping(method = RequestMethod.PATCH) @RequestMapping(method = RequestMethod.PATCH)
public ResponseEntity<ResourceSupport> patch(HttpServletRequest request, @PathVariable UUID uuid, public ResponseEntity<RepresentationModel<?>> patch(HttpServletRequest request, @PathVariable UUID uuid,
@RequestBody(required = true) JsonNode jsonNode) @RequestBody(required = true) JsonNode jsonNode)
throws SQLException, AuthorizeException { throws SQLException, AuthorizeException {
Context context = ContextUtil.obtainContext(request); Context context = ContextUtil.obtainContext(request);
@@ -132,7 +132,7 @@ public class ItemtemplateRestController {
context.commit(); context.commit();
return ControllerUtils.toResponseEntity(HttpStatus.OK, new HttpHeaders(), return ControllerUtils.toResponseEntity(HttpStatus.OK, new HttpHeaders(),
converter.toResource(templateItemRest)); (RepresentationModel<?>) converter.toResource(templateItemRest));
} }
/** /**
@@ -155,7 +155,8 @@ public class ItemtemplateRestController {
*/ */
@PreAuthorize("hasPermission(#uuid, 'ITEM', 'DELETE')") @PreAuthorize("hasPermission(#uuid, 'ITEM', 'DELETE')")
@RequestMapping(method = RequestMethod.DELETE) @RequestMapping(method = RequestMethod.DELETE)
public ResponseEntity<ResourceSupport> deleteTemplateItem(HttpServletRequest request, @PathVariable UUID uuid) public ResponseEntity<RepresentationModel<?>> deleteTemplateItem(HttpServletRequest request,
@PathVariable UUID uuid)
throws SQLException, AuthorizeException, IOException { throws SQLException, AuthorizeException, IOException {
Context context = ContextUtil.obtainContext(request); Context context = ContextUtil.obtainContext(request);

View File

@@ -27,7 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PagedResourcesAssembler; import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.PagedResources; import org.springframework.hateoas.PagedModel;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
@@ -71,7 +71,7 @@ public class RelationshipTypeRestController {
* @throws SQLException If something goes wrong * @throws SQLException If something goes wrong
*/ */
@RequestMapping(method = RequestMethod.GET) @RequestMapping(method = RequestMethod.GET)
public PagedResources<RelationshipTypeResource> retrieve(@PathVariable Integer id, public PagedModel<RelationshipTypeResource> retrieve(@PathVariable Integer id,
HttpServletResponse response, HttpServletResponse response,
HttpServletRequest request, HttpServletRequest request,
Pageable pageable, Pageable pageable,
@@ -86,7 +86,7 @@ public class RelationshipTypeRestController {
Page<RelationshipTypeResource> relationshipTypeResources = relationshipTypeRestPage Page<RelationshipTypeResource> relationshipTypeResources = relationshipTypeRestPage
.map(relationshipTypeRest -> new RelationshipTypeResource(relationshipTypeRest, utils)); .map(relationshipTypeRest -> new RelationshipTypeResource(relationshipTypeRest, utils));
relationshipTypeResources.forEach(halLinkService::addLinks); relationshipTypeResources.forEach(halLinkService::addLinks);
PagedResources<RelationshipTypeResource> result = assembler.toResource(relationshipTypeResources); PagedModel<RelationshipTypeResource> result = assembler.toModel(relationshipTypeResources);
return result; return result;

View File

@@ -10,8 +10,8 @@ package org.dspace.app.rest;
import static org.dspace.app.rest.utils.RegexUtils.REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT; import static org.dspace.app.rest.utils.RegexUtils.REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT;
import static org.dspace.app.rest.utils.RegexUtils.REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG; import static org.dspace.app.rest.utils.RegexUtils.REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG;
import static org.dspace.app.rest.utils.RegexUtils.REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID; import static org.dspace.app.rest.utils.RegexUtils.REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
@@ -63,15 +63,13 @@ import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.data.rest.webmvc.ControllerUtils; import org.springframework.data.rest.webmvc.ControllerUtils;
import org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler;
import org.springframework.data.rest.webmvc.ResourceNotFoundException; import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.data.web.PagedResourcesAssembler; import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import org.springframework.hateoas.PagedResources; import org.springframework.hateoas.PagedModel;
import org.springframework.hateoas.Resource; import org.springframework.hateoas.RepresentationModel;
import org.springframework.hateoas.ResourceSupport;
import org.springframework.hateoas.Resources;
import org.springframework.hateoas.UriTemplate;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -121,7 +119,7 @@ public class RestResourceController implements InitializingBean {
@Override @Override
public void afterPropertiesSet() { public void afterPropertiesSet() {
List<Link> links = new ArrayList<Link>(); List<Link> links = new ArrayList<>();
for (String r : utils.getRepositories()) { for (String r : utils.getRepositories()) {
// this doesn't work as we don't have an active http request // this doesn't work as we don't have an active http request
// see https://github.com/spring-projects/spring-hateoas/issues/408 // see https://github.com/spring-projects/spring-hateoas/issues/408
@@ -130,7 +128,7 @@ public class RestResourceController implements InitializingBean {
String plural = English.plural(split[1]); String plural = English.plural(split[1]);
Link l = new Link("/api/" + split[0] + "/" + plural, plural); Link l = new Link("/api/" + split[0] + "/" + plural, plural);
links.add(l); links.add(l);
System.out.println(l.getRel() + " " + l.getHref()); log.debug(l.getRel().value() + " " + l.getHref());
} }
discoverableEndpointsService.register(this, links); discoverableEndpointsService.register(this, links);
} }
@@ -145,13 +143,12 @@ public class RestResourceController implements InitializingBean {
* identifier * identifier
* and see {@link RestResourceController#findOne(String, String, UUID)} for uuid as identifier * and see {@link RestResourceController#findOne(String, String, UUID)} for uuid as identifier
* *
* @param apiCategory * @param apiCategory category from request
* @param model * @param model model from request
* @param id * @param id Identifier from request
* @return * @return single DSpaceResource
*/ */
@RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT) @RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT)
@SuppressWarnings("unchecked")
public DSpaceResource<RestAddressableModel> findOne(@PathVariable String apiCategory, @PathVariable String model, public DSpaceResource<RestAddressableModel> findOne(@PathVariable String apiCategory, @PathVariable String model,
@PathVariable Integer id) { @PathVariable Integer id) {
return findOneInternal(apiCategory, model, id); return findOneInternal(apiCategory, model, id);
@@ -177,13 +174,12 @@ public class RestResourceController implements InitializingBean {
* identifier * identifier
* and see {@link RestResourceController#findOne(String, String, UUID)} for uuid as identifier * and see {@link RestResourceController#findOne(String, String, UUID)} for uuid as identifier
* *
* @param apiCategory * @param apiCategory category from request
* @param model * @param model model from request
* @param id * @param id Identifier from request
* @return * @return single DSpaceResource
*/ */
@RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG) @RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG)
@SuppressWarnings("unchecked")
public DSpaceResource<RestAddressableModel> findOne(@PathVariable String apiCategory, @PathVariable String model, public DSpaceResource<RestAddressableModel> findOne(@PathVariable String apiCategory, @PathVariable String model,
@PathVariable String id) { @PathVariable String id) {
return findOneInternal(apiCategory, model, id); return findOneInternal(apiCategory, model, id);
@@ -198,13 +194,12 @@ public class RestResourceController implements InitializingBean {
* identifier * identifier
* and see {@link RestResourceController#findOne(String, String, String)} for string as identifier * and see {@link RestResourceController#findOne(String, String, String)} for string as identifier
* *
* @param apiCategory * @param apiCategory category from request
* @param model * @param model model from request
* @param uuid * @param uuid Identifier from request
* @return * @return single DSpaceResource
*/ */
@RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID) @RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID)
@SuppressWarnings("unchecked")
public DSpaceResource<RestAddressableModel> findOne(@PathVariable String apiCategory, @PathVariable String model, public DSpaceResource<RestAddressableModel> findOne(@PathVariable String apiCategory, @PathVariable String model,
@PathVariable UUID uuid) { @PathVariable UUID uuid) {
return findOneInternal(apiCategory, model, uuid); return findOneInternal(apiCategory, model, uuid);
@@ -213,10 +208,10 @@ public class RestResourceController implements InitializingBean {
/** /**
* Internal method to retrieve single resource from an identifier of generic type * Internal method to retrieve single resource from an identifier of generic type
* *
* @param apiCategory * @param apiCategory category from request
* @param model * @param model model from request
* @param id * @param id Identifier from request
* @return * @return single DSpaceResource
*/ */
private <ID extends Serializable> DSpaceResource<RestAddressableModel> findOneInternal(String apiCategory, private <ID extends Serializable> DSpaceResource<RestAddressableModel> findOneInternal(String apiCategory,
String model, ID id) { String model, ID id) {
@@ -238,17 +233,17 @@ public class RestResourceController implements InitializingBean {
* *
* Note that the regular expression in the request mapping accept a number; * Note that the regular expression in the request mapping accept a number;
* *
* @param request * @param request current HTTPServletRequest
* @param apiCategory * @param apiCategory category from request
* @param model * @param model model from request
* @param id * @param id identifier from request
* @param rel * @param rel relation from request
* @param page * @param page pagination information
* @param assembler * @param assembler PagedResourcesAssembler
* @return * @return single RepresentationModel
*/ */
@RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT + "/{rel}") @RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT + "/{rel}")
public ResourceSupport findRel(HttpServletRequest request, HttpServletResponse response, public RepresentationModel findRel(HttpServletRequest request, HttpServletResponse response,
@PathVariable String apiCategory, @PathVariable String apiCategory,
@PathVariable String model, @PathVariable Integer id, @PathVariable String rel, @PathVariable String model, @PathVariable Integer id, @PathVariable String rel,
Pageable page, Pageable page,
@@ -262,18 +257,19 @@ public class RestResourceController implements InitializingBean {
* Note that the regular expression in the request mapping accept a string as identifier but not the other kind * Note that the regular expression in the request mapping accept a string as identifier but not the other kind
* of identifier; * of identifier;
* *
* @param request * @param request current HTTPServletRequest
* @param apiCategory * @param response HTTPServletResponse
* @param model * @param apiCategory category from request
* @param id * @param model model from request
* @param rel * @param id identifier from request
* @param page * @param rel relation from request
* @param assembler * @param page pagination information
* @return * @param assembler PagedResourcesAssembler
* @return single RepresentationModel
*/ */
@RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG + @RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG +
"/{rel}") "/{rel}")
public ResourceSupport findRel(HttpServletRequest request, HttpServletResponse response, public RepresentationModel findRel(HttpServletRequest request, HttpServletResponse response,
@PathVariable String apiCategory, @PathVariable String apiCategory,
@PathVariable String model, @PathVariable String id, @PathVariable String rel, @PathVariable String model, @PathVariable String id, @PathVariable String rel,
Pageable page, Pageable page,
@@ -296,7 +292,7 @@ public class RestResourceController implements InitializingBean {
* @return * @return
*/ */
@RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID + "/{rel}") @RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID + "/{rel}")
public ResourceSupport findRel(HttpServletRequest request, HttpServletResponse response, public RepresentationModel findRel(HttpServletRequest request, HttpServletResponse response,
@PathVariable String apiCategory, @PathVariable String apiCategory,
@PathVariable String model, @PathVariable UUID uuid, @PathVariable String rel, @PathVariable String model, @PathVariable UUID uuid, @PathVariable String rel,
Pageable page, Pageable page,
@@ -338,7 +334,7 @@ public class RestResourceController implements InitializingBean {
*/ */
@RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG + @RequestMapping(method = RequestMethod.GET, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG +
"/{rel}/{relid}") "/{rel}/{relid}")
public ResourceSupport findRel(HttpServletRequest request, HttpServletResponse response, public RepresentationModel findRel(HttpServletRequest request, HttpServletResponse response,
@PathVariable String apiCategory, @PathVariable String apiCategory,
@PathVariable String model, @PathVariable String id, @PathVariable String rel, @PathVariable String model, @PathVariable String id, @PathVariable String rel,
@PathVariable String relid, @PathVariable String relid,
@@ -367,10 +363,10 @@ public class RestResourceController implements InitializingBean {
* @throws HttpRequestMethodNotSupportedException If something goes wrong * @throws HttpRequestMethodNotSupportedException If something goes wrong
*/ */
@RequestMapping(method = RequestMethod.POST, consumes = {"application/json", "application/hal+json"}) @RequestMapping(method = RequestMethod.POST, consumes = {"application/json", "application/hal+json"})
public ResponseEntity<ResourceSupport> post(HttpServletRequest request, public ResponseEntity<RepresentationModel<?>> post(HttpServletRequest request,
@PathVariable String apiCategory, @PathVariable String apiCategory,
@PathVariable String model, @PathVariable String model,
@RequestParam(required = false) String parent) @RequestParam(required = false) String parent)
throws HttpRequestMethodNotSupportedException { throws HttpRequestMethodNotSupportedException {
return postJsonInternal(request, apiCategory, model, parent); return postJsonInternal(request, apiCategory, model, parent);
} }
@@ -394,9 +390,9 @@ public class RestResourceController implements InitializingBean {
* @throws HttpRequestMethodNotSupportedException If something goes wrong * @throws HttpRequestMethodNotSupportedException If something goes wrong
*/ */
@RequestMapping(method = RequestMethod.POST, consumes = {"text/uri-list"}) @RequestMapping(method = RequestMethod.POST, consumes = {"text/uri-list"})
public ResponseEntity<ResourceSupport> postWithUriListContentType(HttpServletRequest request, public ResponseEntity<RepresentationModel<?>> postWithUriListContentType(HttpServletRequest request,
@PathVariable String apiCategory, @PathVariable String apiCategory,
@PathVariable String model) @PathVariable String model)
throws HttpRequestMethodNotSupportedException { throws HttpRequestMethodNotSupportedException {
return postUriListInternal(request, apiCategory, model); return postUriListInternal(request, apiCategory, model);
} }
@@ -411,9 +407,10 @@ public class RestResourceController implements InitializingBean {
* @return The relevant ResponseEntity for this request * @return The relevant ResponseEntity for this request
* @throws HttpRequestMethodNotSupportedException If something goes wrong * @throws HttpRequestMethodNotSupportedException If something goes wrong
*/ */
public <ID extends Serializable> ResponseEntity<ResourceSupport> postJsonInternal(HttpServletRequest request, public <ID extends Serializable> ResponseEntity<RepresentationModel<?>> postJsonInternal(HttpServletRequest request,
String apiCategory, String apiCategory,
String model, String parent) String model,
String parent)
throws HttpRequestMethodNotSupportedException { throws HttpRequestMethodNotSupportedException {
checkModelPluralForm(apiCategory, model); checkModelPluralForm(apiCategory, model);
DSpaceRestRepository<RestAddressableModel, ID> repository = utils.getResourceRepository(apiCategory, model); DSpaceRestRepository<RestAddressableModel, ID> repository = utils.getResourceRepository(apiCategory, model);
@@ -442,9 +439,10 @@ public class RestResourceController implements InitializingBean {
* @return The relevant ResponseEntity for this request * @return The relevant ResponseEntity for this request
* @throws HttpRequestMethodNotSupportedException If something goes wrong * @throws HttpRequestMethodNotSupportedException If something goes wrong
*/ */
public <ID extends Serializable> ResponseEntity<ResourceSupport> postUriListInternal(HttpServletRequest request, public <ID extends Serializable> ResponseEntity<RepresentationModel<?>> postUriListInternal(
String apiCategory, HttpServletRequest request,
String model) String apiCategory,
String model)
throws HttpRequestMethodNotSupportedException { throws HttpRequestMethodNotSupportedException {
checkModelPluralForm(apiCategory, model); checkModelPluralForm(apiCategory, model);
DSpaceRestRepository<RestAddressableModel, ID> repository = utils.getResourceRepository(apiCategory, model); DSpaceRestRepository<RestAddressableModel, ID> repository = utils.getResourceRepository(apiCategory, model);
@@ -482,8 +480,8 @@ public class RestResourceController implements InitializingBean {
*/ */
@RequestMapping(method = RequestMethod.POST, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT, headers = @RequestMapping(method = RequestMethod.POST, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT, headers =
"content-type=application/x-www-form-urlencoded") "content-type=application/x-www-form-urlencoded")
public ResponseEntity<ResourceSupport> action(HttpServletRequest request, @PathVariable String apiCategory, public ResponseEntity<RepresentationModel<?>> action(HttpServletRequest request, @PathVariable String apiCategory,
@PathVariable String model, @PathVariable Integer id) @PathVariable String model, @PathVariable Integer id)
throws HttpRequestMethodNotSupportedException, SQLException, IOException { throws HttpRequestMethodNotSupportedException, SQLException, IOException {
checkModelPluralForm(apiCategory, model); checkModelPluralForm(apiCategory, model);
DSpaceRestRepository<RestAddressableModel, Integer> repository = DSpaceRestRepository<RestAddressableModel, Integer> repository =
@@ -525,11 +523,11 @@ public class RestResourceController implements InitializingBean {
*/ */
@RequestMapping(method = RequestMethod.POST, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT, headers = @RequestMapping(method = RequestMethod.POST, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT, headers =
"content-type=multipart/form-data") "content-type=multipart/form-data")
public <ID extends Serializable> ResponseEntity<ResourceSupport> upload(HttpServletRequest request, public <ID extends Serializable> ResponseEntity<RepresentationModel<?>> upload(HttpServletRequest request,
@PathVariable String apiCategory, @PathVariable String apiCategory,
@PathVariable String model, @PathVariable String model,
@PathVariable Integer id, @PathVariable Integer id,
@RequestParam("file") MultipartFile @RequestParam("file") MultipartFile
uploadfile) uploadfile)
throws HttpRequestMethodNotSupportedException { throws HttpRequestMethodNotSupportedException {
return uploadInternal(request, apiCategory, model, id, uploadfile); return uploadInternal(request, apiCategory, model, id, uploadfile);
@@ -555,11 +553,11 @@ public class RestResourceController implements InitializingBean {
*/ */
@RequestMapping(method = RequestMethod.POST, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID, headers = @RequestMapping(method = RequestMethod.POST, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID, headers =
"content-type=multipart/form-data") "content-type=multipart/form-data")
public <ID extends Serializable> ResponseEntity<ResourceSupport> upload(HttpServletRequest request, public <ID extends Serializable> ResponseEntity<RepresentationModel<?>> upload(HttpServletRequest request,
@PathVariable String apiCategory, @PathVariable String apiCategory,
@PathVariable String model, @PathVariable String model,
@PathVariable UUID uuid, @PathVariable UUID uuid,
@RequestParam("file") MultipartFile @RequestParam("file") MultipartFile
uploadfile) uploadfile)
throws HttpRequestMethodNotSupportedException { throws HttpRequestMethodNotSupportedException {
return uploadInternal(request, apiCategory, model, uuid, uploadfile); return uploadInternal(request, apiCategory, model, uuid, uploadfile);
@@ -575,10 +573,11 @@ public class RestResourceController implements InitializingBean {
* @param uploadfile * @param uploadfile
* @return * @return
*/ */
private <ID extends Serializable> ResponseEntity<ResourceSupport> uploadInternal(HttpServletRequest request, private <ID extends Serializable> ResponseEntity<RepresentationModel<?>> uploadInternal(HttpServletRequest request,
String apiCategory, String model, String apiCategory,
ID id, String model,
MultipartFile uploadfile) { ID id,
MultipartFile uploadfile) {
checkModelPluralForm(apiCategory, model); checkModelPluralForm(apiCategory, model);
DSpaceRestRepository<RestAddressableModel, ID> repository = utils.getResourceRepository(apiCategory, model); DSpaceRestRepository<RestAddressableModel, ID> repository = utils.getResourceRepository(apiCategory, model);
RestAddressableModel modelObject = null; RestAddressableModel modelObject = null;
@@ -613,11 +612,11 @@ public class RestResourceController implements InitializingBean {
* @throws AuthorizeException * @throws AuthorizeException
*/ */
@RequestMapping(method = { RequestMethod.POST }, headers = "content-type=multipart/form-data") @RequestMapping(method = { RequestMethod.POST }, headers = "content-type=multipart/form-data")
public <T extends RestAddressableModel> ResponseEntity<ResourceSupport> upload(HttpServletRequest request, public <T extends RestAddressableModel> ResponseEntity<RepresentationModel<?>> upload(
@PathVariable String apiCategory, HttpServletRequest request,
@PathVariable String model, @PathVariable String apiCategory,
@RequestParam("file") MultipartFile @PathVariable String model,
uploadfile) @RequestParam("file") MultipartFile uploadfile)
throws SQLException, FileNotFoundException, IOException, AuthorizeException { throws SQLException, FileNotFoundException, IOException, AuthorizeException {
checkModelPluralForm(apiCategory, model); checkModelPluralForm(apiCategory, model);
@@ -630,7 +629,7 @@ public class RestResourceController implements InitializingBean {
DSpaceResource result = converter.toResource(modelObject); DSpaceResource result = converter.toResource(modelObject);
resources.add(result); resources.add(result);
} }
return ControllerUtils.toResponseEntity(HttpStatus.OK, new HttpHeaders(), Resources.wrap(resources)); return ControllerUtils.toResponseEntity(HttpStatus.OK, new HttpHeaders(), CollectionModel.wrap(resources));
} }
/** /**
@@ -648,9 +647,9 @@ public class RestResourceController implements InitializingBean {
* @throws HttpRequestMethodNotSupportedException * @throws HttpRequestMethodNotSupportedException
*/ */
@RequestMapping(method = RequestMethod.PATCH, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT) @RequestMapping(method = RequestMethod.PATCH, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT)
public ResponseEntity<ResourceSupport> patch(HttpServletRequest request, @PathVariable String apiCategory, public ResponseEntity<RepresentationModel<?>> patch(HttpServletRequest request, @PathVariable String apiCategory,
@PathVariable String model, @PathVariable Integer id, @PathVariable String model, @PathVariable Integer id,
@RequestBody(required = true) JsonNode jsonNode) { @RequestBody(required = true) JsonNode jsonNode) {
return patchInternal(request, apiCategory, model, id, jsonNode); return patchInternal(request, apiCategory, model, id, jsonNode);
} }
@@ -669,10 +668,10 @@ public class RestResourceController implements InitializingBean {
* @throws HttpRequestMethodNotSupportedException * @throws HttpRequestMethodNotSupportedException
*/ */
@RequestMapping(method = RequestMethod.PATCH, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID) @RequestMapping(method = RequestMethod.PATCH, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID)
public ResponseEntity<ResourceSupport> patch(HttpServletRequest request, @PathVariable String apiCategory, public ResponseEntity<RepresentationModel<?>> patch(HttpServletRequest request, @PathVariable String apiCategory,
@PathVariable String model, @PathVariable String model,
@PathVariable(name = "uuid") UUID id, @PathVariable(name = "uuid") UUID id,
@RequestBody(required = true) JsonNode jsonNode) { @RequestBody(required = true) JsonNode jsonNode) {
return patchInternal(request, apiCategory, model, id, jsonNode); return patchInternal(request, apiCategory, model, id, jsonNode);
} }
@@ -687,10 +686,10 @@ public class RestResourceController implements InitializingBean {
* @return * @return
* @throws HttpRequestMethodNotSupportedException * @throws HttpRequestMethodNotSupportedException
*/ */
public <ID extends Serializable> ResponseEntity<ResourceSupport> patchInternal(HttpServletRequest request, public <ID extends Serializable> ResponseEntity<RepresentationModel<?>> patchInternal(HttpServletRequest request,
String apiCategory, String apiCategory,
String model, ID id, String model, ID id,
JsonNode jsonNode) { JsonNode jsonNode) {
checkModelPluralForm(apiCategory, model); checkModelPluralForm(apiCategory, model);
DSpaceRestRepository<RestAddressableModel, ID> repository = utils.getResourceRepository(apiCategory, model); DSpaceRestRepository<RestAddressableModel, ID> repository = utils.getResourceRepository(apiCategory, model);
RestAddressableModel modelObject = null; RestAddressableModel modelObject = null;
@@ -722,7 +721,7 @@ public class RestResourceController implements InitializingBean {
* @param assembler * @param assembler
* @return * @return
*/ */
private <ID extends Serializable> ResourceSupport findRelEntryInternal(HttpServletRequest request, private <ID extends Serializable> RepresentationModel findRelEntryInternal(HttpServletRequest request,
HttpServletResponse response, HttpServletResponse response,
String apiCategory, String model, String apiCategory, String model,
String id, String rel, String relid, String id, String rel, String relid,
@@ -745,7 +744,7 @@ public class RestResourceController implements InitializingBean {
result.add(object); result.add(object);
PageImpl<RestAddressableModel> pageResult = new PageImpl(result, page, 1); PageImpl<RestAddressableModel> pageResult = new PageImpl(result, page, 1);
Page<HALResource> halResources = pageResult.map(restObject -> converter.toResource(restObject)); Page<HALResource> halResources = pageResult.map(restObject -> converter.toResource(restObject));
return assembler.toResource(halResources, link); return assembler.toModel(halResources, link);
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
// This catch has been made to resolve the issue that caused AuthorizeDenied exceptions for the methods // This catch has been made to resolve the issue that caused AuthorizeDenied exceptions for the methods
// on the repository defined by the @PreAuthorize etc annotation to be absorbed by the reflection's // on the repository defined by the @PreAuthorize etc annotation to be absorbed by the reflection's
@@ -775,7 +774,7 @@ public class RestResourceController implements InitializingBean {
* @param assembler * @param assembler
* @return * @return
*/ */
private <ID extends Serializable> ResourceSupport findRelInternal(HttpServletRequest request, private <ID extends Serializable> RepresentationModel findRelInternal(HttpServletRequest request,
HttpServletResponse response, String apiCategory, HttpServletResponse response, String apiCategory,
String model, ID uuid, String subpath, String model, ID uuid, String subpath,
Pageable page, Pageable page,
@@ -785,7 +784,7 @@ public class RestResourceController implements InitializingBean {
Class<RestAddressableModel> domainClass = repository.getDomainClass(); Class<RestAddressableModel> domainClass = repository.getDomainClass();
LinkRest linkRest = utils.getClassLevelLinkRest(subpath, domainClass); LinkRest linkRest = utils.getClassLevelLinkRest(subpath, domainClass);
PagedResources<? extends HALResource> result; PagedModel<? extends HALResource> result;
if (linkRest != null) { if (linkRest != null) {
LinkRestRepository linkRepository = utils.getLinkResourceRepository(apiCategory, model, linkRest.name()); LinkRestRepository linkRepository = utils.getLinkResourceRepository(apiCategory, model, linkRest.name());
@@ -813,7 +812,7 @@ public class RestResourceController implements InitializingBean {
link = linkTo(this.getClass(), apiCategory, model).slash(uuid).slash(subpath).withSelfRel(); link = linkTo(this.getClass(), apiCategory, model).slash(uuid).slash(subpath).withSelfRel();
} }
return new Resource(new EmbeddedPage(link.getHref(), return new EntityModel(new EmbeddedPage(link.getHref(),
pageResult.map(converter::toResource), null, subpath)); pageResult.map(converter::toResource), null, subpath));
} else { } else {
RestModel object = (RestModel) linkMethod.invoke(linkRepository, request, uuid, page, RestModel object = (RestModel) linkMethod.invoke(linkRepository, request, uuid, page,
@@ -852,10 +851,10 @@ public class RestResourceController implements InitializingBean {
for (Link l : resource.getLinks()) { for (Link l : resource.getLinks()) {
if (l.isTemplated()) { if (l.isTemplated()) {
if (l.getHref().substring(0, l.getHref().indexOf("?")).contentEquals(request.getRequestURL())) { if (l.getHref().substring(0, l.getHref().indexOf("?")).contentEquals(request.getRequestURL())) {
rel = l.getRel(); rel = l.getRel().value();
} }
} else if (l.getHref().contentEquals(request.getRequestURL())) { } else if (l.getHref().contentEquals(request.getRequestURL())) {
rel = l.getRel(); rel = l.getRel().value();
} }
} }
@@ -877,7 +876,7 @@ public class RestResourceController implements InitializingBean {
List<? extends RestAddressableModel> fullList = ep.getFullList(); List<? extends RestAddressableModel> fullList = ep.getFullList();
if (fullList == null || fullList.size() == 0) { if (fullList == null || fullList.size() == 0) {
PageImpl<RestAddressableModel> pageResult = new PageImpl(fullList, page, 0); PageImpl<RestAddressableModel> pageResult = new PageImpl(fullList, page, 0);
result = assembler.toResource(pageResult); result = assembler.toModel(pageResult);
return result; return result;
} }
int start = Math.toIntExact(page.getOffset()); int start = Math.toIntExact(page.getOffset());
@@ -886,12 +885,12 @@ public class RestResourceController implements InitializingBean {
.getResourceRepository(fullList.get(0).getCategory(), fullList.get(0).getType()); .getResourceRepository(fullList.get(0).getCategory(), fullList.get(0).getType());
PageImpl<RestAddressableModel> pageResult = new PageImpl(fullList.subList(start, end), page, PageImpl<RestAddressableModel> pageResult = new PageImpl(fullList.subList(start, end), page,
fullList.size()); fullList.size());
return assembler.toResource(pageResult.map(converter::toResource)); return assembler.toModel(pageResult.map(converter::toResource));
} else { } else {
if (resource.getEmbeddedResources().get(rel) == null) { if (resource.getEmbeddedResources().get(rel) == null) {
response.setStatus(HttpServletResponse.SC_NO_CONTENT); response.setStatus(HttpServletResponse.SC_NO_CONTENT);
} }
return (ResourceSupport) resource.getEmbeddedResources().get(rel); return (RepresentationModel) resource.getEmbeddedResources().get(rel);
} }
} }
@@ -907,7 +906,7 @@ public class RestResourceController implements InitializingBean {
*/ */
@RequestMapping(method = RequestMethod.GET) @RequestMapping(method = RequestMethod.GET)
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends RestAddressableModel> PagedResources<DSpaceResource<T>> findAll(@PathVariable String apiCategory, public <T extends RestAddressableModel> PagedModel<DSpaceResource<T>> findAll(@PathVariable String apiCategory,
@PathVariable String model, @PathVariable String model,
Pageable page, Pageable page,
PagedResourcesAssembler assembler, PagedResourcesAssembler assembler,
@@ -923,7 +922,7 @@ public class RestResourceController implements InitializingBean {
} catch (PaginationException pe) { } catch (PaginationException pe) {
resources = new PageImpl<>(new ArrayList<>(), page, pe.getTotal()); resources = new PageImpl<>(new ArrayList<>(), page, pe.getTotal());
} }
PagedResources<DSpaceResource<T>> result = assembler.toResource(resources, link); PagedModel<DSpaceResource<T>> result = assembler.toModel(resources, link);
if (repositoryUtils.haveSearchMethods(repository)) { if (repositoryUtils.haveSearchMethods(repository)) {
result.add(linkTo(this.getClass(), apiCategory, model).slash("search").withRel("search")); result.add(linkTo(this.getClass(), apiCategory, model).slash("search").withRel("search"));
} }
@@ -942,8 +941,8 @@ public class RestResourceController implements InitializingBean {
} }
@RequestMapping(method = RequestMethod.GET, value = "/search") @RequestMapping(method = RequestMethod.GET, value = "/search")
public ResourceSupport listSearchMethods(@PathVariable String apiCategory, @PathVariable String model) { public RepresentationModel listSearchMethods(@PathVariable String apiCategory, @PathVariable String model) {
ResourceSupport root = new ResourceSupport(); RepresentationModel root = new RepresentationModel();
DSpaceRestRepository repository = utils.getResourceRepository(apiCategory, model); DSpaceRestRepository repository = utils.getResourceRepository(apiCategory, model);
List<String> searchMethods = repositoryUtils.listSearchMethods(repository); List<String> searchMethods = repositoryUtils.listSearchMethods(repository);
@@ -961,14 +960,14 @@ public class RestResourceController implements InitializingBean {
@RequestMapping(method = RequestMethod.GET, value = "/search/{searchMethodName}") @RequestMapping(method = RequestMethod.GET, value = "/search/{searchMethodName}")
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends RestAddressableModel> ResourceSupport executeSearchMethods(@PathVariable String apiCategory, public <T extends RestAddressableModel> RepresentationModel executeSearchMethods(
@PathVariable String model, @PathVariable String apiCategory,
@PathVariable String searchMethodName, @PathVariable String model,
HttpServletResponse response, @PathVariable String searchMethodName,
Pageable pageable, Sort sort, HttpServletResponse response,
PagedResourcesAssembler assembler, Pageable pageable, Sort sort,
@RequestParam MultiValueMap<String, PagedResourcesAssembler assembler,
Object> parameters) @RequestParam MultiValueMap<String, Object> parameters)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Link link = linkTo(this.getClass(), apiCategory, model).slash("search").slash(searchMethodName).withSelfRel(); Link link = linkTo(this.getClass(), apiCategory, model).slash("search").slash(searchMethodName).withSelfRel();
@@ -990,7 +989,7 @@ public class RestResourceController implements InitializingBean {
.executeQueryMethod(repository, parameters, searchMethod, pageable, sort, assembler); .executeQueryMethod(repository, parameters, searchMethod, pageable, sort, assembler);
returnPage = searchMethod.getReturnType().isAssignableFrom(Page.class); returnPage = searchMethod.getReturnType().isAssignableFrom(Page.class);
ResourceSupport result = null; RepresentationModel result = null;
if (returnPage) { if (returnPage) {
Page<DSpaceResource<T>> resources; Page<DSpaceResource<T>> resources;
if (searchResult == null) { if (searchResult == null) {
@@ -998,7 +997,7 @@ public class RestResourceController implements InitializingBean {
} else { } else {
resources = ((Page<T>) searchResult).map(converter::toResource); resources = ((Page<T>) searchResult).map(converter::toResource);
} }
result = assembler.toResource(resources, link); result = assembler.toModel(resources, link);
} else { } else {
if (searchResult == null) { if (searchResult == null) {
response.setStatus(HttpServletResponse.SC_NO_CONTENT); response.setStatus(HttpServletResponse.SC_NO_CONTENT);
@@ -1009,30 +1008,16 @@ public class RestResourceController implements InitializingBean {
return result; return result;
} }
/**
* Sets the location header pointing to the resource representing the given instance. Will make sure we properly
* expand the URI template potentially created as self link.
*
* @param headers must not be {@literal null}.
* @param assembler must not be {@literal null}.
* @param source must not be {@literal null}.
*/
private void addLocationHeader(HttpHeaders headers, PersistentEntityResourceAssembler assembler, Object source) {
String selfLink = assembler.getSelfLinkFor(source).getHref();
headers.setLocation(new UriTemplate(selfLink).expand());
}
@RequestMapping(method = RequestMethod.DELETE, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT) @RequestMapping(method = RequestMethod.DELETE, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT)
public ResponseEntity<ResourceSupport> delete(HttpServletRequest request, @PathVariable String apiCategory, public ResponseEntity<RepresentationModel<?>> delete(HttpServletRequest request, @PathVariable String apiCategory,
@PathVariable String model, @PathVariable Integer id) @PathVariable String model, @PathVariable Integer id)
throws HttpRequestMethodNotSupportedException { throws HttpRequestMethodNotSupportedException {
return deleteInternal(apiCategory, model, id); return deleteInternal(apiCategory, model, id);
} }
@RequestMapping(method = RequestMethod.DELETE, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID) @RequestMapping(method = RequestMethod.DELETE, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID)
public ResponseEntity<ResourceSupport> delete(HttpServletRequest request, @PathVariable String apiCategory, public ResponseEntity<RepresentationModel<?>> delete(HttpServletRequest request, @PathVariable String apiCategory,
@PathVariable String model, @PathVariable UUID uuid) @PathVariable String model, @PathVariable UUID uuid)
throws HttpRequestMethodNotSupportedException { throws HttpRequestMethodNotSupportedException {
return deleteInternal(apiCategory, model, uuid); return deleteInternal(apiCategory, model, uuid);
} }
@@ -1045,8 +1030,9 @@ public class RestResourceController implements InitializingBean {
* @param id * @param id
* @return * @return
*/ */
private <ID extends Serializable> ResponseEntity<ResourceSupport> deleteInternal(String apiCategory, String model, private <ID extends Serializable> ResponseEntity<RepresentationModel<?>> deleteInternal(String apiCategory,
ID id) { String model,
ID id) {
checkModelPluralForm(apiCategory, model); checkModelPluralForm(apiCategory, model);
DSpaceRestRepository<RestAddressableModel, ID> repository = utils.getResourceRepository(apiCategory, model); DSpaceRestRepository<RestAddressableModel, ID> repository = utils.getResourceRepository(apiCategory, model);
repository.deleteById(id); repository.deleteById(id);

View File

@@ -16,7 +16,7 @@ import org.dspace.app.rest.model.hateoas.ProcessResource;
import org.dspace.app.rest.repository.ScriptRestRepository; import org.dspace.app.rest.repository.ScriptRestRepository;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.ControllerUtils; import org.springframework.data.rest.webmvc.ControllerUtils;
import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.RepresentationModel;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -50,7 +50,7 @@ public class ScriptProcessesController {
*/ */
@RequestMapping(method = RequestMethod.POST) @RequestMapping(method = RequestMethod.POST)
@PreAuthorize("hasAuthority('ADMIN')") @PreAuthorize("hasAuthority('ADMIN')")
public ResponseEntity<ResourceSupport> startProcess(@PathVariable(name = "name") String scriptName) public ResponseEntity<RepresentationModel<?>> startProcess(@PathVariable(name = "name") String scriptName)
throws Exception { throws Exception {
if (log.isTraceEnabled()) { if (log.isTraceEnabled()) {
log.trace("Starting Process for Script with name: " + scriptName); log.trace("Starting Process for Script with name: " + scriptName);

View File

@@ -26,8 +26,8 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.ControllerUtils; import org.springframework.data.rest.webmvc.ControllerUtils;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import org.springframework.hateoas.PagedResources; import org.springframework.hateoas.PagedModel;
import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.RepresentationModel;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -75,33 +75,33 @@ public class StatisticsRestController implements InitializingBean {
} }
@RequestMapping(method = RequestMethod.GET, value = "/viewevents/{uuid}") @RequestMapping(method = RequestMethod.GET, value = "/viewevents/{uuid}")
public PagedResources<ViewEventResource> getViewEvent(@PathVariable(name = "uuid") UUID uuid) throws Exception { public PagedModel<ViewEventResource> getViewEvent(@PathVariable(name = "uuid") UUID uuid) throws Exception {
throw new RepositoryMethodNotImplementedException("No implementation found; Method not allowed!", ""); throw new RepositoryMethodNotImplementedException("No implementation found; Method not allowed!", "");
} }
@RequestMapping(method = RequestMethod.GET, value = "/searchevents/{uuid}") @RequestMapping(method = RequestMethod.GET, value = "/searchevents/{uuid}")
public PagedResources<SearchEventResource> getSearchEvent(@PathVariable(name = "uuid") UUID uuid) throws Exception { public PagedModel<SearchEventResource> getSearchEvent(@PathVariable(name = "uuid") UUID uuid) throws Exception {
throw new RepositoryMethodNotImplementedException("No implementation found; Method not allowed!", ""); throw new RepositoryMethodNotImplementedException("No implementation found; Method not allowed!", "");
} }
@RequestMapping(method = RequestMethod.GET, value = "/viewevents") @RequestMapping(method = RequestMethod.GET, value = "/viewevents")
public PagedResources<ViewEventResource> getViewEvents() throws Exception { public PagedModel<ViewEventResource> getViewEvents() throws Exception {
throw new RepositoryMethodNotImplementedException("No implementation found; Method not allowed!", ""); throw new RepositoryMethodNotImplementedException("No implementation found; Method not allowed!", "");
} }
@RequestMapping(method = RequestMethod.GET, value = "/searchevents") @RequestMapping(method = RequestMethod.GET, value = "/searchevents")
public PagedResources<SearchEventResource> getSearchEvents() throws Exception { public PagedModel<SearchEventResource> getSearchEvents() throws Exception {
throw new RepositoryMethodNotImplementedException("No implementation found; Method not allowed!", ""); throw new RepositoryMethodNotImplementedException("No implementation found; Method not allowed!", "");
} }
@RequestMapping(method = RequestMethod.POST, value = "/viewevents") @RequestMapping(method = RequestMethod.POST, value = "/viewevents")
public ResponseEntity<ResourceSupport> postViewEvent() throws Exception { public ResponseEntity<RepresentationModel<?>> postViewEvent() throws Exception {
ViewEventResource result = converter.toResource(viewEventRestRepository.createViewEvent()); ViewEventResource result = converter.toResource(viewEventRestRepository.createViewEvent());
return ControllerUtils.toResponseEntity(HttpStatus.CREATED, new HttpHeaders(), result); return ControllerUtils.toResponseEntity(HttpStatus.CREATED, new HttpHeaders(), result);
} }
@RequestMapping(method = RequestMethod.POST, value = "/searchevents") @RequestMapping(method = RequestMethod.POST, value = "/searchevents")
public ResponseEntity<ResourceSupport> postSearchEvent() throws Exception { public ResponseEntity<RepresentationModel<?>> postSearchEvent() throws Exception {
SearchEventResource result = converter.toResource(searchEventRestRepository.createSearchEvent()); SearchEventResource result = converter.toResource(searchEventRestRepository.createSearchEvent());
return ControllerUtils.toResponseEntity(HttpStatus.CREATED, new HttpHeaders(), result); return ControllerUtils.toResponseEntity(HttpStatus.CREATED, new HttpHeaders(), result);
} }

View File

@@ -2,12 +2,12 @@
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.app.rest; package org.dspace.app.rest;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;

View File

@@ -71,7 +71,7 @@ public class WorkflowDefinitionCollectionsLinkRepository extends AbstractDSpaceR
} }
collectionsMappedToWorkflow.addAll(xmlWorkflowFactory.getCollectionHandlesMappedToWorklow(context, collectionsMappedToWorkflow.addAll(xmlWorkflowFactory.getCollectionHandlesMappedToWorklow(context,
workflowName)); workflowName));
Pageable pageable = optionalPageable != null ? optionalPageable : new PageRequest(0, 20); Pageable pageable = optionalPageable != null ? optionalPageable : PageRequest.of(0, 20);
return converter.toRestPage(utils.getPage(collectionsMappedToWorkflow, pageable), return converter.toRestPage(utils.getPage(collectionsMappedToWorkflow, pageable),
projection); projection);
} else { } else {

View File

@@ -54,7 +54,7 @@ public class WorkflowDefinitionStepsLinkRepository extends AbstractDSpaceRestRep
Projection projection) { Projection projection) {
try { try {
List<Step> steps = xmlWorkflowFactory.getWorkflowByName(workflowName).getSteps(); List<Step> steps = xmlWorkflowFactory.getWorkflowByName(workflowName).getSteps();
Pageable pageable = optionalPageable != null ? optionalPageable : new PageRequest(0, 20); Pageable pageable = optionalPageable != null ? optionalPageable : PageRequest.of(0, 20);
return converter.toRestPage(utils.getPage(steps, pageable), projection); return converter.toRestPage(utils.getPage(steps, pageable), projection);
} catch (WorkflowConfigurationException e) { } catch (WorkflowConfigurationException e) {
throw new ResourceNotFoundException("No workflow with name " + workflowName + " is configured"); throw new ResourceNotFoundException("No workflow with name " + workflowName + " is configured");

View File

@@ -51,7 +51,7 @@ public class WorkflowStepActionsLinkRepository extends AbstractDSpaceRestReposit
@Nullable Pageable optionalPageable, @Nullable Pageable optionalPageable,
Projection projection) { Projection projection) {
List<WorkflowActionConfig> actions = xmlWorkflowFactory.getStepByName(workflowStepName).getActions(); List<WorkflowActionConfig> actions = xmlWorkflowFactory.getStepByName(workflowStepName).getActions();
Pageable pageable = optionalPageable != null ? optionalPageable : new PageRequest(0, 20); Pageable pageable = optionalPageable != null ? optionalPageable : PageRequest.of(0, 20);
return converter.toRestPage(utils.getPage(actions, pageable), projection); return converter.toRestPage(utils.getPage(actions, pageable), projection);
} }
} }

View File

@@ -32,8 +32,8 @@ import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import org.springframework.hateoas.Resource;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -286,7 +286,7 @@ public class ConverterService {
// scan all resource classes and look for compatible rest classes (by naming convention), // scan all resource classes and look for compatible rest classes (by naming convention),
// creating a map of resource constructors keyed by rest class, for later use. // creating a map of resource constructors keyed by rest class, for later use.
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false); ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new AssignableTypeFilter(Resource.class)); provider.addIncludeFilter(new AssignableTypeFilter(EntityModel.class));
Set<BeanDefinition> beanDefinitions = provider.findCandidateComponents( Set<BeanDefinition> beanDefinitions = provider.findCandidateComponents(
HALResource.class.getPackage().getName().replaceAll("\\.", "/")); HALResource.class.getPackage().getName().replaceAll("\\.", "/"));
for (BeanDefinition beanDefinition : beanDefinitions) { for (BeanDefinition beanDefinition : beanDefinitions) {

View File

@@ -7,7 +7,7 @@
*/ */
package org.dspace.app.rest.link; package org.dspace.app.rest.link;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import java.util.LinkedList; import java.util.LinkedList;
@@ -18,6 +18,7 @@ import org.dspace.app.rest.model.AuthorityRest;
import org.dspace.app.rest.model.hateoas.AuthorityEntryResource; import org.dspace.app.rest.model.hateoas.AuthorityEntryResource;
import org.dspace.app.rest.utils.AuthorityUtils; import org.dspace.app.rest.utils.AuthorityUtils;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.IanaLinkRelations;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
@@ -50,7 +51,7 @@ public class AuthorityEntryHalLinkFactory extends HalLinkFactory<AuthorityEntryR
String selfLinkString = linkTo( String selfLinkString = linkTo(
getMethodOn().findOne(entry.getCategory(), English.plural(entry.getType()), entry.getAuthorityName())) getMethodOn().findOne(entry.getCategory(), English.plural(entry.getType()), entry.getAuthorityName()))
.toUriComponentsBuilder().build().toString() + "/entryValues/" + entry.getId(); .toUriComponentsBuilder().build().toString() + "/entryValues/" + entry.getId();
list.add(buildLink(Link.REL_SELF, selfLinkString)); list.add(buildLink(IanaLinkRelations.SELF.value(), selfLinkString));
} }
protected Class<RestResourceController> getControllerClass() { protected Class<RestResourceController> getControllerClass() {

View File

@@ -22,6 +22,7 @@ import org.dspace.app.rest.model.hateoas.DSpaceResource;
import org.dspace.app.rest.utils.Utils; import org.dspace.app.rest.utils.Utils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.IanaLinkRelations;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -80,7 +81,7 @@ public class DSpaceResourceHalLinkFactory extends HalLinkFactory<DSpaceResource,
e.printStackTrace(); e.printStackTrace();
} }
halResource.add(utils.linkToSingleResource(data, Link.REL_SELF)); halResource.add(utils.linkToSingleResource(data, IanaLinkRelations.SELF.value()));
} }
protected Class<RestResourceController> getControllerClass() { protected Class<RestResourceController> getControllerClass() {

View File

@@ -7,8 +7,8 @@
*/ */
package org.dspace.app.rest.link; package org.dspace.app.rest.link;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;

View File

@@ -48,7 +48,7 @@ public class HalLinkService {
links.addAll(halLinkFactory.getLinksFor(halResource, pageable)); links.addAll(halLinkFactory.getLinksFor(halResource, pageable));
} }
links.sort((Link l1, Link l2) -> ObjectUtils.compare(l1.getRel(), l2.getRel())); links.sort((Link l1, Link l2) -> ObjectUtils.compare(l1.getRel().value(), l2.getRel().value()));
halResource.add(links); halResource.add(links);

View File

@@ -29,7 +29,8 @@ public class RootHalLinkFactory extends HalLinkFactory<RootResource, RootRestRes
protected void addLinks(RootResource halResource, Pageable page, LinkedList<Link> list) throws Exception { protected void addLinks(RootResource halResource, Pageable page, LinkedList<Link> list) throws Exception {
for (Link endpointLink : discoverableEndpointsService.getDiscoverableEndpoints()) { for (Link endpointLink : discoverableEndpointsService.getDiscoverableEndpoints()) {
list.add( list.add(
buildLink(endpointLink.getRel(), halResource.getContent().getDspaceRest() + endpointLink.getHref())); buildLink(endpointLink.getRel().value(),
halResource.getContent().getDspaceRest() + endpointLink.getHref()));
} }
} }

View File

@@ -7,7 +7,7 @@
*/ */
package org.dspace.app.rest.link; package org.dspace.app.rest.link;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import java.util.LinkedList; import java.util.LinkedList;

View File

@@ -13,6 +13,7 @@ import org.dspace.app.rest.ExternalSourcesRestController;
import org.dspace.app.rest.link.HalLinkFactory; import org.dspace.app.rest.link.HalLinkFactory;
import org.dspace.app.rest.model.hateoas.ExternalSourceEntryResource; import org.dspace.app.rest.model.hateoas.ExternalSourceEntryResource;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.IanaLinkRelations;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -27,7 +28,7 @@ public class ExternalSourceEntryHalLinkFactory
protected void addLinks(ExternalSourceEntryResource halResource, Pageable pageable, LinkedList<Link> list) protected void addLinks(ExternalSourceEntryResource halResource, Pageable pageable, LinkedList<Link> list)
throws Exception { throws Exception {
list.add(buildLink(Link.REL_SELF, list.add(buildLink(IanaLinkRelations.SELF.value(),
getMethodOn().getExternalSourceEntryValue(halResource.getContent().getExternalSource(), getMethodOn().getExternalSourceEntryValue(halResource.getContent().getExternalSource(),
halResource.getContent().getId()))); halResource.getContent().getId())));

View File

@@ -13,6 +13,7 @@ import java.util.UUID;
import org.dspace.app.rest.model.HarvestedCollectionRest; import org.dspace.app.rest.model.HarvestedCollectionRest;
import org.dspace.app.rest.model.hateoas.HarvestedCollectionResource; import org.dspace.app.rest.model.hateoas.HarvestedCollectionResource;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.IanaLinkRelations;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -31,7 +32,7 @@ public class HarvestedCollectionHalLinkFactory
if (data != null) { if (data != null) {
list.add( list.add(
buildLink( buildLink(
Link.REL_SELF, IanaLinkRelations.SELF.value(),
getMethodOn().get(UUID.fromString(data.getCollectionRest().getUuid()), null, null) getMethodOn().get(UUID.fromString(data.getCollectionRest().getUuid()), null, null)
) )
); );

View File

@@ -12,6 +12,7 @@ import java.util.LinkedList;
import org.dspace.app.rest.model.FacetConfigurationRest; import org.dspace.app.rest.model.FacetConfigurationRest;
import org.dspace.app.rest.model.hateoas.FacetConfigurationResource; import org.dspace.app.rest.model.hateoas.FacetConfigurationResource;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.IanaLinkRelations;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -31,7 +32,7 @@ public class FacetConfigurationResourceHalLinkFactory extends DiscoveryRestHalLi
FacetConfigurationRest data = halResource.getContent(); FacetConfigurationRest data = halResource.getContent();
if (data != null) { if (data != null) {
list.add(buildLink(Link.REL_SELF, getMethodOn() list.add(buildLink(IanaLinkRelations.SELF.value(), getMethodOn()
.getFacetsConfiguration(data.getScope(), data.getConfiguration(), page))); .getFacetsConfiguration(data.getScope(), data.getConfiguration(), page)));
} }
} }

View File

@@ -16,6 +16,7 @@ import org.dspace.app.rest.model.hateoas.FacetsResource;
import org.dspace.app.rest.model.hateoas.SearchFacetEntryResource; import org.dspace.app.rest.model.hateoas.SearchFacetEntryResource;
import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.IanaLinkRelations;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -34,7 +35,8 @@ public class FacetsResourceHalLinkFactory extends DiscoveryRestHalLinkFactory<Fa
halResource.setPageHeader(new EmbeddedPageHeader(buildSearchBaseLink(content), page)); halResource.setPageHeader(new EmbeddedPageHeader(buildSearchBaseLink(content), page));
list.add(buildLink(Link.REL_SELF, buildSearchFacetsBaseLink(content).build().toUriString())); list.add(buildLink(IanaLinkRelations.SELF.value(),
buildSearchFacetsBaseLink(content).build().toUriString()));
} }
} }

View File

@@ -14,6 +14,7 @@ import org.dspace.app.rest.link.HalLinkFactory;
import org.dspace.app.rest.model.SearchConfigurationRest; import org.dspace.app.rest.model.SearchConfigurationRest;
import org.dspace.app.rest.model.hateoas.SearchConfigurationResource; import org.dspace.app.rest.model.hateoas.SearchConfigurationResource;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.IanaLinkRelations;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -32,7 +33,7 @@ public class SearchConfigurationResourceHalLinkFactory
if (data != null) { if (data != null) {
list.add(buildLink(Link.REL_SELF, getMethodOn() list.add(buildLink(IanaLinkRelations.SELF.value(), getMethodOn()
.getSearchConfiguration(data.getScope(), data.getConfiguration()))); .getSearchConfiguration(data.getScope(), data.getConfiguration())));
list.add(buildLink("objects", getMethodOn().getSearchObjects(null, null, null, null, null, null))); list.add(buildLink("objects", getMethodOn().getSearchObjects(null, null, null, null, null, null)));

View File

@@ -18,6 +18,7 @@ import org.dspace.app.rest.model.hateoas.SearchFacetEntryResource;
import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.IanaLinkRelations;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
@@ -49,14 +50,14 @@ public class SearchFacetEntryHalLinkFactory extends DiscoveryRestHalLinkFactory<
//If our rest data contains a list of values, construct the page links. Otherwise, only add a self link //If our rest data contains a list of values, construct the page links. Otherwise, only add a self link
if (CollectionUtils.isNotEmpty(facetData.getValues())) { if (CollectionUtils.isNotEmpty(facetData.getValues())) {
PageImpl page = new PageImpl<>(facetData.getValues(), new PageRequest(0, facetData.getFacetLimit()), PageImpl page = new PageImpl<>(facetData.getValues(), PageRequest.of(0, facetData.getFacetLimit()),
facetData.getValues().size() + (BooleanUtils facetData.getValues().size() + (BooleanUtils
.isTrue(facetData.isHasMore()) ? 1 : 0)); .isTrue(facetData.isHasMore()) ? 1 : 0));
halResource.setPageHeader(new EmbeddedPageHeader(uriBuilder, page, false)); halResource.setPageHeader(new EmbeddedPageHeader(uriBuilder, page, false));
} else { } else {
list.add(buildLink(Link.REL_SELF, uriBuilder.build().toUriString())); list.add(buildLink(IanaLinkRelations.SELF.value(), uriBuilder.build().toUriString()));
} }
} }

View File

@@ -12,6 +12,7 @@ import java.util.LinkedList;
import org.dspace.app.rest.model.SearchResultsRest; import org.dspace.app.rest.model.SearchResultsRest;
import org.dspace.app.rest.model.hateoas.SearchResultsResource; import org.dspace.app.rest.model.hateoas.SearchResultsResource;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.IanaLinkRelations;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -26,7 +27,7 @@ public class SearchResultsResourceHalLinkFactory extends DiscoveryRestHalLinkFac
throws Exception { throws Exception {
SearchResultsRest resultsRest = halResource.getContent(); SearchResultsRest resultsRest = halResource.getContent();
list.add(buildLink(Link.REL_SELF, buildSearchBaseLink(resultsRest).toUriString())); list.add(buildLink(IanaLinkRelations.SELF.value(), buildSearchBaseLink(resultsRest).toUriString()));
} }
@Override @Override
@@ -35,4 +36,4 @@ public class SearchResultsResourceHalLinkFactory extends DiscoveryRestHalLinkFac
} }
} }

View File

@@ -13,6 +13,7 @@ import org.dspace.app.rest.DiscoveryRestController;
import org.dspace.app.rest.link.HalLinkFactory; import org.dspace.app.rest.link.HalLinkFactory;
import org.dspace.app.rest.model.hateoas.SearchSupportResource; import org.dspace.app.rest.model.hateoas.SearchSupportResource;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.IanaLinkRelations;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -26,7 +27,7 @@ public class SearchSupportHalLinkFactory extends HalLinkFactory<SearchSupportRes
protected void addLinks(SearchSupportResource halResource, Pageable pageable, LinkedList<Link> list) protected void addLinks(SearchSupportResource halResource, Pageable pageable, LinkedList<Link> list)
throws Exception { throws Exception {
list.add(buildLink(Link.REL_SELF, getMethodOn() list.add(buildLink(IanaLinkRelations.SELF.value(), getMethodOn()
.getSearchSupport(null, null))); .getSearchSupport(null, null)));
list.add(buildLink("search", getMethodOn().getSearchConfiguration(null, null))); list.add(buildLink("search", getMethodOn().getSearchConfiguration(null, null)));
list.add(buildLink("facets", getMethodOn().getFacetsConfiguration(null, null, pageable))); list.add(buildLink("facets", getMethodOn().getFacetsConfiguration(null, null, pageable)));

View File

@@ -13,6 +13,7 @@ import org.dspace.app.rest.StatisticsRestController;
import org.dspace.app.rest.link.HalLinkFactory; import org.dspace.app.rest.link.HalLinkFactory;
import org.dspace.app.rest.model.hateoas.StatisticsSupportResource; import org.dspace.app.rest.model.hateoas.StatisticsSupportResource;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.IanaLinkRelations;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -22,7 +23,7 @@ public class StatisticsSupportHalLinkFactory
protected void addLinks(StatisticsSupportResource halResource, Pageable pageable, LinkedList<Link> list) protected void addLinks(StatisticsSupportResource halResource, Pageable pageable, LinkedList<Link> list)
throws Exception { throws Exception {
list.add(buildLink(Link.REL_SELF, getMethodOn().getStatisticsSupport())); list.add(buildLink(IanaLinkRelations.SELF.value(), getMethodOn().getStatisticsSupport()));
list.add(buildLink("viewevents", getMethodOn().getViewEvents())); list.add(buildLink("viewevents", getMethodOn().getViewEvents()));
list.add(buildLink("searchevents", getMethodOn().getSearchEvents())); list.add(buildLink("searchevents", getMethodOn().getSearchEvents()));
} }

View File

@@ -13,22 +13,20 @@ import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonInclude.Include;
import org.springframework.hateoas.Identifiable;
/** /**
* Base class for any REST resource that need to be addressable * Base class for any REST resource that need to be addressable and identifiable (via an ID)
* *
* @param <T> the class of the resource identifier * @param <T> the class of the resource identifier
* @author Andrea Bollini (andrea.bollini at 4science.it) * @author Andrea Bollini (andrea.bollini at 4science.it)
*/ */
public abstract class BaseObjectRest<T extends Serializable> extends RestAddressableModel implements Identifiable<T> { public abstract class BaseObjectRest<T extends Serializable> extends RestAddressableModel {
protected T id; protected T id;
@JsonInclude(Include.NON_EMPTY) @JsonInclude(Include.NON_EMPTY)
private List<ErrorRest> errors; private List<ErrorRest> errors;
@Override
public T getId() { public T getId() {
return id; return id;
} }

View File

@@ -9,21 +9,22 @@ package org.dspace.app.rest.model.hateoas;
import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource; import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource;
import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.hateoas.core.EvoInflectorRelProvider; import org.springframework.hateoas.LinkRelation;
import org.springframework.hateoas.server.core.EvoInflectorLinkRelationProvider;
/** /**
* A DSpace Relation Provider that use the RelNameDSpaceResource to use the * A DSpace Link Relation Provider that use the RelNameDSpaceResource annotation to use the
* right names for the embedded collection when a DSpaceResource is requested * right names for the embedded collection when a DSpaceResource is requested
* *
* @author Andrea Bollini (andrea.bollini at 4science.it) * @author Andrea Bollini (andrea.bollini at 4science.it)
*/ */
public class DSpaceRelProvider extends EvoInflectorRelProvider { public class DSpaceLinkRelationProvider extends EvoInflectorLinkRelationProvider {
@Override @Override
public String getItemResourceRelFor(Class<?> type) { public LinkRelation getItemResourceRelFor(Class<?> type) {
RelNameDSpaceResource nameAnnotation = AnnotationUtils.findAnnotation(type, RelNameDSpaceResource.class); RelNameDSpaceResource nameAnnotation = AnnotationUtils.findAnnotation(type, RelNameDSpaceResource.class);
if (nameAnnotation != null) { if (nameAnnotation != null) {
return nameAnnotation.value(); return LinkRelation.of(nameAnnotation.value());
} }
return super.getItemResourceRelFor(type); return super.getItemResourceRelFor(type);
} }

View File

@@ -13,13 +13,13 @@ import java.util.Map;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonUnwrapped; import com.fasterxml.jackson.annotation.JsonUnwrapped;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import org.springframework.hateoas.Resource;
/** /**
* The abstract, generic class for the HalResources * The abstract, generic class for the HalResources
*/ */
public abstract class HALResource<T> extends Resource<T> { public abstract class HALResource<T> extends EntityModel<T> {
public HALResource(T content) { public HALResource(T content) {
super(content); super(content);
@@ -46,9 +46,10 @@ public abstract class HALResource<T> extends Resource<T> {
} }
@Override @Override
public void add(Link link) { public EntityModel<T> add(Link link) {
if (!hasLink(link.getRel())) { if (!hasLink(link.getRel())) {
super.add(link); return super.add(link);
} }
return this;
} }
} }

View File

@@ -44,7 +44,7 @@ public class EmbedRelsProjection extends AbstractProjection {
StringBuilder fullName = new StringBuilder(); StringBuilder fullName = new StringBuilder();
for (Link oldLink : oldLinks) { for (Link oldLink : oldLinks) {
fullName.append(oldLink.getRel()).append("/"); fullName.append(oldLink.getRel().value()).append("/");
} }
fullName.append(linkRest.name()); fullName.append(linkRest.name());
// If the full name matches, the link can be embedded (e.g. mappedItems/owningCollection on a collection page) // If the full name matches, the link can be embedded (e.g. mappedItems/owningCollection on a collection page)

View File

@@ -115,7 +115,7 @@ public class BrowseEntryLinkRepository extends AbstractDSpaceRestRepository
} }
BrowseInfo binfo = be.browse(bs); BrowseInfo binfo = be.browse(bs);
Pageable pageResultInfo = new PageRequest((binfo.getStart() - 1) / binfo.getResultsPerPage(), Pageable pageResultInfo = PageRequest.of((binfo.getStart() - 1) / binfo.getResultsPerPage(),
binfo.getResultsPerPage()); binfo.getResultsPerPage());
Page<BrowseEntryRest> page = new PageImpl<>(Arrays.asList(binfo.getStringResults()), pageResultInfo, Page<BrowseEntryRest> page = new PageImpl<>(Arrays.asList(binfo.getStringResults()), pageResultInfo,
binfo.getTotal()).map(browseEntryConverter); binfo.getTotal()).map(browseEntryConverter);

View File

@@ -143,7 +143,7 @@ public class BrowseItemLinkRepository extends AbstractDSpaceRestRepository
BrowseInfo binfo = be.browse(bs); BrowseInfo binfo = be.browse(bs);
Pageable pageResultInfo = Pageable pageResultInfo =
new PageRequest((binfo.getStart() - 1) / binfo.getResultsPerPage(), binfo.getResultsPerPage()); PageRequest.of((binfo.getStart() - 1) / binfo.getResultsPerPage(), binfo.getResultsPerPage());
List<Item> tmpResult = new ArrayList<Item>(); List<Item> tmpResult = new ArrayList<Item>();
for (Item bb : binfo.getBrowseItemResults()) { for (Item bb : binfo.getBrowseItemResults()) {
tmpResult.add(bb); tmpResult.add(bb);

View File

@@ -161,7 +161,7 @@ public class DiscoveryRestRepository extends AbstractDSpaceRestRepository {
List<SearchFilter> searchFilters) { List<SearchFilter> searchFilters) {
Context context = obtainContext(); Context context = obtainContext();
Pageable page = new PageRequest(1, 1); Pageable page = PageRequest.of(1, 1);
IndexableObject scopeObject = scopeResolver.resolveScope(context, dsoScope); IndexableObject scopeObject = scopeResolver.resolveScope(context, dsoScope);
DiscoveryConfiguration discoveryConfiguration = searchConfigurationService DiscoveryConfiguration discoveryConfiguration = searchConfigurationService
.getDiscoveryConfigurationByNameOrDso(configuration, scopeObject); .getDiscoveryConfigurationByNameOrDso(configuration, scopeObject);

View File

@@ -63,7 +63,7 @@ public class VersionsLinkRepository extends AbstractDSpaceRestRepository
" couldn't be found"); " couldn't be found");
} }
List<Version> versions = versioningService.getVersionsByHistory(context, versionHistory); List<Version> versions = versioningService.getVersionsByHistory(context, versionHistory);
Pageable pageable = optionalPageable != null ? optionalPageable : new PageRequest(0, 20); Pageable pageable = optionalPageable != null ? optionalPageable : PageRequest.of(0, 20);
return converter.toRestPage(utils.getPage(versions, pageable), projection); return converter.toRestPage(utils.getPage(versions, pageable), projection);
} }
} }

View File

@@ -29,8 +29,8 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.data.repository.support.QueryMethodParameterConversionException; import org.springframework.data.repository.support.QueryMethodParameterConversionException;
import org.springframework.data.web.PagedResourcesAssembler; import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.core.AnnotationAttribute; import org.springframework.hateoas.server.core.AnnotationAttribute;
import org.springframework.hateoas.core.MethodParameters; import org.springframework.hateoas.server.core.MethodParameters;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;

View File

@@ -9,7 +9,7 @@ package org.dspace.app.rest.utils;
import static java.lang.Integer.parseInt; import static java.lang.Integer.parseInt;
import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toList;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import java.beans.IntrospectionException; import java.beans.IntrospectionException;
import java.beans.Introspector; import java.beans.Introspector;
@@ -57,7 +57,6 @@ import org.dspace.app.rest.model.ResourcePolicyRest;
import org.dspace.app.rest.model.RestAddressableModel; import org.dspace.app.rest.model.RestAddressableModel;
import org.dspace.app.rest.model.RestModel; import org.dspace.app.rest.model.RestModel;
import org.dspace.app.rest.model.VersionHistoryRest; import org.dspace.app.rest.model.VersionHistoryRest;
import org.dspace.app.rest.model.hateoas.DSpaceResource;
import org.dspace.app.rest.model.hateoas.EmbeddedPage; import org.dspace.app.rest.model.hateoas.EmbeddedPage;
import org.dspace.app.rest.model.hateoas.HALResource; import org.dspace.app.rest.model.hateoas.HALResource;
import org.dspace.app.rest.projection.CompositeProjection; import org.dspace.app.rest.projection.CompositeProjection;
@@ -159,32 +158,64 @@ public class Utils {
* @return the existing instance if it is not null, a default pageable instance otherwise. * @return the existing instance if it is not null, a default pageable instance otherwise.
*/ */
public Pageable getPageable(@Nullable Pageable optionalPageable) { public Pageable getPageable(@Nullable Pageable optionalPageable) {
return optionalPageable != null ? optionalPageable : new PageRequest(0, DEFAULT_PAGE_SIZE); return optionalPageable != null ? optionalPageable : PageRequest.of(0, DEFAULT_PAGE_SIZE);
}
public Link linkToSingleResource(DSpaceResource r, String rel) {
RestAddressableModel data = r.getContent();
return linkToSingleResource(data, rel);
} }
/**
* Create a HAL Link to a single resource
* @param data the resource itself
* @param rel name of the link relation to create
* @return created Link object
*/
public Link linkToSingleResource(RestAddressableModel data, String rel) { public Link linkToSingleResource(RestAddressableModel data, String rel) {
return linkTo(data.getController(), data.getCategory(), data.getTypePlural()).slash(data) // Create link using Spring HATEOAS link builder
return linkTo(data.getController(), data.getCategory(), data.getTypePlural()).slash(getIdentifierForLink(data))
.withRel(rel); .withRel(rel);
} }
/**
* Create a HAL Link to a subresource of given resource. This method assumes the name & link to the subresource
* are both the same string value. See other linkToSubResource method if they are different.
* @param data main resource
* @param rel name/subpath of the subresource (assumed to be the same)
* @return created Link object
*/
public Link linkToSubResource(RestAddressableModel data, String rel) { public Link linkToSubResource(RestAddressableModel data, String rel) {
return linkToSubResource(data, rel, rel); return linkToSubResource(data, rel, rel);
} }
/**
* Create a HAL Link to a subresource of given resource using given path name and link name
* @param data main resource
* @param rel name of the subresource link relation to create
* @param path subpath for the subresource
* @return created Link object
*/
public Link linkToSubResource(RestAddressableModel data, String rel, String path) { public Link linkToSubResource(RestAddressableModel data, String rel, String path) {
return linkTo(data.getController(), data.getCategory(), data.getTypePlural()).slash(data).slash(path) // Create link using Spring HATEOAS link builder
return linkTo(data.getController(), data.getCategory(), data.getTypePlural()).slash(getIdentifierForLink(data))
.slash(path)
.withRel(rel); .withRel(rel);
} }
/**
* Returns an identifier for a given resource, to be used in a Link.
* @param data resource to identify
* @return identifier, which is either an ID (if exists) or string representation of the object.
*/
private Serializable getIdentifierForLink(RestAddressableModel data) {
// If the resource is identifiable by an ID, use it. Otherwise use toString() to represent it.
Serializable identifier = data.toString();
if (data instanceof BaseObjectRest) {
identifier = ((BaseObjectRest) data).getId();
}
return identifier;
}
/** /**
* Retrieve the {@link DSpaceRestRepository} for the specified category and model in the plural form as used in the endpoints. * Retrieve the {@link DSpaceRestRepository} for the specified category and model in the plural form as used in the endpoints.
* If the model is available in its singular form use {@link #getResourceRepositoryByCategoryAndModel(String, String)} * If the model is available in its singular form use {@link #getResourceRepositoryByCategoryAndModel(String, String)}
* *
* @param apiCategory * @param apiCategory
* @param modelPlural * @param modelPlural
* @return * @return
@@ -197,7 +228,7 @@ public class Utils {
/** /**
* Retrieve the {@link DSpaceRestRepository} for the specified category and model. The model is in the singular form * Retrieve the {@link DSpaceRestRepository} for the specified category and model. The model is in the singular form
* as returned by the {@link RestAddressableModel#getType()} method * as returned by the {@link RestAddressableModel#getType()} method
* *
* @param apiCategory * @param apiCategory
* @param modelSingular * @param modelSingular
* @return * @return
@@ -278,7 +309,7 @@ public class Utils {
/** /**
* Create a temporary file from a multipart file upload * Create a temporary file from a multipart file upload
* *
* @param multipartFile * @param multipartFile
* the multipartFile representing the uploaded file. Please note that it is a complex object including * the multipartFile representing the uploaded file. Please note that it is a complex object including
* additional information other than the binary like the orginal file name and the mimetype * additional information other than the binary like the orginal file name and the mimetype
@@ -312,7 +343,7 @@ public class Utils {
/** /**
* Return the filename part from a multipartFile upload that could eventually contains the fullpath on the client * Return the filename part from a multipartFile upload that could eventually contains the fullpath on the client
* *
* @param multipartFile * @param multipartFile
* the file uploaded * the file uploaded
* @return the filename part of the file on the client filesystem * @return the filename part of the file on the client filesystem
@@ -771,23 +802,23 @@ public class Utils {
return new EmbeddedPage(link.getHref(), page.map((restObject) -> { return new EmbeddedPage(link.getHref(), page.map((restObject) -> {
restObject.setEmbedLevel(childEmbedLevel); restObject.setEmbedLevel(childEmbedLevel);
return converter.toResource(restObject, newList); return converter.toResource(restObject, newList);
}), null, link.getRel()); }), null, link.getRel().value());
} else if (linkedObject instanceof List) { } else if (linkedObject instanceof List) {
// The full list has been retrieved and we need to provide the first page for embedding // The full list has been retrieved and we need to provide the first page for embedding
List<RestAddressableModel> list = (List<RestAddressableModel>) linkedObject; List<RestAddressableModel> list = (List<RestAddressableModel>) linkedObject;
if (list.size() > 0) { if (list.size() > 0) {
PageImpl<RestAddressableModel> page = new PageImpl( PageImpl<RestAddressableModel> page = new PageImpl(
list.subList(0, list.size() > DEFAULT_PAGE_SIZE ? DEFAULT_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()); PageRequest.of(0, DEFAULT_PAGE_SIZE), list.size());
return new EmbeddedPage(link.getHref(), return new EmbeddedPage(link.getHref(),
page.map((restObject) -> { page.map((restObject) -> {
restObject.setEmbedLevel(childEmbedLevel); restObject.setEmbedLevel(childEmbedLevel);
return converter.toResource(restObject, newList); return converter.toResource(restObject, newList);
}), }),
list, link.getRel()); list, link.getRel().value());
} else { } else {
PageImpl<RestAddressableModel> page = new PageImpl(list); PageImpl<RestAddressableModel> page = new PageImpl(list);
return new EmbeddedPage(link.getHref(), page, list, link.getRel()); return new EmbeddedPage(link.getHref(), page, list, link.getRel().value());
} }
} else { } else {
return linkedObject; return linkedObject;
@@ -823,7 +854,7 @@ public class Utils {
/** /**
* Convert the input string in the primary key class according to the repository interface * Convert the input string in the primary key class according to the repository interface
* *
* @param repository * @param repository
* @param pkStr * @param pkStr
* @return * @return
@@ -837,7 +868,7 @@ public class Utils {
* rest object is supported by a {@link DSpaceRestRepository} that also implement the * rest object is supported by a {@link DSpaceRestRepository} that also implement the
* {@link ReloadableEntityObjectRepository} interface. If this is not the case the method will throw an * {@link ReloadableEntityObjectRepository} interface. If this is not the case the method will throw an
* IllegalArgumentException * IllegalArgumentException
* *
* @param context * @param context
* the DSpace Context * the DSpace Context
* @param restObj * @param restObj
@@ -859,7 +890,7 @@ public class Utils {
/** /**
* Get the rest object associated with the specified URI * Get the rest object associated with the specified URI
* *
* @param context the DSpace context * @param context the DSpace context
* @param uri the uri of a {@link BaseObjectRest} * @param uri the uri of a {@link BaseObjectRest}
* @return the {@link BaseObjectRest} identified by the provided uri * @return the {@link BaseObjectRest} identified by the provided uri

View File

@@ -34,8 +34,8 @@ import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mock; import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import org.springframework.hateoas.Resource;
/** /**
* Tests functionality of {@link ConverterService}. * Tests functionality of {@link ConverterService}.
@@ -153,7 +153,7 @@ public class ConverterServiceIT extends AbstractControllerIntegrationTest {
assertHasEmbeds(resource, new String[] { assertHasEmbeds(resource, new String[] {
"restPropUnannotated" // embedded; unannotated properties can't be omitted by projections "restPropUnannotated" // embedded; unannotated properties can't be omitted by projections
}, new Class[] { }, new Class[] {
Resource.class EntityModel.class
}); });
assertHasLinks(resource, new String[] { assertHasLinks(resource, new String[] {
@@ -182,7 +182,8 @@ public class ConverterServiceIT extends AbstractControllerIntegrationTest {
r0.setRestPropUnannotated(restPropUnannotatedValue); r0.setRestPropUnannotated(restPropUnannotatedValue);
String r0json = new ObjectMapper().writeValueAsString(r0); String r0json = new ObjectMapper().writeValueAsString(r0);
when(mockLink.getRel()).thenReturn("mockLink"); // return "mockLink" LinkRelation when getRel() is called
when(mockLink.getRel()).thenReturn(() -> "mockLink");
r0.setProjection(new MockProjection(mockLink, mockEmbeddedResource)); r0.setProjection(new MockProjection(mockLink, mockEmbeddedResource));
MockObjectResource resource = converter.toResource(r0); MockObjectResource resource = converter.toResource(r0);
@@ -198,10 +199,10 @@ public class ConverterServiceIT extends AbstractControllerIntegrationTest {
"optionallyEmbeddedChildren", "optionallyEmbeddedChildren",
"resource" // added by MockProjection "resource" // added by MockProjection
}, new Class[] { }, new Class[] {
Resource.class, EntityModel.class,
null, null,
Resource.class, EntityModel.class,
Resource.class, EntityModel.class,
EmbeddedPage.class, EmbeddedPage.class,
Object.class Object.class
}); });
@@ -217,9 +218,9 @@ public class ConverterServiceIT extends AbstractControllerIntegrationTest {
}); });
} }
private void assertHasLinks(Resource resource, String[] rels) { private void assertHasLinks(EntityModel resource, String[] rels) {
Map<String, Link> map = new HashMap<>(); Map<String, Link> map = new HashMap<>();
resource.getLinks().stream().forEach((link) -> map.put(link.getRel(), link)); resource.getLinks().stream().forEach((link) -> map.put(link.getRel().value(), link));
assertThat(new TreeSet(map.keySet()), equalTo(new TreeSet(Sets.newHashSet(rels)))); assertThat(new TreeSet(map.keySet()), equalTo(new TreeSet(Sets.newHashSet(rels))));
} }

View File

@@ -16,7 +16,7 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import org.springframework.hateoas.mvc.ControllerLinkBuilder; import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
/** /**
* This class' purpose is to test the FacetConfigurationResourceHalLinkFactory * This class' purpose is to test the FacetConfigurationResourceHalLinkFactory
@@ -25,7 +25,7 @@ public class FacetConfigurationResourceHalLinkFactoryTest {
@Mock @Mock
ControllerLinkBuilder controllerLinkBuilder; WebMvcLinkBuilder webMvcLinkBuilder;
@Mock @Mock
HalLinkFactory halLinkFactory; HalLinkFactory halLinkFactory;

View File

@@ -16,16 +16,15 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import org.springframework.hateoas.mvc.ControllerLinkBuilder; import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
/** /**
* This class' purpose is to test the SearchConfigurationResourceHalLinkFactory * This class' purpose is to test the SearchConfigurationResourceHalLinkFactory
*/ */
public class SearchConfigurationResourceHalLinkFactoryTest { public class SearchConfigurationResourceHalLinkFactoryTest {
@Mock @Mock
ControllerLinkBuilder controllerLinkBuilder; WebMvcLinkBuilder webMvcLinkBuilder;
@Mock @Mock
HalLinkFactory halLinkFactory; HalLinkFactory halLinkFactory;

View File

@@ -11,7 +11,6 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup; import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
import java.nio.charset.StandardCharsets;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@@ -58,7 +57,7 @@ import org.springframework.web.context.WebApplicationContext;
* @author Tim Donohue * @author Tim Donohue
* @see org.dspace.app.rest.test.AbstractWebClientIntegrationTest * @see org.dspace.app.rest.test.AbstractWebClientIntegrationTest
*/ */
// Run tests with JUnit 4 and Spring TestContext Framework // Run tests with JUnit and Spring TestContext Framework
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
// Specify main class to use to load Spring ApplicationContext // Specify main class to use to load Spring ApplicationContext
// NOTE: By default, Spring caches and reuses ApplicationContext for each integration test (to speed up tests) // NOTE: By default, Spring caches and reuses ApplicationContext for each integration test (to speed up tests)
@@ -81,7 +80,7 @@ public class AbstractControllerIntegrationTest extends AbstractIntegrationTestWi
public static final String BASE_REST_SERVER_URL = "http://localhost"; public static final String BASE_REST_SERVER_URL = "http://localhost";
protected MediaType contentType = new MediaType(MediaTypes.HAL_JSON.getType(), protected MediaType contentType = new MediaType(MediaTypes.HAL_JSON.getType(),
MediaTypes.HAL_JSON.getSubtype(), StandardCharsets.UTF_8); MediaTypes.HAL_JSON.getSubtype());
protected MediaType textUriContentType = RestMediaTypes.TEXT_URI_LIST; protected MediaType textUriContentType = RestMediaTypes.TEXT_URI_LIST;
@@ -121,7 +120,7 @@ public class AbstractControllerIntegrationTest extends AbstractIntegrationTestWi
if (StringUtils.isNotBlank(authToken)) { if (StringUtils.isNotBlank(authToken)) {
mockMvcBuilder.defaultRequest( mockMvcBuilder.defaultRequest(
get("").header(AUTHORIZATION_HEADER, AUTHORIZATION_TYPE + authToken)); get("/").header(AUTHORIZATION_HEADER, AUTHORIZATION_TYPE + authToken));
} }
return mockMvcBuilder return mockMvcBuilder

View File

@@ -168,7 +168,7 @@ public class DiscoverQueryBuilderTest {
query = "my test case"; query = "my test case";
searchFilter = new SearchFilter("subject", "equals", "Java"); searchFilter = new SearchFilter("subject", "equals", "Java");
page = new PageRequest(1, 10, Sort.Direction.ASC, "dc.title"); page = PageRequest.of(1, 10, Sort.Direction.ASC, "dc.title");
queryBuilder.afterPropertiesSet(); queryBuilder.afterPropertiesSet();
} }
@@ -230,7 +230,7 @@ public class DiscoverQueryBuilderTest {
@Test @Test
public void testSortByScore() throws Exception { public void testSortByScore() throws Exception {
page = new PageRequest(2, 10, Sort.Direction.ASC, "SCORE"); page = PageRequest.of(2, 10, Sort.Direction.ASC, "SCORE");
DiscoverQuery discoverQuery = DiscoverQuery discoverQuery =
queryBuilder.buildQuery(context, null, discoveryConfiguration, null, null, null, page); queryBuilder.buildQuery(context, null, discoveryConfiguration, null, null, null, page);
@@ -346,4 +346,4 @@ public class DiscoverQueryBuilderTest {
} }
}; };
} }
} }

View File

@@ -234,39 +234,16 @@ just adding new jar in the classloader</description>
<type>war</type> <type>war</type>
</dependency> </dependency>
<dependency> <!-- Test Dependencies -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<exclusions>
<!-- Temporary exclusion to avoid dependency conflict with version of org.json:json used by dspace-api.
NOTE: THIS CAN BE REMOVED ONCE WE UPGRADE TO SPRING-BOOT v1.5 (or above), see DS-3802
As of Spring-Boot 1.5, org.json:json is no longer used by spring-boot-starter-test -->
<exclusion>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</exclusion>
<!-- More recent version used for testing below -->
<exclusion>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
</exclusion>
</exclusions>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.jayway.jsonpath</groupId> <groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path-assert</artifactId> <artifactId>json-path-assert</artifactId>
<version>${json-path.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
@@ -279,10 +256,69 @@ just adding new jar in the classloader</description>
<artifactId>h2</artifactId> <artifactId>h2</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.apache.solr</groupId> <groupId>org.apache.solr</groupId>
<artifactId>solr-cell</artifactId> <artifactId>solr-cell</artifactId>
<scope>test</scope> <scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-continuation</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-deploy</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-http</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-io</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jmx</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-rewrite</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-security</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlets</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-xml</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<!-- Reminder: Keep icu4j (in Parent POM) synced with version used by lucene-analyzers-icu below, <!-- Reminder: Keep icu4j (in Parent POM) synced with version used by lucene-analyzers-icu below,
otherwise ICUFoldingFilterFactory may throw errors in tests. --> otherwise ICUFoldingFilterFactory may throw errors in tests. -->

109
pom.xml
View File

@@ -17,34 +17,50 @@
</organization> </organization>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!--=== GENERAL / DSPACE-API DEPENDENCIES ===-->
<project.reporting.outputEncoding>${project.build.sourceEncoding}</project.reporting.outputEncoding>
<java.version>11</java.version> <java.version>11</java.version>
<pdfbox-version>2.0.15</pdfbox-version> <spring.version>5.2.5.RELEASE</spring.version>
<poi-version>3.17</poi-version> <spring-boot.version>2.2.6.RELEASE</spring-boot.version>
<postgresql.driver.version>42.2.9</postgresql.driver.version>
<!-- PIN Jena to 2.x until both RDF and SWORDv2 can be updated to Jena 3. Requires package renaming, see
https://jena.apache.org/documentation/migrate_jena2_jena3.html -->
<jena.version>2.13.0</jena.version>
<jaxb-api.version>2.3.1</jaxb-api.version>
<jaxb-runtime.version>2.3.1</jaxb-runtime.version>
<javax-annotation.version>1.3.2</javax-annotation.version>
<axiom.version>1.2.22</axiom.version>
<errorprone.version>2.3.4</errorprone.version>
<log4j.version>2.11.2</log4j.version>
<slf4j.version>1.7.25</slf4j.version>
<!-- NOTE: when updating jackson.version, also sync jackson-databind dependency below -->
<jackson.version>2.10.2</jackson.version>
<jersey.version>2.28</jersey.version>
<hibernate.version>5.4.10.Final</hibernate.version> <hibernate.version>5.4.10.Final</hibernate.version>
<hibernate-validator.version>6.0.17.Final</hibernate-validator.version> <hibernate-validator.version>6.0.18.Final</hibernate-validator.version>
<postgresql.driver.version>42.2.9</postgresql.driver.version>
<!-- PIN Solr to 7.3.x until SOLR-12858 is fixed. This bug affects all integration tests that use Solr <!-- PIN Solr to 7.3.x until SOLR-12858 is fixed. This bug affects all integration tests that use Solr
https://issues.apache.org/jira/browse/SOLR-12858 --> https://issues.apache.org/jira/browse/SOLR-12858 -->
<solr.client.version>7.3.1</solr.client.version> <solr.client.version>7.3.1</solr.client.version>
<spring.version>5.1.9.RELEASE</spring.version>
<spring-boot.version>2.1.8.RELEASE</spring-boot.version> <axiom.version>1.2.22</axiom.version>
<!-- Library for reading JSON documents: https://github.com/json-path/JsonPath --> <errorprone.version>2.3.4</errorprone.version>
<!-- NOTE: when updating jackson.version, also sync jackson-databind dependency below -->
<jackson.version>2.10.2</jackson.version>
<javax-annotation.version>1.3.2</javax-annotation.version>
<jaxb-api.version>2.3.1</jaxb-api.version>
<jaxb-runtime.version>2.3.1</jaxb-runtime.version>
<!-- NOTE: Jetty needed for Handle Server & tests. Should be synced with version provided by solr-cell -->
<jetty.version>9.4.8.v20171121</jetty.version>
<log4j.version>2.11.2</log4j.version>
<pdfbox-version>2.0.15</pdfbox-version>
<poi-version>3.17</poi-version>
<slf4j.version>1.7.25</slf4j.version>
<!--=== SERVER WEBAPP DEPENDENCIES ===-->
<!-- Spring Data REST HAL Browser (used by Server webapp) -->
<spring-hal-browser.version>3.2.6.RELEASE</spring-hal-browser.version>
<!-- Library for reading JSON documents: https://github.com/json-path/JsonPath (used by Server webapp) -->
<json-path.version>2.4.0</json-path.version> <json-path.version>2.4.0</json-path.version>
<!-- Library for managing JSON Web Tokens (JWT): https://bitbucket.org/connect2id/nimbus-jose-jwt/wiki/Home
(used by Server webapp) -->
<nimbus-jose-jwt.version>7.9</nimbus-jose-jwt.version>
<!--=== OTHER MODULE-SPECIFIC DEPENDENCIES ===-->
<!-- PIN Jena to 2.x until both RDF and SWORDv2 can be updated to Jena 3. Requires package renaming, see
https://jena.apache.org/documentation/migrate_jena2_jena3.html -->
<jena.version>2.13.0</jena.version>
<!-- Used by (now obsolete) 'dspace-rest' WAR -->
<jersey.version>2.30.1</jersey.version>
<!--=== MAVEN SETTINGS ===-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>${project.build.sourceEncoding}</project.reporting.outputEncoding>
<!-- 'root.basedir' is the path to the root [dspace-src] dir. It must be redefined by each child POM, <!-- 'root.basedir' is the path to the root [dspace-src] dir. It must be redefined by each child POM,
as it is used to reference the LICENSE_HEADER and *.properties file(s) in that directory. --> as it is used to reference the LICENSE_HEADER and *.properties file(s) in that directory. -->
<root.basedir>${basedir}</root.basedir> <root.basedir>${basedir}</root.basedir>
@@ -1064,7 +1080,7 @@
<dependency> <dependency>
<groupId>org.ow2.asm</groupId> <groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId> <artifactId>asm</artifactId>
<version>5.1</version> <version>7.1</version>
</dependency> </dependency>
<dependency> <dependency>
@@ -1168,21 +1184,22 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot.version}</version> <version>${spring-boot.version}</version>
<scope>test</scope>
<exclusions> <exclusions>
<!-- Temporary exclusion to avoid dependency conflict with version of org.json:json used by dspace-api. <!-- We are still using JUnit 4, while Spring Boot defaults to JUnit 5 -->
NOTE: THIS CAN BE REMOVED ONCE WE UPGRADE TO SPRING-BOOT v1.5 (or above), see DS-3802
As of Spring-Boot 1.5, org.json:json is no longer used by spring-boot-starter-test -->
<exclusion> <exclusion>
<groupId>org.json</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>json</artifactId> <artifactId>junit-jupiter</artifactId>
</exclusion> </exclusion>
<!-- More recent version used for testing below -->
<exclusion> <exclusion>
<groupId>com.jayway.jsonpath</groupId> <groupId>org.junit.vintage</groupId>
<artifactId>json-path</artifactId> <artifactId>junit-vintage-engine</artifactId>
</exclusion>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
</exclusion> </exclusion>
</exclusions> </exclusions>
<scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
@@ -1199,19 +1216,6 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path-assert</artifactId>
<version>${json-path.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>${json-path.version}</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.apache.ant</groupId> <groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId> <artifactId>ant</artifactId>
@@ -1234,16 +1238,11 @@
<artifactId>handle</artifactId> <artifactId>handle</artifactId>
<version>9.1.0.v20190416</version> <version>9.1.0.v20190416</version>
</dependency> </dependency>
<!-- Jetty is needed to run Handle Server (and tests in some modules) -->
<dependency> <dependency>
<groupId>org.eclipse.jetty.aggregate</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-all</artifactId> <artifactId>jetty-server</artifactId>
<version>8.1.22.v20160922</version> <version>${jetty.version}</version>
<exclusions>
<exclusion>
<artifactId>javax.servlet</artifactId>
<groupId>org.eclipse.jetty.orbit</groupId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
@@ -1576,7 +1575,7 @@
<dependency> <dependency>
<groupId>org.mockito</groupId> <groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId> <artifactId>mockito-core</artifactId>
<version>2.28.2</version> <version>3.1.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- H2 is an in-memory database used for Unit/Integration tests --> <!-- H2 is an in-memory database used for Unit/Integration tests -->