TSK-422: HATEOAS support for ClassificationController.

This commit is contained in:
Holger Hagen 2018-04-06 08:41:56 +02:00 committed by Martin Rojas Miguel Angel
parent 9cacb892c6
commit 1d58cb39e1
9 changed files with 358 additions and 52 deletions

View File

@ -37,7 +37,7 @@ public class QueryClassificationAccTest extends AbstractAccTest {
columnValueList = classificationService.createClassificationQuery()
.listValues("TYPE", null);
assertNotNull(columnValueList);
assertEquals(3, columnValueList.size());
assertEquals(2, columnValueList.size());
columnValueList = classificationService.createClassificationQuery()
.domainIn("")
@ -180,7 +180,7 @@ public class QueryClassificationAccTest extends AbstractAccTest {
.typeIn("TASK")
.list();
assertNotNull(classifications);
assertEquals(12, classifications.size());
assertEquals(13, classifications.size());
}
@Test

View File

@ -39,7 +39,7 @@ INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:200000000000000000000000000000000
-- WITH PARENT CLASSIFICATIONS (MIXED DOMAIN) ---
-- DOMAIN_A
INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:200000000000000000000000000000000001', 'A12', 'CLI:100000000000000000000000000000000014', 'EXTERNAL', 'TASK', 'DOMAIN_A', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'OLD-Leistungsfall', 'OLD-Leistungsfall', 1, 'P1D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:200000000000000000000000000000000002', 'A13', 'CLI:100000000000000000000000000000000011', 'AUTOMATIC', 'EXTERNAL', 'DOMAIN_A', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Beratungsprotokoll', 'Beratungsprotokoll', 1, 'P1D', '', 'VNR,RVNR,KOLVNR, ANR', '', '', '', '', '', '', '');
INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:200000000000000000000000000000000002', 'A13', 'CLI:100000000000000000000000000000000011', 'AUTOMATIC', 'TASK', 'DOMAIN_A', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Beratungsprotokoll', 'Beratungsprotokoll', 1, 'P1D', '', 'VNR,RVNR,KOLVNR, ANR', '', '', '', '', '', '', '');
-- DOMAIN_B
INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:200000000000000000000000000000000003', 'A12', 'CLI:100000000000000000000000000000000015', 'MANUAL', 'TASK', 'DOMAIN_B', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Widerruf', 'Widerruf', 1, 'P1D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:200000000000000000000000000000000004', 'T21001', 'CLI:100000000000000000000000000000000015', 'MANUAL', 'TASK', 'DOMAIN_B', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Beratungsprotokoll', 'Beratungsprotokoll', 1, 'P1D', '', 'VNR,RVNR,KOLVNR, ANR', '', '', '', '', '', '', '');

View File

@ -39,7 +39,7 @@ INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:200000000000000000000000000000000
-- WITH PARENT CLASSIFICATIONS (MIXED DOMAIN) ---
-- DOMAIN_A
INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:200000000000000000000000000000000001', 'A12', 'CLI:100000000000000000000000000000000014', 'EXTERNAL', 'TASK', 'DOMAIN_A', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'OLD-Leistungsfall', 'OLD-Leistungsfall', 1, 'P1D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:200000000000000000000000000000000002', 'A13', 'CLI:100000000000000000000000000000000011', 'AUTOMATIC', 'EXTERNAL', 'DOMAIN_A', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Beratungsprotokoll', 'Beratungsprotokoll', 1, 'P1D', '', 'VNR,RVNR,KOLVNR, ANR', '', '', '', '', '', '', '');
INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:200000000000000000000000000000000002', 'A13', 'CLI:100000000000000000000000000000000011', 'AUTOMATIC', 'TASK', 'DOMAIN_A', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Beratungsprotokoll', 'Beratungsprotokoll', 1, 'P1D', '', 'VNR,RVNR,KOLVNR, ANR', '', '', '', '', '', '', '');
-- DOMAIN_B
INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:200000000000000000000000000000000003', 'A12', 'CLI:100000000000000000000000000000000015', 'MANUAL', 'TASK', 'DOMAIN_B', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Widerruf', 'Widerruf', 1, 'P1D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO TASKANA.CLASSIFICATION VALUES('CLI:200000000000000000000000000000000004', 'T21001', 'CLI:100000000000000000000000000000000015', 'MANUAL', 'TASK', 'DOMAIN_B', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Beratungsprotokoll', 'Beratungsprotokoll', 1, 'P1D', '', 'VNR,RVNR,KOLVNR, ANR', '', '', '', '', '', '', '');

View File

@ -0,0 +1,138 @@
package pro.taskana.rest;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.Collections;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.context.annotation.Import;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.PagedResources;
import org.springframework.hateoas.hal.Jackson2HalModule;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import pro.taskana.rest.resource.ClassificationSummaryResource;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@Import(RestConfiguration.class)
public class ClassificationControllerIntTest {
@LocalServerPort
int port;
@Test
public void testGetAllClassifications() {
RestTemplate template = getRestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x");
HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<PagedResources<ClassificationSummaryResource>> response = template.exchange(
"http://127.0.0.1:" + port + "/v1/classifications", HttpMethod.GET, request,
new ParameterizedTypeReference<PagedResources<ClassificationSummaryResource>>() {
});
assertNotNull(response.getBody().getLink(Link.REL_SELF));
}
@Test
public void testGetAllClassificationsKeepingFilters() {
RestTemplate template = getRestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x");
HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<PagedResources<ClassificationSummaryResource>> response = template.exchange(
"http://127.0.0.1:" + port + "/v1/classifications?domain=DOMAIN_A&sortBy=key&order=asc", HttpMethod.GET,
request,
new ParameterizedTypeReference<PagedResources<ClassificationSummaryResource>>() {
});
assertNotNull(response.getBody().getLink(Link.REL_SELF));
assertTrue(response.getBody()
.getLink(Link.REL_SELF)
.getHref()
.endsWith("/v1/classifications?domain=DOMAIN_A&sortBy=key&order=asc"));
assertEquals(17, response.getBody().getContent().size());
assertEquals("A12", response.getBody().getContent().iterator().next().key);
}
@Test
public void testGetSecondPageSortedByKey() {
RestTemplate template = getRestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x");
HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<PagedResources<ClassificationSummaryResource>> response = template.exchange(
"http://127.0.0.1:" + port + "/v1/classifications?domain=DOMAIN_A&sortBy=key&order=asc&page=2&pagesize=5",
HttpMethod.GET,
request,
new ParameterizedTypeReference<PagedResources<ClassificationSummaryResource>>() {
});
assertEquals(5, response.getBody().getContent().size());
assertEquals("L1050", response.getBody().getContent().iterator().next().key);
assertNotNull(response.getBody().getLink(Link.REL_SELF));
assertTrue(response.getBody()
.getLink(Link.REL_SELF)
.getHref()
.endsWith("/v1/classifications?domain=DOMAIN_A&sortBy=key&order=asc&page=2&pagesize=5"));
assertNotNull(response.getBody().getLink("allClassifications"));
assertTrue(response.getBody()
.getLink("allClassifications")
.getHref()
.endsWith("/v1/classifications"));
assertNotNull(response.getBody().getLink(Link.REL_FIRST));
assertNotNull(response.getBody().getLink(Link.REL_LAST));
assertNotNull(response.getBody().getLink(Link.REL_NEXT));
assertNotNull(response.getBody().getLink(Link.REL_PREVIOUS));
}
@Test
public void testGetClassificationWithSpecialCharacter() {
RestTemplate template = getRestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x");
HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<ClassificationSummaryResource> response = template.exchange(
"http://127.0.0.1:" + port + "/v1/classifications/CLI:100000000000000000000000000000000009",
HttpMethod.GET,
request,
new ParameterizedTypeReference<ClassificationSummaryResource>() {
});
assertEquals("Zustimmungserklärung", response.getBody().name);
}
/**
* Return a REST template which is capable of dealing with responses in HAL format
*
* @return RestTemplate
*/
private RestTemplate getRestTemplate() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.registerModule(new Jackson2HalModule());
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json"));
converter.setObjectMapper(mapper);
RestTemplate template = new RestTemplate(Collections.<HttpMessageConverter<?>> singletonList(converter));
return template;
}
}

View File

@ -1,19 +1,27 @@
package pro.taskana.rest;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.hateoas.PagedResources;
import org.springframework.hateoas.PagedResources.PageMetadata;
import org.springframework.hateoas.config.EnableHypermediaSupport;
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import pro.taskana.BaseQuery;
import pro.taskana.Classification;
import pro.taskana.ClassificationQuery;
import pro.taskana.ClassificationService;
import pro.taskana.ClassificationSummary;
import pro.taskana.exceptions.ClassificationAlreadyExistException;
@ -23,33 +31,69 @@ import pro.taskana.exceptions.DomainNotFoundException;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.rest.resource.ClassificationResource;
import pro.taskana.rest.resource.mapper.ClassificationMapper;
import java.util.List;
import pro.taskana.rest.resource.ClassificationSummaryResource;
import pro.taskana.rest.resource.mapper.ClassificationResourceAssembler;
import pro.taskana.rest.resource.mapper.ClassificationSummaryResourcesAssembler;
/**
* Controller for all {@link Classification} related endpoints.
*/
@RestController
@RequestMapping(path = "/v1/classifications", produces = {MediaType.APPLICATION_JSON_VALUE})
public class ClassificationController {
@EnableHypermediaSupport(type = HypermediaType.HAL)
@RequestMapping(path = "/v1/classifications", produces = "application/hal+json")
public class ClassificationController extends AbstractPagingController {
private static final String LIKE = "%";
private static final String NAME = "name";
private static final String KEY = "key";
private static final String DOMAIN = "domain";
private static final String CATEGORY = "category";
private static final String DESC = "desc";
@Autowired
private ClassificationService classificationService;
@Autowired
private ClassificationMapper classificationMapper;
private ClassificationResourceAssembler classificationResourceAssembler;
@GetMapping
@Transactional(readOnly = true, rollbackFor = Exception.class)
public ResponseEntity<List<ClassificationSummary>> getClassifications() {
try {
List<ClassificationSummary> classificationTree = classificationService.createClassificationQuery().list();
return ResponseEntity.status(HttpStatus.OK).body(classificationTree);
} catch (Exception e) {
TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
public ResponseEntity<PagedResources<ClassificationSummaryResource>> getClassifications(
@RequestParam(value = "sortBy", defaultValue = "key", required = false) String sortBy,
@RequestParam(value = "order", defaultValue = "asc", required = false) String order,
@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "nameLike", required = false) String nameLike,
@RequestParam(value = "key", required = false) String key,
@RequestParam(value = "category", required = false) String category,
@RequestParam(value = "domain", required = false) String domain,
@RequestParam(value = "type", required = false) String type,
@RequestParam(value = "page", required = false) String page,
@RequestParam(value = "pagesize", required = false) String pageSize) throws InvalidArgumentException {
ClassificationQuery query = classificationService.createClassificationQuery();
addSortingToQuery(query, sortBy, order);
addAttributeFilter(query, name, nameLike, key, category, type, domain);
PageMetadata pageMetadata = null;
List<ClassificationSummary> classificationSummaries = null;
if (page != null && pageSize != null) {
// paging
long totalElements = query.count();
pageMetadata = initPageMetadata(pageSize, page, totalElements);
classificationSummaries = query.listPage((int) pageMetadata.getNumber(),
(int) pageMetadata.getSize());
} else if (page == null && pageSize == null) {
// not paging
classificationSummaries = query.list();
} else {
throw new InvalidArgumentException("Paging information is incomplete.");
}
ClassificationSummaryResourcesAssembler assembler = new ClassificationSummaryResourcesAssembler();
PagedResources<ClassificationSummaryResource> pagedResources = assembler.toResources(classificationSummaries,
pageMetadata);
return new ResponseEntity<>(pagedResources, HttpStatus.OK);
}
@GetMapping(path = "/{classificationId}")
@ -58,16 +102,7 @@ public class ClassificationController {
throws ClassificationNotFoundException, NotAuthorizedException, ClassificationAlreadyExistException,
ConcurrencyException, DomainNotFoundException, InvalidArgumentException {
Classification classification = classificationService.getClassification(classificationId);
return ResponseEntity.status(HttpStatus.OK).body(classificationMapper.toResource(classification));
}
@GetMapping(path = "/{classificationKey}/{domain}")
@Transactional(readOnly = true, rollbackFor = Exception.class)
public ResponseEntity<ClassificationResource> getClassification(@PathVariable String classificationKey,
@PathVariable String domain) throws ClassificationNotFoundException, NotAuthorizedException,
ClassificationAlreadyExistException, ConcurrencyException, DomainNotFoundException, InvalidArgumentException {
Classification classification = classificationService.getClassification(classificationKey, domain);
return ResponseEntity.status(HttpStatus.OK).body(classificationMapper.toResource(classification));
return ResponseEntity.status(HttpStatus.OK).body(classificationResourceAssembler.toResource(classification));
}
@PostMapping
@ -76,18 +111,84 @@ public class ClassificationController {
@RequestBody ClassificationResource resource)
throws NotAuthorizedException, ClassificationNotFoundException, ClassificationAlreadyExistException,
ConcurrencyException, DomainNotFoundException, InvalidArgumentException {
Classification classification = classificationMapper.toModel(resource);
Classification classification = classificationResourceAssembler.toModel(resource);
classification = classificationService.createClassification(classification);
return ResponseEntity.status(HttpStatus.CREATED).body(classificationMapper.toResource(classification));
return ResponseEntity.status(HttpStatus.CREATED)
.body(classificationResourceAssembler.toResource(classification));
}
@PutMapping
@PutMapping(path = "/{classificationId}")
@Transactional(rollbackFor = Exception.class)
public ResponseEntity<ClassificationResource> updateClassification(@RequestBody ClassificationResource resource)
public ResponseEntity<ClassificationResource> updateClassification(
@PathVariable(value = "classificationId") String classificationId, @RequestBody ClassificationResource resource)
throws NotAuthorizedException, ClassificationNotFoundException, ConcurrencyException,
ClassificationAlreadyExistException, DomainNotFoundException, InvalidArgumentException {
Classification classification = classificationMapper.toModel(resource);
classification = classificationService.updateClassification(classification);
return ResponseEntity.status(HttpStatus.OK).body(classificationMapper.toResource(classification));
ResponseEntity<ClassificationResource> result;
if (classificationId.equals(resource.classificationId)) {
Classification classification = classificationResourceAssembler.toModel(resource);
classification = classificationService.updateClassification(classification);
result = ResponseEntity.ok(classificationResourceAssembler.toResource(classification));
} else {
throw new InvalidArgumentException(
"ClassificationId ('" + classificationId
+ "') of the URI is not identical with the classificationId ('"
+ resource.getClassificationId() + "') of the object in the payload.");
}
return result;
}
private void addSortingToQuery(ClassificationQuery query, String sortBy, String order)
throws IllegalArgumentException {
BaseQuery.SortDirection sortDirection = getSortDirection(order);
switch (sortBy) {
case CATEGORY:
query.orderByCategory(sortDirection);
break;
case DOMAIN:
query.orderByDomain(sortDirection);
break;
case KEY:
query.orderByKey(sortDirection);
break;
case NAME:
query.orderByName(sortDirection);
break;
default:
throw new IllegalArgumentException("Unknown order '" + sortBy + "'");
}
}
private BaseQuery.SortDirection getSortDirection(String order) {
if (order.equals(DESC)) {
return BaseQuery.SortDirection.DESCENDING;
}
return BaseQuery.SortDirection.ASCENDING;
}
private void addAttributeFilter(ClassificationQuery query,
String name, String nameLike,
String key, String category,
String type, String domain) throws InvalidArgumentException {
if (name != null) {
query.nameIn(name);
}
if (nameLike != null) {
query.nameLike(LIKE + nameLike + LIKE);
}
if (key != null) {
query.keyIn(key);
}
if (category != null) {
query.categoryIn(category);
}
if (type != null) {
query.typeIn(type);
}
if (domain != null) {
query.domainIn(domain);
}
}
}

View File

@ -23,7 +23,7 @@ import pro.taskana.exceptions.DomainNotFoundException;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.rest.resource.ClassificationResource;
import pro.taskana.rest.resource.mapper.ClassificationMapper;
import pro.taskana.rest.resource.mapper.ClassificationResourceAssembler;
import java.util.ArrayList;
import java.util.List;
@ -41,7 +41,7 @@ public class ClassificationDefinitionController {
private ClassificationService classificationService;
@Autowired
private ClassificationMapper classificationMapper;
private ClassificationResourceAssembler classificationMapper;
@GetMapping
@Transactional(readOnly = true, rollbackFor = Exception.class)

View File

@ -25,7 +25,7 @@ import pro.taskana.rest.resource.ClassificationResource;
* Transforms {@link Classification} to its resource counterpart {@link ClassificationResource} and vice versa.
*/
@Component
public class ClassificationMapper {
public class ClassificationResourceAssembler {
@Autowired
ClassificationService classificationService;
@ -60,17 +60,8 @@ public class ClassificationMapper {
linkTo(methodOn(ClassificationController.class).getClassification(classification.getId()))
.withSelfRel());
resource.add(
linkTo(methodOn(ClassificationController.class).getClassification(classification.getKey(),
classification.getDomain()))
.withRel("getClassificationByKeyAndDomain"));
resource.add(
linkTo(methodOn(ClassificationController.class).getClassifications()).withRel("getAllClassifications"));
resource.add(
linkTo(methodOn(ClassificationController.class).createClassification(resource))
.withRel("createClassification"));
resource.add(
linkTo(methodOn(ClassificationController.class).updateClassification(resource))
.withRel("updateClassification"));
linkTo(methodOn(ClassificationController.class).getClassifications(null, null, null, null, null, null, null,
null, null, null)).withRel("getAllClassifications"));
return resource;
}
}

View File

@ -0,0 +1,76 @@
package pro.taskana.rest.resource.mapper;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.PagedResources;
import org.springframework.hateoas.PagedResources.PageMetadata;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import org.springframework.web.util.UriComponentsBuilder;
import pro.taskana.ClassificationSummary;
import pro.taskana.rest.ClassificationController;
import pro.taskana.rest.resource.ClassificationSummaryResource;
/**
* @author HH
*/
public class ClassificationSummaryResourcesAssembler {
public ClassificationSummaryResourcesAssembler() {
}
public PagedResources<ClassificationSummaryResource> toResources(
List<ClassificationSummary> classificationSummaries,
PageMetadata pageMetadata) {
ClassificationSummaryResourceAssembler assembler = new ClassificationSummaryResourceAssembler();
List<ClassificationSummaryResource> resources = assembler.toResources(classificationSummaries);
PagedResources<ClassificationSummaryResource> pagedResources = new PagedResources<ClassificationSummaryResource>(
resources,
pageMetadata);
UriComponentsBuilder original = getBuilderForOriginalUri();
pagedResources.add(new Link(original.toUriString()).withSelfRel());
if (pageMetadata != null) {
pagedResources.add(linkTo(ClassificationController.class).withRel("allClassifications"));
pagedResources.add(new Link(original.replaceQueryParam("page", 1).toUriString()).withRel(Link.REL_FIRST));
pagedResources.add(new Link(original.replaceQueryParam("page", pageMetadata.getTotalPages()).toUriString())
.withRel(Link.REL_LAST));
if (pageMetadata.getNumber() > 1) {
pagedResources
.add(new Link(original.replaceQueryParam("page", pageMetadata.getNumber() - 1).toUriString())
.withRel(Link.REL_PREVIOUS));
}
if (pageMetadata.getNumber() < pageMetadata.getTotalPages()) {
pagedResources
.add(new Link(original.replaceQueryParam("page", pageMetadata.getNumber() + 1).toUriString())
.withRel(Link.REL_NEXT));
}
}
return pagedResources;
}
private UriComponentsBuilder getBuilderForOriginalUri() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getRequest();
UriComponentsBuilder baseUri = ServletUriComponentsBuilder.fromServletMapping(request)
.path(request.getRequestURI());
for (Map.Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
for (String value : entry.getValue()) {
baseUri.queryParam(entry.getKey(), value);
}
}
UriComponentsBuilder original = baseUri;
return original;
}
}

View File

@ -23,7 +23,7 @@ import pro.taskana.rest.RestConfiguration;
import pro.taskana.rest.resource.ClassificationResource;
/**
* Test for {@link ClassificationMapper}.
* Test for {@link ClassificationResourceAssembler}.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {RestConfiguration.class})
@ -31,7 +31,7 @@ import pro.taskana.rest.resource.ClassificationResource;
public class ClassificationMapperTest {
@Autowired
private ClassificationMapper classificationMapper;
private ClassificationResourceAssembler classificationMapper;
@Autowired
private ClassificationService classificationService;