pro.taskana.workbasket.rest.WorkbasketController Maven / Gradle / Ivy
package pro.taskana.workbasket.rest;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.hateoas.MediaTypes;
import org.springframework.hateoas.PagedModel.PageMetadata;
import org.springframework.hateoas.config.EnableHypermediaSupport;
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.DeleteMapping;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import pro.taskana.common.api.BaseQuery.SortDirection;
import pro.taskana.common.api.LoggerUtils;
import pro.taskana.common.api.exceptions.ConcurrencyException;
import pro.taskana.common.api.exceptions.DomainNotFoundException;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.common.rest.AbstractPagingController;
import pro.taskana.common.rest.Mapping;
import pro.taskana.common.rest.models.TaskanaPagedModel;
import pro.taskana.workbasket.api.WorkbasketPermission;
import pro.taskana.workbasket.api.WorkbasketQuery;
import pro.taskana.workbasket.api.WorkbasketService;
import pro.taskana.workbasket.api.WorkbasketType;
import pro.taskana.workbasket.api.exceptions.InvalidWorkbasketException;
import pro.taskana.workbasket.api.exceptions.WorkbasketAccessItemAlreadyExistException;
import pro.taskana.workbasket.api.exceptions.WorkbasketAlreadyExistException;
import pro.taskana.workbasket.api.exceptions.WorkbasketInUseException;
import pro.taskana.workbasket.api.exceptions.WorkbasketNotFoundException;
import pro.taskana.workbasket.api.models.Workbasket;
import pro.taskana.workbasket.api.models.WorkbasketAccessItem;
import pro.taskana.workbasket.api.models.WorkbasketSummary;
import pro.taskana.workbasket.rest.assembler.DistributionTargetRepresentationModelAssembler;
import pro.taskana.workbasket.rest.assembler.WorkbasketAccessItemRepresentationModelAssembler;
import pro.taskana.workbasket.rest.assembler.WorkbasketRepresentationModelAssembler;
import pro.taskana.workbasket.rest.assembler.WorkbasketSummaryRepresentationModelAssembler;
import pro.taskana.workbasket.rest.models.WorkbasketAccessItemRepresentationModel;
import pro.taskana.workbasket.rest.models.WorkbasketRepresentationModel;
import pro.taskana.workbasket.rest.models.WorkbasketSummaryRepresentationModel;
/** Controller for all {@link Workbasket} related endpoints. */
@RestController
@EnableHypermediaSupport(type = HypermediaType.HAL)
public class WorkbasketController extends AbstractPagingController {
private static final Logger LOGGER = LoggerFactory.getLogger(WorkbasketController.class);
private static final String LIKE = "%";
private static final String NAME = "name";
private static final String NAME_LIKE = "name-like";
private static final String KEY = "key";
private static final String KEY_LIKE = "key-like";
private static final String OWNER = "owner";
private static final String OWNER_LIKE = "owner-like";
private static final String DESCRIPTION_LIKE = "description-like";
private static final String DOMAIN = "domain";
private static final String REQUIRED_PERMISSION = "required-permission";
private static final String TYPE = "type";
private static final String DESCRIPTION = "description";
private static final String SORT_BY = "sort-by";
private static final String SORT_DIRECTION = "order";
private final WorkbasketService workbasketService;
private final WorkbasketRepresentationModelAssembler workbasketRepresentationModelAssembler;
private final WorkbasketSummaryRepresentationModelAssembler
workbasketSummaryRepresentationModelAssembler;
private final DistributionTargetRepresentationModelAssembler
distributionTargetRepresentationModelAssembler;
private final WorkbasketAccessItemRepresentationModelAssembler
workbasketAccessItemRepresentationModelAssembler;
WorkbasketController(
WorkbasketService workbasketService,
WorkbasketRepresentationModelAssembler workbasketRepresentationModelAssembler,
WorkbasketSummaryRepresentationModelAssembler workbasketSummaryRepresentationModelAssembler,
DistributionTargetRepresentationModelAssembler distributionTargetRepresentationModelAssembler,
WorkbasketAccessItemRepresentationModelAssembler
workbasketAccessItemRepresentationModelAssembler) {
this.workbasketService = workbasketService;
this.workbasketRepresentationModelAssembler = workbasketRepresentationModelAssembler;
this.workbasketSummaryRepresentationModelAssembler =
workbasketSummaryRepresentationModelAssembler;
this.distributionTargetRepresentationModelAssembler =
distributionTargetRepresentationModelAssembler;
this.workbasketAccessItemRepresentationModelAssembler =
workbasketAccessItemRepresentationModelAssembler;
}
@GetMapping(path = Mapping.URL_WORKBASKET)
@Transactional(readOnly = true, rollbackFor = Exception.class)
public ResponseEntity> getWorkbaskets(
@RequestParam MultiValueMap params) throws InvalidArgumentException {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Entry to getWorkbaskets(params= {})", params);
}
WorkbasketQuery query = workbasketService.createWorkbasketQuery();
query = applySortingParams(query, params);
applyFilterParams(query, params);
PageMetadata pageMetadata = getPageMetadata(params, query);
List workbasketSummaries = getQueryList(query, pageMetadata);
TaskanaPagedModel pagedModels =
workbasketSummaryRepresentationModelAssembler.toPageModel(
workbasketSummaries, pageMetadata);
ResponseEntity> response =
ResponseEntity.ok(pagedModels);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Exit from getWorkbaskets(), returning {}", response);
}
return response;
}
@GetMapping(path = Mapping.URL_WORKBASKET_ID, produces = MediaTypes.HAL_JSON_VALUE)
@Transactional(readOnly = true, rollbackFor = Exception.class)
public ResponseEntity getWorkbasket(
@PathVariable(value = "workbasketId") String workbasketId)
throws WorkbasketNotFoundException, NotAuthorizedException {
LOGGER.debug("Entry to getWorkbasket(workbasketId= {})", workbasketId);
ResponseEntity result;
Workbasket workbasket = workbasketService.getWorkbasket(workbasketId);
result = ResponseEntity.ok(workbasketRepresentationModelAssembler.toModel(workbasket));
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Exit from getWorkbasket(), returning {}", result);
}
return result;
}
@DeleteMapping(path = Mapping.URL_WORKBASKET_ID)
@Transactional(rollbackFor = Exception.class, noRollbackFor = WorkbasketNotFoundException.class)
public ResponseEntity deleteWorkbasket(
@PathVariable(value = "workbasketId") String workbasketId)
throws NotAuthorizedException, InvalidArgumentException, WorkbasketNotFoundException,
WorkbasketInUseException {
LOGGER.debug("Entry to markWorkbasketForDeletion(workbasketId= {})", workbasketId);
ResponseEntity response;
boolean workbasketDeleted = workbasketService.deleteWorkbasket(workbasketId);
if (workbasketDeleted) {
LOGGER.debug("Workbasket successfully deleted.");
response = ResponseEntity.noContent().build();
} else {
LOGGER.debug(
"Workbasket was only marked for deletion and will be physically deleted later on.");
response = ResponseEntity.accepted().build();
}
LOGGER.debug("Exit from markWorkbasketForDeletion(), returning {}", response);
return response;
}
@PostMapping(path = Mapping.URL_WORKBASKET)
@Transactional(rollbackFor = Exception.class)
public ResponseEntity createWorkbasket(
@RequestBody WorkbasketRepresentationModel workbasketRepresentationModel)
throws InvalidWorkbasketException, NotAuthorizedException, WorkbasketAlreadyExistException,
DomainNotFoundException {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(
"Entry to createWorkbasket(workbasketResource= {})", workbasketRepresentationModel);
}
Workbasket workbasket =
workbasketRepresentationModelAssembler.toEntityModel(workbasketRepresentationModel);
workbasket = workbasketService.createWorkbasket(workbasket);
ResponseEntity response =
ResponseEntity.status(HttpStatus.CREATED)
.body(workbasketRepresentationModelAssembler.toModel(workbasket));
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Exit from createWorkbasket(), returning {}", response);
}
return response;
}
@PutMapping(path = Mapping.URL_WORKBASKET_ID)
@Transactional(rollbackFor = Exception.class)
public ResponseEntity updateWorkbasket(
@PathVariable(value = "workbasketId") String workbasketId,
@RequestBody WorkbasketRepresentationModel workbasketRepresentationModel)
throws InvalidWorkbasketException, WorkbasketNotFoundException, NotAuthorizedException,
ConcurrencyException {
LOGGER.debug("Entry to updateWorkbasket(workbasketId= {})", workbasketId);
ResponseEntity result;
if (workbasketId.equals(workbasketRepresentationModel.getWorkbasketId())) {
Workbasket workbasket =
workbasketRepresentationModelAssembler.toEntityModel(workbasketRepresentationModel);
workbasket = workbasketService.updateWorkbasket(workbasket);
result = ResponseEntity.ok(workbasketRepresentationModelAssembler.toModel(workbasket));
} else {
throw new InvalidWorkbasketException(
"Target-WB-ID('"
+ workbasketId
+ "') is not identical with the WB-ID of to object which should be updated. ID=('"
+ workbasketRepresentationModel.getWorkbasketId()
+ "')");
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Exit from updateWorkbasket(), returning {}", result);
}
return result;
}
@GetMapping(path = Mapping.URL_WORKBASKET_ID_ACCESSITEMS, produces = MediaTypes.HAL_JSON_VALUE)
@Transactional(readOnly = true, rollbackFor = Exception.class)
public ResponseEntity>
getWorkbasketAccessItems(@PathVariable(value = "workbasketId") String workbasketId)
throws NotAuthorizedException, WorkbasketNotFoundException {
LOGGER.debug("Entry to getWorkbasketAccessItems(workbasketId= {})", workbasketId);
ResponseEntity> result;
List accessItems =
workbasketService.getWorkbasketAccessItems(workbasketId);
result =
ResponseEntity.ok(
workbasketAccessItemRepresentationModelAssembler.toPageModel(
workbasketId, accessItems, null));
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Exit from getWorkbasketAccessItems(), returning {}", result);
}
return result;
}
@PutMapping(path = Mapping.URL_WORKBASKET_ID_ACCESSITEMS)
@Transactional(rollbackFor = Exception.class)
public ResponseEntity>
setWorkbasketAccessItems(
@PathVariable(value = "workbasketId") String workbasketId,
@RequestBody List workbasketAccessResourceItems)
throws NotAuthorizedException, InvalidArgumentException, WorkbasketNotFoundException,
WorkbasketAccessItemAlreadyExistException {
LOGGER.debug("Entry to setWorkbasketAccessItems(workbasketId= {})", workbasketId);
if (workbasketAccessResourceItems == null) {
throw new InvalidArgumentException("Can´t create something with NULL body-value.");
}
List wbAccessItems = new ArrayList<>();
workbasketAccessResourceItems.forEach(
item -> wbAccessItems
.add(workbasketAccessItemRepresentationModelAssembler.toEntityModel(item)));
workbasketService.setWorkbasketAccessItems(workbasketId, wbAccessItems);
List updatedWbAccessItems =
workbasketService.getWorkbasketAccessItems(workbasketId);
ResponseEntity> response =
ResponseEntity.ok(
workbasketAccessItemRepresentationModelAssembler.toPageModel(
workbasketId, updatedWbAccessItems, null));
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Exit from setWorkbasketAccessItems(), returning {}", response);
}
return response;
}
@GetMapping(path = Mapping.URL_WORKBASKET_ID_DISTRIBUTION, produces = MediaTypes.HAL_JSON_VALUE)
@Transactional(readOnly = true, rollbackFor = Exception.class)
public ResponseEntity>
getDistributionTargets(@PathVariable(value = "workbasketId") String workbasketId)
throws WorkbasketNotFoundException, NotAuthorizedException {
LOGGER.debug("Entry to getDistributionTargets(workbasketId= {})", workbasketId);
List distributionTargets =
workbasketService.getDistributionTargets(workbasketId);
TaskanaPagedModel distributionTargetListResource =
distributionTargetRepresentationModelAssembler.toPageModel(distributionTargets, null);
ResponseEntity> result =
ResponseEntity.ok(distributionTargetListResource);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Exit from getDistributionTargets(), returning {}", result);
}
return result;
}
@PutMapping(path = Mapping.URL_WORKBASKET_ID_DISTRIBUTION)
@Transactional(rollbackFor = Exception.class)
public ResponseEntity>
setDistributionTargetsForWorkbasketId(
@PathVariable(value = "workbasketId") String sourceWorkbasketId,
@RequestBody List targetWorkbasketIds)
throws WorkbasketNotFoundException, NotAuthorizedException {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(
"Entry to getTasksStatusReport(workbasketId= {}, targetWorkbasketIds´= {})",
sourceWorkbasketId,
LoggerUtils.listToString(targetWorkbasketIds));
}
workbasketService.setDistributionTargets(sourceWorkbasketId, targetWorkbasketIds);
List distributionTargets =
workbasketService.getDistributionTargets(sourceWorkbasketId);
ResponseEntity> response =
ResponseEntity.ok(
distributionTargetRepresentationModelAssembler.toPageModel(distributionTargets, null));
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Exit from getTasksStatusReport(), returning {}", response);
}
return response;
}
@DeleteMapping(path = Mapping.URL_WORKBASKET_ID_DISTRIBUTION)
@Transactional(rollbackFor = Exception.class)
public ResponseEntity>
removeDistributionTargetForWorkbasketId(
@PathVariable(value = "workbasketId") String targetWorkbasketId)
throws WorkbasketNotFoundException, NotAuthorizedException {
LOGGER.debug(
"Entry to removeDistributionTargetForWorkbasketId(workbasketId= {})", targetWorkbasketId);
List sourceWorkbaskets =
workbasketService.getDistributionSources(targetWorkbasketId);
for (WorkbasketSummary source : sourceWorkbaskets) {
workbasketService.removeDistributionTarget(source.getId(), targetWorkbasketId);
}
ResponseEntity> response =
ResponseEntity.noContent().build();
LOGGER.debug("Exit from removeDistributionTargetForWorkbasketId(), returning {}", response);
return response;
}
private WorkbasketQuery applySortingParams(
WorkbasketQuery query, MultiValueMap params) throws InvalidArgumentException {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Entry to applySortingParams(query= {}, params={})", query, params);
}
// sorting
String sortBy = params.getFirst(SORT_BY);
if (sortBy != null) {
SortDirection sortDirection;
if (params.getFirst(SORT_DIRECTION) != null
&& "desc".equals(params.getFirst(SORT_DIRECTION))) {
sortDirection = SortDirection.DESCENDING;
} else {
sortDirection = SortDirection.ASCENDING;
}
switch (sortBy) {
case (NAME):
query = query.orderByName(sortDirection);
break;
case (KEY):
query = query.orderByKey(sortDirection);
break;
case (OWNER):
query = query.orderByOwner(sortDirection);
break;
case (TYPE):
query = query.orderByType(sortDirection);
break;
case (DESCRIPTION):
query = query.orderByDescription(sortDirection);
break;
default:
throw new InvalidArgumentException("Unknown order '" + sortBy + "'");
}
}
params.remove(SORT_BY);
params.remove(SORT_DIRECTION);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Exit from applySortingParams(), returning {}", query);
}
return query;
}
private void applyFilterParams(
WorkbasketQuery query, MultiValueMap params) throws InvalidArgumentException {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Entry to applyFilterParams(query= {}, params= {})", query, params);
}
if (params.containsKey(NAME)) {
String[] names = extractCommaSeparatedFields(params.get(NAME));
query.nameIn(names);
params.remove(NAME);
}
if (params.containsKey(NAME_LIKE)) {
query.nameLike(LIKE + params.get(NAME_LIKE).get(0) + LIKE);
params.remove(NAME_LIKE);
}
if (params.containsKey(KEY)) {
String[] names = extractCommaSeparatedFields(params.get(KEY));
query.keyIn(names);
params.remove(KEY);
}
if (params.containsKey(KEY_LIKE)) {
query.keyLike(LIKE + params.get(KEY_LIKE).get(0) + LIKE);
params.remove(KEY_LIKE);
}
if (params.containsKey(OWNER)) {
String[] names = extractCommaSeparatedFields(params.get(OWNER));
query.ownerIn(names);
params.remove(OWNER);
}
if (params.containsKey(OWNER_LIKE)) {
query.ownerLike(LIKE + params.get(OWNER_LIKE).get(0) + LIKE);
params.remove(OWNER_LIKE);
}
if (params.containsKey(DESCRIPTION_LIKE)) {
query.descriptionLike(LIKE + params.get(DESCRIPTION_LIKE).get(0) + LIKE);
params.remove(DESCRIPTION_LIKE);
}
if (params.containsKey(DOMAIN)) {
query.domainIn(extractCommaSeparatedFields(params.get(DOMAIN)));
params.remove(DOMAIN);
}
if (params.containsKey(TYPE)) {
switch (params.getFirst(TYPE)) {
case "PERSONAL":
query.typeIn(WorkbasketType.PERSONAL);
break;
case "GROUP":
query.typeIn(WorkbasketType.GROUP);
break;
case "CLEARANCE":
query.typeIn(WorkbasketType.CLEARANCE);
break;
case "TOPIC":
query.typeIn(WorkbasketType.TOPIC);
break;
default:
throw new InvalidArgumentException(
"Unknown Workbasket type '" + params.getFirst(TYPE) + "'");
}
params.remove(TYPE);
}
if (params.containsKey(REQUIRED_PERMISSION)) {
for (String authorization : params.getFirst(REQUIRED_PERMISSION).split(",")) {
switch (authorization.trim()) {
case "READ":
query.callerHasPermission(WorkbasketPermission.READ);
break;
case "OPEN":
query.callerHasPermission(WorkbasketPermission.OPEN);
break;
case "APPEND":
query.callerHasPermission(WorkbasketPermission.APPEND);
break;
case "TRANSFER":
query.callerHasPermission(WorkbasketPermission.TRANSFER);
break;
case "DISTRIBUTE":
query.callerHasPermission(WorkbasketPermission.DISTRIBUTE);
break;
case "CUSTOM_1":
query.callerHasPermission(WorkbasketPermission.CUSTOM_1);
break;
case "CUSTOM_2":
query.callerHasPermission(WorkbasketPermission.CUSTOM_2);
break;
case "CUSTOM_3":
query.callerHasPermission(WorkbasketPermission.CUSTOM_3);
break;
case "CUSTOM_4":
query.callerHasPermission(WorkbasketPermission.CUSTOM_4);
break;
case "CUSTOM_5":
query.callerHasPermission(WorkbasketPermission.CUSTOM_5);
break;
case "CUSTOM_6":
query.callerHasPermission(WorkbasketPermission.CUSTOM_6);
break;
case "CUSTOM_7":
query.callerHasPermission(WorkbasketPermission.CUSTOM_7);
break;
case "CUSTOM_8":
query.callerHasPermission(WorkbasketPermission.CUSTOM_8);
break;
case "CUSTOM_9":
query.callerHasPermission(WorkbasketPermission.CUSTOM_9);
break;
case "CUSTOM_10":
query.callerHasPermission(WorkbasketPermission.CUSTOM_10);
break;
case "CUSTOM_11":
query.callerHasPermission(WorkbasketPermission.CUSTOM_11);
break;
case "CUSTOM_12":
query.callerHasPermission(WorkbasketPermission.CUSTOM_12);
break;
default:
throw new InvalidArgumentException("Unknown authorization '" + authorization + "'");
}
}
params.remove(REQUIRED_PERMISSION);
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Exit from applyFilterParams(), returning {}", query);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy