diff --git a/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/HistoryQueryImpl.java b/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/HistoryQueryImpl.java index dd3ba2678..0a299c0b4 100644 --- a/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/HistoryQueryImpl.java +++ b/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/HistoryQueryImpl.java @@ -7,25 +7,26 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import pro.taskana.common.api.TimeInterval; -import pro.taskana.common.api.exceptions.InvalidArgumentException; +import pro.taskana.common.api.exceptions.SystemException; import pro.taskana.simplehistory.impl.mappings.HistoryQueryMapper; import pro.taskana.simplehistory.query.HistoryQuery; import pro.taskana.simplehistory.query.HistoryQueryColumnName; +import pro.taskana.spi.history.api.events.TaskHistoryCustomField; /** Implementation for generating dynamic sql. */ public class HistoryQueryImpl implements HistoryQuery { private static final Logger LOGGER = LoggerFactory.getLogger(HistoryQueryImpl.class); - private TaskanaHistoryEngineImpl taskanaHistoryEngine; - private HistoryQueryMapper historyQueryMapper; + private final TaskanaHistoryEngineImpl taskanaHistoryEngine; + private final HistoryQueryMapper historyQueryMapper; - private HistoryQueryColumnName columnName; - private List orderBy; - private List orderColumns; + private final List orderBy; + private final List orderColumns; private int maxRows; // limit for rows. used to make list(offset, limit) and single() more efficient. + private HistoryQueryColumnName columnName; private String[] idIn; private String[] businessProcessIdIn; private String[] parentBusinessProcessIdIn; @@ -195,30 +196,6 @@ public class HistoryQueryImpl implements HistoryQuery { return this; } - @Override - public HistoryQuery custom1In(String... custom1) { - this.custom1In = toUpperCopy(custom1); - return this; - } - - @Override - public HistoryQuery custom2In(String... custom2) { - this.custom2In = toUpperCopy(custom2); - return this; - } - - @Override - public HistoryQuery custom3In(String... custom3) { - this.custom3In = toUpperCopy(custom3); - return this; - } - - @Override - public HistoryQuery custom4In(String... custom4) { - this.custom4In = toUpperCopy(custom4); - return this; - } - @Override public HistoryQuery businessProcessIdLike(String... businessProcessId) { this.businessProcessIdLike = toUpperCopy(businessProcessId); @@ -322,26 +299,46 @@ public class HistoryQueryImpl implements HistoryQuery { } @Override - public HistoryQuery custom1Like(String... custom1) { - this.custom1Like = toUpperCopy(custom1); + public HistoryQuery customAttributeIn( + TaskHistoryCustomField customField, String... searchArguments) { + switch (customField) { + case CUSTOM_1: + custom1In = toUpperCopy(searchArguments); + break; + case CUSTOM_2: + custom2In = toUpperCopy(searchArguments); + break; + case CUSTOM_3: + custom3In = toUpperCopy(searchArguments); + break; + case CUSTOM_4: + custom4In = toUpperCopy(searchArguments); + break; + default: + throw new SystemException("Unknown customField '" + customField + "'"); + } return this; } @Override - public HistoryQuery custom2Like(String... custom2) { - this.custom2Like = toUpperCopy(custom2); - return this; - } - - @Override - public HistoryQuery custom3Like(String... custom3) { - this.custom3Like = toUpperCopy(custom3); - return this; - } - - @Override - public HistoryQuery custom4Like(String... custom4) { - this.custom4Like = toUpperCopy(custom4); + public HistoryQuery customAttributeLike( + TaskHistoryCustomField customField, String... searchArguments) { + switch (customField) { + case CUSTOM_1: + custom1Like = toUpperCopy(searchArguments); + break; + case CUSTOM_2: + custom2Like = toUpperCopy(searchArguments); + break; + case CUSTOM_3: + custom3Like = toUpperCopy(searchArguments); + break; + case CUSTOM_4: + custom4Like = toUpperCopy(searchArguments); + break; + default: + throw new SystemException("Unknown customField '" + customField + "'"); + } return this; } @@ -436,22 +433,9 @@ public class HistoryQueryImpl implements HistoryQuery { } @Override - public HistoryQuery orderByCustomAttribute(int num, SortDirection sortDirection) - throws InvalidArgumentException { - - switch (num) { - case 1: - return addOrderCriteria("CUSTOM_1", sortDirection); - case 2: - return addOrderCriteria("CUSTOM_2", sortDirection); - case 3: - return addOrderCriteria("CUSTOM_3", sortDirection); - case 4: - return addOrderCriteria("CUSTOM_4", sortDirection); - default: - throw new InvalidArgumentException( - "Custom number has to be between 1 and 4, but this is: " + num); - } + public HistoryQuery orderByCustomAttribute( + TaskHistoryCustomField customField, SortDirection sortDirection) { + return addOrderCriteria(customField.name(), sortDirection); } @Override @@ -512,7 +496,6 @@ public class HistoryQueryImpl implements HistoryQuery { this); List result = new ArrayList<>(); this.columnName = dbColumnName; - List cacheOrderBy = this.orderBy; this.orderBy.clear(); this.addOrderCriteria(columnName.toString(), sortDirection); @@ -529,8 +512,6 @@ public class HistoryQueryImpl implements HistoryQuery { LOGGER.error("No History Event found."); return result; } finally { - this.orderBy = cacheOrderBy; - this.columnName = null; this.orderColumns.remove(orderColumns.size() - 1); taskanaHistoryEngine.returnConnection(); } diff --git a/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/query/HistoryQuery.java b/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/query/HistoryQuery.java index 0ba348f19..666746a96 100644 --- a/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/query/HistoryQuery.java +++ b/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/query/HistoryQuery.java @@ -2,8 +2,8 @@ package pro.taskana.simplehistory.query; import pro.taskana.common.api.BaseQuery; import pro.taskana.common.api.TimeInterval; -import pro.taskana.common.api.exceptions.InvalidArgumentException; import pro.taskana.simplehistory.impl.HistoryEventImpl; +import pro.taskana.spi.history.api.events.TaskHistoryCustomField; /** HistoryQuery for generating dynamic sql. */ public interface HistoryQuery extends BaseQuery { @@ -161,38 +161,6 @@ public interface HistoryQuery extends BaseQuery defaultList = @@ -166,16 +163,32 @@ class QueryHistoryAccTest extends AbstractAccTest { .list(); assertThat(returnValues).hasSize(6); - returnValues = getHistoryService().createHistoryQuery().custom1In("custom1").list(); + returnValues = + getHistoryService() + .createHistoryQuery() + .customAttributeIn(TaskHistoryCustomField.CUSTOM_1, "custom1") + .list(); assertThat(returnValues).hasSize(13); - returnValues = getHistoryService().createHistoryQuery().custom2In("custom2").list(); + returnValues = + getHistoryService() + .createHistoryQuery() + .customAttributeIn(TaskHistoryCustomField.CUSTOM_2, "custom2") + .list(); assertThat(returnValues).hasSize(1); - returnValues = getHistoryService().createHistoryQuery().custom3In("custom3").list(); + returnValues = + getHistoryService() + .createHistoryQuery() + .customAttributeIn(TaskHistoryCustomField.CUSTOM_3, "custom3") + .list(); assertThat(returnValues).hasSize(7); - returnValues = getHistoryService().createHistoryQuery().custom4In("custom4").list(); + returnValues = + getHistoryService() + .createHistoryQuery() + .customAttributeIn(TaskHistoryCustomField.CUSTOM_4, "custom4") + .list(); assertThat(returnValues).hasSize(1); returnValues = getHistoryService().createHistoryQuery().oldValueIn("old_val").list(); diff --git a/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/TaskHistoryEventController.java b/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/TaskHistoryEventController.java index 6c927a15a..3f4af400d 100644 --- a/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/TaskHistoryEventController.java +++ b/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/TaskHistoryEventController.java @@ -27,10 +27,11 @@ import pro.taskana.common.rest.QueryHelper; import pro.taskana.simplehistory.impl.HistoryEventImpl; import pro.taskana.simplehistory.impl.SimpleHistoryServiceImpl; import pro.taskana.simplehistory.query.HistoryQuery; -import pro.taskana.simplehistory.rest.resource.TaskHistoryEventListResource; -import pro.taskana.simplehistory.rest.resource.TaskHistoryEventListResourceAssembler; -import pro.taskana.simplehistory.rest.resource.TaskHistoryEventResource; -import pro.taskana.simplehistory.rest.resource.TaskHistoryEventResourceAssembler; +import pro.taskana.simplehistory.rest.assembler.TaskHistoryEventListResourceAssembler; +import pro.taskana.simplehistory.rest.assembler.TaskHistoryEventRepresentationModelAssembler; +import pro.taskana.simplehistory.rest.models.TaskHistoryEventListResource; +import pro.taskana.simplehistory.rest.models.TaskHistoryEventRepresentationModel; +import pro.taskana.spi.history.api.events.TaskHistoryCustomField; import pro.taskana.spi.history.api.events.TaskanaHistoryEvent; import pro.taskana.spi.history.api.exceptions.TaskanaHistoryEventNotFoundException; @@ -76,28 +77,26 @@ public class TaskHistoryEventController extends AbstractPagingController { private static final String ATTACHMENT_CLASSIFICATION_KEY_LIKE = "attachment-classification-key-like"; private static final String CUSTOM_1 = "custom-1"; - private static final String CUSTOM_1_LIKE = "custom-1-like"; private static final String CUSTOM_2 = "custom-2"; - private static final String CUSTOM_2_LIKE = "custom-2-like"; private static final String CUSTOM_3 = "custom-3"; - private static final String CUSTOM_3_LIKE = "custom-3-like"; private static final String CUSTOM_4 = "custom-4"; - private static final String CUSTOM_4_LIKE = "custom-4-like"; private static final String PAGING_PAGE = "page"; private static final String PAGING_PAGE_SIZE = "page-size"; private final SimpleHistoryServiceImpl simpleHistoryService; - private final TaskHistoryEventResourceAssembler taskHistoryEventResourceAssembler; + private final TaskHistoryEventRepresentationModelAssembler + taskHistoryEventRepresentationModelAssembler; @Autowired public TaskHistoryEventController( TaskanaEngineConfiguration taskanaEngineConfiguration, SimpleHistoryServiceImpl simpleHistoryServiceImpl, - TaskHistoryEventResourceAssembler taskHistoryEventResourceAssembler) { + TaskHistoryEventRepresentationModelAssembler taskHistoryEventRepresentationModelAssembler) { this.simpleHistoryService = simpleHistoryServiceImpl; this.simpleHistoryService.initialize(taskanaEngineConfiguration); - this.taskHistoryEventResourceAssembler = taskHistoryEventResourceAssembler; + this.taskHistoryEventRepresentationModelAssembler = + taskHistoryEventRepresentationModelAssembler; } @GetMapping @@ -109,8 +108,8 @@ public class TaskHistoryEventController extends AbstractPagingController { } HistoryQuery query = simpleHistoryService.createHistoryQuery(); - query = applySortingParams(query, params); - query = applyFilterParams(query, params); + applySortingParams(query, params); + applyFilterParams(query, params); PageMetadata pageMetadata = null; List historyEvents; @@ -144,7 +143,7 @@ public class TaskHistoryEventController extends AbstractPagingController { @GetMapping(path = "/{historyEventId}", produces = "application/hal+json") @Transactional(readOnly = true, rollbackFor = Exception.class) - public ResponseEntity getTaskHistoryEvent( + public ResponseEntity getTaskHistoryEvent( @PathVariable String historyEventId) throws TaskanaHistoryEventNotFoundException { if (LOGGER.isDebugEnabled()) { @@ -153,8 +152,8 @@ public class TaskHistoryEventController extends AbstractPagingController { TaskanaHistoryEvent resultEvent = simpleHistoryService.getHistoryEvent(historyEventId); - TaskHistoryEventResource taskEventResource = - taskHistoryEventResourceAssembler.toModel(resultEvent); + TaskHistoryEventRepresentationModel taskEventResource = + taskHistoryEventRepresentationModelAssembler.toModel(resultEvent); if (LOGGER.isDebugEnabled()) { LOGGER.debug( @@ -165,7 +164,7 @@ public class TaskHistoryEventController extends AbstractPagingController { return new ResponseEntity<>(taskEventResource, HttpStatus.OK); } - private HistoryQuery applySortingParams(HistoryQuery query, MultiValueMap params) + private void applySortingParams(HistoryQuery query, MultiValueMap params) throws InvalidArgumentException { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Entry to applySortingParams(params= {})", params); @@ -175,65 +174,65 @@ public class TaskHistoryEventController extends AbstractPagingController { params, (sortBy, sortDirection) -> { switch (sortBy) { - case (BUSINESS_PROCESS_ID): + case BUSINESS_PROCESS_ID: query.orderByBusinessProcessId(sortDirection); break; - case (PARENT_BUSINESS_PROCESS_ID): + case PARENT_BUSINESS_PROCESS_ID: query.orderByParentBusinessProcessId(sortDirection); break; - case (TASK_ID): + case TASK_ID: query.orderByTaskId(sortDirection); break; - case (EVENT_TYPE): + case EVENT_TYPE: query.orderByEventType(sortDirection); break; - case (CREATED): + case CREATED: query.orderByCreated(sortDirection); break; - case (USER_ID): + case USER_ID: query.orderByUserId(sortDirection); break; - case (DOMAIN): + case DOMAIN: query.orderByDomain(sortDirection); break; - case (WORKBASKET_KEY): + case WORKBASKET_KEY: query.orderByWorkbasketKey(sortDirection); break; - case (POR_COMPANY): + case POR_COMPANY: query.orderByPorCompany(sortDirection); break; - case (POR_SYSTEM): + case POR_SYSTEM: query.orderByPorSystem(sortDirection); break; - case (POR_INSTANCE): + case POR_INSTANCE: query.orderByPorInstance(sortDirection); break; - case (POR_TYPE): + case POR_TYPE: query.orderByPorType(sortDirection); break; - case (POR_VALUE): + case POR_VALUE: query.orderByPorValue(sortDirection); break; - case (TASK_CLASSIFICATION_KEY): + case TASK_CLASSIFICATION_KEY: query.orderByTaskClassificationKey(sortDirection); break; - case (TASK_CLASSIFICATION_CATEGORY): + case TASK_CLASSIFICATION_CATEGORY: query.orderByTaskClassificationCategory(sortDirection); break; - case (ATTACHMENT_CLASSIFICATION_KEY): + case ATTACHMENT_CLASSIFICATION_KEY: query.orderByAttachmentClassificationKey(sortDirection); break; - case (CUSTOM_1): - query.orderByCustomAttribute(1, sortDirection); + case CUSTOM_1: + query.orderByCustomAttribute(TaskHistoryCustomField.CUSTOM_1, sortDirection); break; - case (CUSTOM_2): - query.orderByCustomAttribute(2, sortDirection); + case CUSTOM_2: + query.orderByCustomAttribute(TaskHistoryCustomField.CUSTOM_2, sortDirection); break; - case (CUSTOM_3): - query.orderByCustomAttribute(3, sortDirection); + case CUSTOM_3: + query.orderByCustomAttribute(TaskHistoryCustomField.CUSTOM_3, sortDirection); break; - case (CUSTOM_4): - query.orderByCustomAttribute(4, sortDirection); + case CUSTOM_4: + query.orderByCustomAttribute(TaskHistoryCustomField.CUSTOM_4, sortDirection); break; default: throw new IllegalArgumentException("Unknown order '" + sortBy + "'"); @@ -243,11 +242,9 @@ public class TaskHistoryEventController extends AbstractPagingController { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Exit from applySortingParams(), returning: {}", query); } - - return query; } - private HistoryQuery applyFilterParams(HistoryQuery query, MultiValueMap params) { + private void applyFilterParams(HistoryQuery query, MultiValueMap params) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Entry to applyFilterParams(query= {}, params= {})", query, params); } @@ -396,47 +393,23 @@ public class TaskHistoryEventController extends AbstractPagingController { LIKE + params.get(ATTACHMENT_CLASSIFICATION_KEY_LIKE).get(0) + LIKE); params.remove(ATTACHMENT_CLASSIFICATION_KEY_LIKE); } - if (params.containsKey(CUSTOM_1)) { - String[] custom1 = extractCommaSeparatedFields(params.get(CUSTOM_1)); - query.custom1In(custom1); - params.remove(CUSTOM_1); - } - if (params.containsKey(CUSTOM_1_LIKE)) { - query.custom1Like(LIKE + params.get(CUSTOM_1_LIKE).get(0) + LIKE); - params.remove(CUSTOM_1_LIKE); - } - if (params.containsKey(CUSTOM_2)) { - String[] custom2 = extractCommaSeparatedFields(params.get(CUSTOM_2)); - query.custom2In(custom2); - params.remove(CUSTOM_2); - } - if (params.containsKey(CUSTOM_2_LIKE)) { - query.custom2Like(LIKE + params.get(CUSTOM_2_LIKE).get(0) + LIKE); - params.remove(CUSTOM_2_LIKE); - } - if (params.containsKey(CUSTOM_3)) { - String[] custom3 = extractCommaSeparatedFields(params.get(CUSTOM_3)); - query.custom3In(custom3); - params.remove(CUSTOM_3); - } - if (params.containsKey(CUSTOM_3_LIKE)) { - query.custom3Like(LIKE + params.get(CUSTOM_3_LIKE).get(0) + LIKE); - params.remove(CUSTOM_3_LIKE); - } - if (params.containsKey(CUSTOM_4)) { - String[] custom4 = extractCommaSeparatedFields(params.get(CUSTOM_4)); - query.custom4In(custom4); - params.remove(CUSTOM_4); - } - if (params.containsKey(CUSTOM_4_LIKE)) { - query.custom4Like(LIKE + params.get(CUSTOM_4_LIKE).get(0) + LIKE); - params.remove(CUSTOM_4_LIKE); + for (TaskHistoryCustomField customField : TaskHistoryCustomField.values()) { + List list = params.remove(customField.name().replace("_", "-").toLowerCase()); + if (list != null) { + query.customAttributeIn(customField, extractCommaSeparatedFields(list)); + } + list = params.remove(customField.name().replace("_", "-").toLowerCase() + "-like"); + if (list != null) { + String[] values = extractCommaSeparatedFields(list); + for (int i = 0; i < values.length; i++) { + values[i] = LIKE + values[i] + LIKE; + } + query.customAttributeLike(customField, values); + } } if (LOGGER.isDebugEnabled()) { LOGGER.debug("Exit from applyFilterParams(), returning {}", query); } - - return query; } private TimeInterval getTimeIntervalOf(String[] created) { diff --git a/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/TaskHistoryRestConfiguration.java b/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/TaskHistoryRestConfiguration.java index 5b2d17cd6..1f188027c 100644 --- a/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/TaskHistoryRestConfiguration.java +++ b/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/TaskHistoryRestConfiguration.java @@ -6,7 +6,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.transaction.annotation.EnableTransactionManagement; import pro.taskana.simplehistory.impl.SimpleHistoryServiceImpl; -import pro.taskana.simplehistory.rest.resource.TaskHistoryEventResourceAssembler; +import pro.taskana.simplehistory.rest.assembler.TaskHistoryEventRepresentationModelAssembler; /** Configuration for Taskana history REST service. */ @Configuration @@ -20,7 +20,7 @@ public class TaskHistoryRestConfiguration { } @Bean - public TaskHistoryEventResourceAssembler getTaskHistoryEventResourceAssembler() { - return new TaskHistoryEventResourceAssembler(); + public TaskHistoryEventRepresentationModelAssembler getTaskHistoryEventResourceAssembler() { + return new TaskHistoryEventRepresentationModelAssembler(); } } diff --git a/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/resource/TaskHistoryEventListResourceAssembler.java b/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/assembler/TaskHistoryEventListResourceAssembler.java similarity index 85% rename from history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/resource/TaskHistoryEventListResourceAssembler.java rename to history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/assembler/TaskHistoryEventListResourceAssembler.java index 4caad25a7..ef3c3f76f 100644 --- a/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/resource/TaskHistoryEventListResourceAssembler.java +++ b/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/assembler/TaskHistoryEventListResourceAssembler.java @@ -1,4 +1,4 @@ -package pro.taskana.simplehistory.rest.resource; +package pro.taskana.simplehistory.rest.assembler; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; @@ -11,6 +11,8 @@ import org.springframework.hateoas.PagedModel.PageMetadata; import pro.taskana.resource.rest.AbstractRessourcesAssembler; import pro.taskana.simplehistory.impl.HistoryEventImpl; import pro.taskana.simplehistory.rest.TaskHistoryEventController; +import pro.taskana.simplehistory.rest.models.TaskHistoryEventListResource; +import pro.taskana.simplehistory.rest.models.TaskHistoryEventRepresentationModel; /** Mapper to convert from a list of HistoryEventImpl to a TaskHistoryEventResource. */ public class TaskHistoryEventListResourceAssembler extends AbstractRessourcesAssembler { @@ -18,8 +20,9 @@ public class TaskHistoryEventListResourceAssembler extends AbstractRessourcesAss public TaskHistoryEventListResource toResources( List historyEvents, PageMetadata pageMetadata) { - TaskHistoryEventResourceAssembler assembler = new TaskHistoryEventResourceAssembler(); - List resources = + TaskHistoryEventRepresentationModelAssembler assembler = + new TaskHistoryEventRepresentationModelAssembler(); + List resources = new ArrayList<>(assembler.toCollectionModel(historyEvents).getContent()); TaskHistoryEventListResource pagedResources = new TaskHistoryEventListResource(resources, pageMetadata); diff --git a/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/assembler/TaskHistoryEventRepresentationModelAssembler.java b/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/assembler/TaskHistoryEventRepresentationModelAssembler.java new file mode 100644 index 000000000..25fe2d4dc --- /dev/null +++ b/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/assembler/TaskHistoryEventRepresentationModelAssembler.java @@ -0,0 +1,60 @@ +package pro.taskana.simplehistory.rest.assembler; + +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; + +import org.springframework.hateoas.server.RepresentationModelAssembler; +import org.springframework.lang.NonNull; + +import pro.taskana.common.api.exceptions.SystemException; +import pro.taskana.simplehistory.impl.HistoryEventImpl; +import pro.taskana.simplehistory.rest.TaskHistoryEventController; +import pro.taskana.simplehistory.rest.models.TaskHistoryEventRepresentationModel; +import pro.taskana.spi.history.api.events.TaskHistoryCustomField; +import pro.taskana.spi.history.api.events.TaskanaHistoryEvent; + +/** Transforms any {@link HistoryEventImpl} into its {@link TaskHistoryEventRepresentationModel}. */ +public class TaskHistoryEventRepresentationModelAssembler + implements RepresentationModelAssembler< + TaskanaHistoryEvent, TaskHistoryEventRepresentationModel> { + + @NonNull + @Override + public TaskHistoryEventRepresentationModel toModel(@NonNull TaskanaHistoryEvent historyEvent) { + TaskHistoryEventRepresentationModel repModel = new TaskHistoryEventRepresentationModel(); + repModel.setTaskHistoryId(historyEvent.getId()); + repModel.setBusinessProcessId(historyEvent.getBusinessProcessId()); + repModel.setParentBusinessProcessId(historyEvent.getParentBusinessProcessId()); + repModel.setTaskId(historyEvent.getTaskId()); + repModel.setEventType(historyEvent.getEventType()); + repModel.setCreated(historyEvent.getCreated()); + repModel.setUserId(historyEvent.getUserId()); + repModel.setDomain(historyEvent.getDomain()); + repModel.setWorkbasketKey(historyEvent.getWorkbasketKey()); + repModel.setPorCompany(historyEvent.getPorCompany()); + repModel.setPorType(historyEvent.getPorType()); + repModel.setPorInstance(historyEvent.getPorInstance()); + repModel.setPorSystem(historyEvent.getPorSystem()); + repModel.setPorValue(historyEvent.getPorValue()); + repModel.setTaskClassificationKey(historyEvent.getTaskClassificationKey()); + repModel.setTaskClassificationCategory(historyEvent.getTaskClassificationCategory()); + repModel.setAttachmentClassificationKey(historyEvent.getAttachmentClassificationKey()); + repModel.setOldValue(historyEvent.getOldValue()); + repModel.setNewValue(historyEvent.getNewValue()); + repModel.setCustom1(historyEvent.getCustomAttribute(TaskHistoryCustomField.CUSTOM_1)); + repModel.setCustom2(historyEvent.getCustomAttribute(TaskHistoryCustomField.CUSTOM_2)); + repModel.setCustom3(historyEvent.getCustomAttribute(TaskHistoryCustomField.CUSTOM_3)); + repModel.setCustom4(historyEvent.getCustomAttribute(TaskHistoryCustomField.CUSTOM_4)); + repModel.setDetails(historyEvent.getDetails()); + try { + repModel.add( + linkTo( + methodOn(TaskHistoryEventController.class) + .getTaskHistoryEvent(historyEvent.getId())) + .withSelfRel()); + } catch (Exception e) { + throw new SystemException("caught unexpecte Exception", e); + } + return repModel; + } +} diff --git a/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/models/TaskHistoryEventListResource.java b/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/models/TaskHistoryEventListResource.java new file mode 100644 index 000000000..d9d2f1496 --- /dev/null +++ b/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/models/TaskHistoryEventListResource.java @@ -0,0 +1,29 @@ +package pro.taskana.simplehistory.rest.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.Collection; +import org.springframework.hateoas.Link; +import org.springframework.hateoas.PagedModel.PageMetadata; + +import pro.taskana.common.rest.models.PagedResources; + +/** Resource class for {@link TaskHistoryEventRepresentationModel} with Pagination. */ +public class TaskHistoryEventListResource + extends PagedResources { + + @SuppressWarnings("unused") + private TaskHistoryEventListResource() {} + + public TaskHistoryEventListResource( + Collection content, + PageMetadata metadata, + Link... links) { + super(content, metadata, links); + } + + @Override + @JsonProperty("taskHistoryEvents") + public Collection getContent() { + return super.getContent(); + } +} diff --git a/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/resource/TaskHistoryEventResource.java b/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/models/TaskHistoryEventRepresentationModel.java similarity index 73% rename from history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/resource/TaskHistoryEventResource.java rename to history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/models/TaskHistoryEventRepresentationModel.java index f798fb184..a78997e66 100644 --- a/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/resource/TaskHistoryEventResource.java +++ b/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/models/TaskHistoryEventRepresentationModel.java @@ -1,18 +1,20 @@ -package pro.taskana.simplehistory.rest.resource; +package pro.taskana.simplehistory.rest.models; +import java.time.Instant; import org.springframework.hateoas.RepresentationModel; import pro.taskana.spi.history.api.events.TaskanaHistoryEvent; /** Resource class for {@link TaskanaHistoryEvent}. */ -public class TaskHistoryEventResource extends RepresentationModel { +public class TaskHistoryEventRepresentationModel + extends RepresentationModel { - private String taskHistoryEventId; + private String taskHistoryId; private String businessProcessId; private String parentBusinessProcessId; private String taskId; private String eventType; - private String created; + private Instant created; private String userId; private String domain; private String workbasketKey; @@ -33,11 +35,11 @@ public class TaskHistoryEventResource extends RepresentationModel { - - public TaskHistoryEventListResource() { - super(); - } - - public TaskHistoryEventListResource( - Collection content, PageMetadata metadata, Link... links) { - super(content, metadata, links); - } - - public TaskHistoryEventListResource( - Collection content, PageMetadata metadata, Iterable links) { - super(content, metadata, links); - } - - @Override - @JsonProperty("taskHistoryEvents") - public Collection getContent() { - return super.getContent(); - } -} diff --git a/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/resource/TaskHistoryEventResourceAssembler.java b/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/resource/TaskHistoryEventResourceAssembler.java deleted file mode 100644 index 30369de84..000000000 --- a/history/taskana-simplehistory-rest-spring/src/main/java/pro/taskana/simplehistory/rest/resource/TaskHistoryEventResourceAssembler.java +++ /dev/null @@ -1,46 +0,0 @@ -package pro.taskana.simplehistory.rest.resource; - -import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; -import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; - -import org.springframework.beans.BeanUtils; -import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport; -import org.springframework.lang.NonNull; - -import pro.taskana.common.api.exceptions.SystemException; -import pro.taskana.simplehistory.impl.HistoryEventImpl; -import pro.taskana.simplehistory.rest.TaskHistoryEventController; -import pro.taskana.spi.history.api.events.TaskanaHistoryEvent; -import pro.taskana.spi.history.api.exceptions.TaskanaHistoryEventNotFoundException; - -/** Transforms any {@link HistoryEventImpl} into its {@link TaskHistoryEventResource}. */ -public class TaskHistoryEventResourceAssembler - extends RepresentationModelAssemblerSupport { - - public TaskHistoryEventResourceAssembler() { - super(HistoryEventImpl.class, TaskHistoryEventResource.class); - } - - @NonNull - @Override - public TaskHistoryEventResource toModel(@NonNull TaskanaHistoryEvent historyEvent) { - TaskHistoryEventResource resource = createModelWithId(historyEvent.getId(), historyEvent); - try { - resource.removeLinks(); - resource.add( - linkTo( - methodOn(TaskHistoryEventController.class) - .getTaskHistoryEvent(String.valueOf(historyEvent.getId()))) - .withSelfRel()); - } catch (TaskanaHistoryEventNotFoundException e) { - throw new SystemException("caught unexpected Exception.", e.getCause()); - } - BeanUtils.copyProperties(historyEvent, resource); - if (historyEvent.getCreated() != null) { - resource.setCreated(historyEvent.getCreated().toString()); - } - resource.setTaskHistoryId(String.valueOf(historyEvent.getId())); - - return resource; - } -} diff --git a/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/TaskHistoryEventResourceAssemblerTest.java b/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/TaskHistoryEventResourceAssemblerTest.java deleted file mode 100644 index 8910004da..000000000 --- a/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/TaskHistoryEventResourceAssemblerTest.java +++ /dev/null @@ -1,94 +0,0 @@ -package pro.taskana; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.time.Instant; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import pro.taskana.simplehistory.impl.HistoryEventImpl; -import pro.taskana.simplehistory.rest.TaskHistoryRestConfiguration; -import pro.taskana.simplehistory.rest.resource.TaskHistoryEventResource; -import pro.taskana.simplehistory.rest.resource.TaskHistoryEventResourceAssembler; -import pro.taskana.spi.history.api.events.TaskanaHistoryEvent; - -/** Test for {@link TaskHistoryEventResourceAssembler}. */ -@ExtendWith(SpringExtension.class) -@SpringBootTest( - classes = {TaskHistoryRestConfiguration.class}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -class TaskHistoryEventResourceAssemblerTest { - - private final TaskHistoryEventResourceAssembler taskHistoryEventResourceAssembler; - - @Autowired - TaskHistoryEventResourceAssemblerTest( - TaskHistoryEventResourceAssembler taskHistoryEventResourceAssembler) { - this.taskHistoryEventResourceAssembler = taskHistoryEventResourceAssembler; - } - - @Test - void taskHistoryEventModelToResource() { - - HistoryEventImpl historyEvent = - new HistoryEventImpl("HEI:000000000000000000000000000000000000", "user1", "someDetails"); - - historyEvent.setEventType("TASK_CREATED"); - historyEvent.setBusinessProcessId("BPI:01"); - historyEvent.setParentBusinessProcessId("BPI:02"); - historyEvent.setTaskId("TKI:000000000000000000000000000000000000"); - historyEvent.setTaskClassificationCategory("MANUAL"); - historyEvent.setDomain("DOMAIN_A"); - historyEvent.setWorkbasketKey("WorkbasketKey"); - historyEvent.setAttachmentClassificationKey("L1050"); - historyEvent.setCreated(Instant.now()); - historyEvent.setOldValue("oldValue"); - historyEvent.setNewValue("newValue"); - historyEvent.setPorCompany("porCompany"); - historyEvent.setPorSystem("porSystem"); - historyEvent.setPorType("porType"); - historyEvent.setPorValue("porValue"); - historyEvent.setCustom1("custom1"); - historyEvent.setCustom2("custom2"); - historyEvent.setCustom3("custom3"); - historyEvent.setCustom4("custom4"); - - TaskHistoryEventResource taskHistoryEventResource = - taskHistoryEventResourceAssembler.toModel(historyEvent); - - testEquality(historyEvent, taskHistoryEventResource); - } - - private void testEquality( - TaskanaHistoryEvent historyEvent, TaskHistoryEventResource taskHistoryEventResource) { - - assertThat(historyEvent.getEventType()).isEqualTo(taskHistoryEventResource.getEventType()); - assertThat(historyEvent.getBusinessProcessId()) - .isEqualTo(taskHistoryEventResource.getBusinessProcessId()); - assertThat(historyEvent.getParentBusinessProcessId()) - .isEqualTo(taskHistoryEventResource.getParentBusinessProcessId()); - assertThat(historyEvent.getTaskId()).isEqualTo(taskHistoryEventResource.getTaskId()); - assertThat(historyEvent.getTaskClassificationCategory()) - .isEqualTo(taskHistoryEventResource.getTaskClassificationCategory()); - assertThat(historyEvent.getDomain()).isEqualTo(taskHistoryEventResource.getDomain()); - assertThat(historyEvent.getWorkbasketKey()) - .isEqualTo(taskHistoryEventResource.getWorkbasketKey()); - assertThat(historyEvent.getAttachmentClassificationKey()) - .isEqualTo(taskHistoryEventResource.getAttachmentClassificationKey()); - assertThat(historyEvent.getCreated()) - .isEqualTo(Instant.parse(taskHistoryEventResource.getCreated())); - assertThat(historyEvent.getOldValue()).isEqualTo(taskHistoryEventResource.getOldValue()); - assertThat(historyEvent.getNewValue()).isEqualTo(taskHistoryEventResource.getNewValue()); - assertThat(historyEvent.getPorCompany()).isEqualTo(taskHistoryEventResource.getPorCompany()); - assertThat(historyEvent.getPorSystem()).isEqualTo(taskHistoryEventResource.getPorSystem()); - assertThat(historyEvent.getPorType()).isEqualTo(taskHistoryEventResource.getPorType()); - assertThat(historyEvent.getPorValue()).isEqualTo(taskHistoryEventResource.getPorValue()); - assertThat(historyEvent.getCustom1()).isEqualTo(taskHistoryEventResource.getCustom1()); - assertThat(historyEvent.getCustom2()).isEqualTo(taskHistoryEventResource.getCustom2()); - assertThat(historyEvent.getCustom3()).isEqualTo(taskHistoryEventResource.getCustom3()); - assertThat(historyEvent.getCustom4()).isEqualTo(taskHistoryEventResource.getCustom4()); - } -} diff --git a/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/doc/api/TaskHistoryEventControllerRestDocumentation.java b/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/doc/api/TaskHistoryEventControllerRestDocumentation.java index 47ccc78c4..5b8377185 100644 --- a/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/doc/api/TaskHistoryEventControllerRestDocumentation.java +++ b/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/doc/api/TaskHistoryEventControllerRestDocumentation.java @@ -39,7 +39,7 @@ public class TaskHistoryEventControllerRestDocumentation { private MockMvc mockMvc; - private HashMap taskHistoryEventFieldDescriptionsMap = new HashMap<>(); + private final HashMap taskHistoryEventFieldDescriptionsMap = new HashMap<>(); private FieldDescriptor[] allTaskHistoryEventFieldDescriptors; diff --git a/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/rest/ExampleDocumentationApplication.java b/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/simplehistory/rest/ExampleDocumentationApplication.java similarity index 96% rename from history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/rest/ExampleDocumentationApplication.java rename to history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/simplehistory/rest/ExampleDocumentationApplication.java index f88aa7b14..4970a4878 100644 --- a/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/rest/ExampleDocumentationApplication.java +++ b/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/simplehistory/rest/ExampleDocumentationApplication.java @@ -1,4 +1,4 @@ -package pro.taskana.rest; +package pro.taskana.simplehistory.rest; import java.sql.SQLException; import javax.sql.DataSource; @@ -15,7 +15,6 @@ import org.springframework.context.annotation.Primary; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; -import pro.taskana.simplehistory.rest.TaskHistoryRestConfiguration; import pro.taskana.simplehistory.rest.sampledata.SampleDataGenerator; /** Example Application to create the documentation. */ diff --git a/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/TaskHistoryEventControllerIntTest.java b/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/simplehistory/rest/TaskHistoryEventControllerIntTest.java similarity index 77% rename from history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/TaskHistoryEventControllerIntTest.java rename to history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/simplehistory/rest/TaskHistoryEventControllerIntTest.java index 35cea5377..c2f602b86 100644 --- a/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/TaskHistoryEventControllerIntTest.java +++ b/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/simplehistory/rest/TaskHistoryEventControllerIntTest.java @@ -1,10 +1,13 @@ -package pro.taskana; +package pro.taskana.simplehistory.rest; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; import java.time.LocalDateTime; import java.util.Collections; import org.assertj.core.api.ThrowableAssert.ThrowingCallable; @@ -15,6 +18,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.core.ParameterizedTypeReference; import org.springframework.hateoas.IanaLinkRelations; +import org.springframework.hateoas.Link; import org.springframework.hateoas.mediatype.hal.Jackson2HalModule; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; @@ -26,9 +30,8 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; -import pro.taskana.simplehistory.rest.TaskHistoryRestConfiguration; -import pro.taskana.simplehistory.rest.resource.TaskHistoryEventListResource; -import pro.taskana.simplehistory.rest.resource.TaskHistoryEventResource; +import pro.taskana.simplehistory.rest.models.TaskHistoryEventListResource; +import pro.taskana.simplehistory.rest.models.TaskHistoryEventRepresentationModel; /** Controller for integration test. */ @ExtendWith(SpringExtension.class) @@ -56,6 +59,7 @@ class TaskHistoryEventControllerIntTest { HttpMethod.GET, request, ParameterizedTypeReference.forType(TaskHistoryEventListResource.class)); + assertThat(response.getBody()).isNotNull(); assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isNotNull(); assertThat(response.getBody().getContent()).hasSize(45); } @@ -70,15 +74,14 @@ class TaskHistoryEventControllerIntTest { HttpMethod.GET, request, ParameterizedTypeReference.forType(TaskHistoryEventListResource.class)); - assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isNotNull(); + assertThat(response.getBody()).isNotNull(); assertThat(response.getBody().getContent()).hasSize(3); - assertThat( - response - .getBody() - .getRequiredLink(IanaLinkRelations.SELF) - .getHref() - .endsWith(parameters)) - .isTrue(); + assertThat(response.getBody().getLink(IanaLinkRelations.SELF)) + .isNotNull() + .get() + .extracting(Link::getHref) + .asString() + .endsWith(parameters); } @Test @@ -92,38 +95,36 @@ class TaskHistoryEventControllerIntTest { HttpMethod.GET, request, ParameterizedTypeReference.forType(TaskHistoryEventListResource.class)); - + assertThat(response.getBody()).isNotNull(); assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isNotNull(); - assertThat(response.getBody().getLinks()).isNotNull(); assertThat(response.getBody().getMetadata()).isNotNull(); assertThat(response.getBody().getContent()).hasSize(1); - assertThat(response.getBody().getContent().stream().findFirst().get().getDetails()).isNull(); + assertThat(response.getBody().getContent().iterator().next().getDetails()).isNull(); } @Test void should_ReturnSpecificTaskHistoryEventWithDetails_When_SingleEventIsQueried() { - ResponseEntity response = + ResponseEntity response = template.exchange( server + port + "/api/v1/task-history-event/HEI:000000000000000000000000000000000000", HttpMethod.GET, request, - ParameterizedTypeReference.forType(TaskHistoryEventResource.class)); + ParameterizedTypeReference.forType(TaskHistoryEventRepresentationModel.class)); + assertThat(response.getBody()).isNotNull(); assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isNotNull(); - assertThat(response.getBody().getLinks()).isNotNull(); assertThat(response.getBody().getDetails()).isNotNull(); } @Test void testThrowsExceptionIfInvalidFilterIsUsed() { ThrowingCallable httpCall = - () -> { - template.exchange( - server + port + "/api/v1/task-history-event?invalid=BPI:01", - HttpMethod.GET, - request, - ParameterizedTypeReference.forType(TaskHistoryEventListResource.class)); - }; + () -> + template.exchange( + server + port + "/api/v1/task-history-event?invalid=BPI:01", + HttpMethod.GET, + request, + ParameterizedTypeReference.forType(TaskHistoryEventListResource.class)); assertThatThrownBy(httpCall) .isInstanceOf(HttpClientErrorException.class) .hasMessageContaining("[invalid]") @@ -136,13 +137,12 @@ class TaskHistoryEventControllerIntTest { String currentTime = LocalDateTime.now().toString(); final String finalCurrentTime = currentTime; ThrowingCallable httpCall = - () -> { - template.exchange( - server + port + "/api/v1/task-history-event?created=" + finalCurrentTime, - HttpMethod.GET, - request, - ParameterizedTypeReference.forType(TaskHistoryEventListResource.class)); - }; + () -> + template.exchange( + server + port + "/api/v1/task-history-event?created=" + finalCurrentTime, + HttpMethod.GET, + request, + ParameterizedTypeReference.forType(TaskHistoryEventListResource.class)); assertThatThrownBy(httpCall) .isInstanceOf(HttpClientErrorException.class) .hasMessageContaining(currentTime) @@ -157,6 +157,7 @@ class TaskHistoryEventControllerIntTest { HttpMethod.GET, request, ParameterizedTypeReference.forType(TaskHistoryEventListResource.class)); + assertThat(response.getBody()).isNotNull(); assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isNotNull(); assertThat(response.getBody().getContent()).hasSize(23); } @@ -172,25 +173,23 @@ class TaskHistoryEventControllerIntTest { request, ParameterizedTypeReference.forType(TaskHistoryEventListResource.class)); + assertThat(response.getBody()).isNotNull(); assertThat(response.getBody().getContent()).hasSize(2); assertThat(response.getBody().getContent().iterator().next().getWorkbasketKey()) .isEqualTo("WBI:100000000000000000000000000000000002"); - assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isNotNull(); - assertThat( - response - .getBody() - .getRequiredLink(IanaLinkRelations.SELF) - .getHref() - .endsWith(parameters)) - .isTrue(); - assertThat(response.getBody().getLink("allTaskHistoryEvent")).isNotNull(); - assertThat( - response - .getBody() - .getRequiredLink("allTaskHistoryEvent") - .getHref() - .endsWith("/api/v1/task-history-event")) - .isTrue(); + assertThat(response.getBody().getLink(IanaLinkRelations.SELF)) + .isNotNull() + .get() + .extracting(Link::getHref) + .asString() + .endsWith(parameters); + assertThat(response.getBody().getLink("allTaskHistoryEvent")) + .isNotNull() + .get() + .extracting(Link::getHref) + .asString() + .endsWith("/api/v1/task-history-event"); + assertThat(response.getBody().getLink(IanaLinkRelations.FIRST)).isNotNull(); assertThat(response.getBody().getLink(IanaLinkRelations.LAST)).isNotNull(); } @@ -204,6 +203,10 @@ class TaskHistoryEventControllerIntTest { ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.registerModule(new Jackson2HalModule()); + mapper + .registerModule(new ParameterNamesModule()) + .registerModule(new Jdk8Module()) + .registerModule(new JavaTimeModule()); MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json")); diff --git a/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/simplehistory/rest/assembler/TaskHistoryEventRepresentationModelAssemblerTest.java b/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/simplehistory/rest/assembler/TaskHistoryEventRepresentationModelAssemblerTest.java new file mode 100644 index 000000000..e9897c116 --- /dev/null +++ b/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/simplehistory/rest/assembler/TaskHistoryEventRepresentationModelAssemblerTest.java @@ -0,0 +1,108 @@ +package pro.taskana.simplehistory.rest.assembler; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.Instant; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import pro.taskana.simplehistory.impl.HistoryEventImpl; +import pro.taskana.simplehistory.rest.TaskHistoryRestConfiguration; +import pro.taskana.simplehistory.rest.models.TaskHistoryEventRepresentationModel; +import pro.taskana.spi.history.api.events.TaskHistoryCustomField; +import pro.taskana.spi.history.api.events.TaskanaHistoryEvent; + +/** Test for {@link TaskHistoryEventRepresentationModelAssembler}. */ +@ExtendWith(SpringExtension.class) +@SpringBootTest( + classes = {TaskHistoryRestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +class TaskHistoryEventRepresentationModelAssemblerTest { + + private final TaskHistoryEventRepresentationModelAssembler + taskHistoryEventRepresentationModelAssembler; + + @Autowired + TaskHistoryEventRepresentationModelAssemblerTest( + TaskHistoryEventRepresentationModelAssembler taskHistoryEventRepresentationModelAssembler) { + this.taskHistoryEventRepresentationModelAssembler = + taskHistoryEventRepresentationModelAssembler; + } + + @Test + void taskHistoryEventModelToResource() { + + HistoryEventImpl historyEvent = + new HistoryEventImpl("HEI:000000000000000000000000000000000000", "user1", "someDetails"); + + historyEvent.setEventType("TASK_CREATED"); + historyEvent.setBusinessProcessId("BPI:01"); + historyEvent.setParentBusinessProcessId("BPI:02"); + historyEvent.setTaskId("TKI:000000000000000000000000000000000000"); + historyEvent.setTaskClassificationCategory("MANUAL"); + historyEvent.setDomain("DOMAIN_A"); + historyEvent.setWorkbasketKey("WorkbasketKey"); + historyEvent.setAttachmentClassificationKey("L1050"); + historyEvent.setCreated(Instant.now()); + historyEvent.setOldValue("oldValue"); + historyEvent.setNewValue("newValue"); + historyEvent.setPorCompany("porCompany"); + historyEvent.setPorSystem("porSystem"); + historyEvent.setPorType("porType"); + historyEvent.setPorValue("porValue"); + historyEvent.setCustomAttribute(TaskHistoryCustomField.CUSTOM_1, "custom1"); + historyEvent.setCustomAttribute(TaskHistoryCustomField.CUSTOM_2, "custom2"); + historyEvent.setCustomAttribute(TaskHistoryCustomField.CUSTOM_3, "custom3"); + historyEvent.setCustomAttribute(TaskHistoryCustomField.CUSTOM_4, "custom4"); + + TaskHistoryEventRepresentationModel taskHistoryEventRepresentationModel = + taskHistoryEventRepresentationModelAssembler.toModel(historyEvent); + + testEquality(historyEvent, taskHistoryEventRepresentationModel); + } + + private void testEquality( + TaskanaHistoryEvent historyEvent, + TaskHistoryEventRepresentationModel taskHistoryEventRepresentationModel) { + + assertThat(historyEvent.getEventType()) + .isEqualTo(taskHistoryEventRepresentationModel.getEventType()); + assertThat(historyEvent.getBusinessProcessId()) + .isEqualTo(taskHistoryEventRepresentationModel.getBusinessProcessId()); + assertThat(historyEvent.getParentBusinessProcessId()) + .isEqualTo(taskHistoryEventRepresentationModel.getParentBusinessProcessId()); + assertThat(historyEvent.getTaskId()).isEqualTo(taskHistoryEventRepresentationModel.getTaskId()); + assertThat(historyEvent.getTaskClassificationCategory()) + .isEqualTo(taskHistoryEventRepresentationModel.getTaskClassificationCategory()); + assertThat(historyEvent.getDomain()).isEqualTo(taskHistoryEventRepresentationModel.getDomain()); + assertThat(historyEvent.getWorkbasketKey()) + .isEqualTo(taskHistoryEventRepresentationModel.getWorkbasketKey()); + assertThat(historyEvent.getAttachmentClassificationKey()) + .isEqualTo(taskHistoryEventRepresentationModel.getAttachmentClassificationKey()); + assertThat(historyEvent.getCreated()) + .isEqualTo(taskHistoryEventRepresentationModel.getCreated()); + assertThat(historyEvent.getOldValue()) + .isEqualTo(taskHistoryEventRepresentationModel.getOldValue()); + assertThat(historyEvent.getNewValue()) + .isEqualTo(taskHistoryEventRepresentationModel.getNewValue()); + assertThat(historyEvent.getPorCompany()) + .isEqualTo(taskHistoryEventRepresentationModel.getPorCompany()); + assertThat(historyEvent.getPorSystem()) + .isEqualTo(taskHistoryEventRepresentationModel.getPorSystem()); + assertThat(historyEvent.getPorType()) + .isEqualTo(taskHistoryEventRepresentationModel.getPorType()); + assertThat(historyEvent.getPorValue()) + .isEqualTo(taskHistoryEventRepresentationModel.getPorValue()); + assertThat(historyEvent.getCustomAttribute(TaskHistoryCustomField.CUSTOM_1)) + .isEqualTo(taskHistoryEventRepresentationModel.getCustom1()); + assertThat(historyEvent.getCustomAttribute(TaskHistoryCustomField.CUSTOM_2)) + .isEqualTo(taskHistoryEventRepresentationModel.getCustom2()); + assertThat(historyEvent.getCustomAttribute(TaskHistoryCustomField.CUSTOM_3)) + .isEqualTo(taskHistoryEventRepresentationModel.getCustom3()); + assertThat(historyEvent.getCustomAttribute(TaskHistoryCustomField.CUSTOM_4)) + .isEqualTo(taskHistoryEventRepresentationModel.getCustom4()); + } +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/classification/api/ClassificationCustomField.java b/lib/taskana-core/src/main/java/pro/taskana/classification/api/ClassificationCustomField.java new file mode 100644 index 000000000..7b1e8033c --- /dev/null +++ b/lib/taskana-core/src/main/java/pro/taskana/classification/api/ClassificationCustomField.java @@ -0,0 +1,12 @@ +package pro.taskana.classification.api; + +public enum ClassificationCustomField { + CUSTOM_1, + CUSTOM_2, + CUSTOM_3, + CUSTOM_4, + CUSTOM_5, + CUSTOM_6, + CUSTOM_7, + CUSTOM_8 +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/classification/api/ClassificationQuery.java b/lib/taskana-core/src/main/java/pro/taskana/classification/api/ClassificationQuery.java index 2d0a598e4..fc0b04daa 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/classification/api/ClassificationQuery.java +++ b/lib/taskana-core/src/main/java/pro/taskana/classification/api/ClassificationQuery.java @@ -157,25 +157,29 @@ public interface ClassificationQuery ClassificationQuery applicationEntryPointLike(String... applicationEntryPointLike); /** - * Add a custom to your query. + * Add the values of custom attributes for exact matching to your query. * - * @param num the number of the custom as String (eg "4") - * @param customIn filter for this custom + * @param customField identifies which custom attribute is affected. + * @param searchArguments the customField values of the searched for tasks * @return the query - * @throws InvalidArgumentException when the number of the custom is incorrect. + * @throws InvalidArgumentException when searchArguments is empty or null */ - ClassificationQuery customAttributeIn(String num, String... customIn) + ClassificationQuery customAttributeIn( + ClassificationCustomField customField, String... searchArguments) throws InvalidArgumentException; /** - * Add a custom to your query. + * Add the values of custom attributes for pattern matching to your query. They will be compared + * in SQL with the LIKE operator. You may use a wildcard like % to specify the pattern. If you + * specify multiple arguments they are combined with the OR keyword. * - * @param num the number of the custom as String (eg "4") - * @param customLike filter for this custom with a LIKE-query + * @param customField identifies which custom attribute is affected. + * @param searchArguments the customField values of the searched-for tasks * @return the query - * @throws InvalidArgumentException when the number of the custom is incorrect. + * @throws InvalidArgumentException when searchArguments is empty or null */ - ClassificationQuery customAttributeLike(String num, String... customLike) + ClassificationQuery customAttributeLike( + ClassificationCustomField customField, String... searchArguments) throws InvalidArgumentException; /** @@ -260,14 +264,13 @@ public interface ClassificationQuery ClassificationQuery orderByApplicationEntryPoint(SortDirection sortDirection); /** - * Sort the query result by a custom. + * This method sorts the query result according to the value of a custom field. * - * @param num the number of the custom as String (eg "4") + * @param customField identifies which custom attribute is affected. * @param sortDirection Determines whether the result is sorted in ascending or descending order. * If sortDirection is null, the result is sorted in ascending order * @return the query - * @throws InvalidArgumentException when the number of the custom is incorrect. */ - ClassificationQuery orderByCustomAttribute(String num, SortDirection sortDirection) - throws InvalidArgumentException; + ClassificationQuery orderByCustomAttribute( + ClassificationCustomField customField, SortDirection sortDirection); } diff --git a/lib/taskana-core/src/main/java/pro/taskana/classification/api/models/Classification.java b/lib/taskana-core/src/main/java/pro/taskana/classification/api/models/Classification.java index 0981e04cb..85b5b12bf 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/classification/api/models/Classification.java +++ b/lib/taskana-core/src/main/java/pro/taskana/classification/api/models/Classification.java @@ -2,6 +2,8 @@ package pro.taskana.classification.api.models; import java.time.Instant; +import pro.taskana.classification.api.ClassificationCustomField; + /** Interface used to specify the Classification-Model. */ public interface Classification extends ClassificationSummary { @@ -123,60 +125,12 @@ public interface Classification extends ClassificationSummary { void setServiceLevel(String serviceLevel); /** - * Set/Change the 1. custom-attribute. + * Sets the value for custom Attribute. * - * @param custom1 the first custom attribute + * @param customField identifies which custom attribute is to be set. + * @param value the value of the custom attribute to be set */ - void setCustom1(String custom1); - - /** - * Set/Change the 2. custom-attribute. - * - * @param custom2 the second custom attribute - */ - void setCustom2(String custom2); - - /** - * Set/Change the 3. custom-attribute. - * - * @param custom3 the third custom attribute - */ - void setCustom3(String custom3); - - /** - * Set/Change the 4. custom-attribute. - * - * @param custom4 the fourth custom attribute - */ - void setCustom4(String custom4); - - /** - * Set/Change the 5. custom-attribute. - * - * @param custom5 the fifth custom attribute - */ - void setCustom5(String custom5); - - /** - * Set/Change the 6. custom-attribute. - * - * @param custom6 the sixth custom attribute - */ - void setCustom6(String custom6); - - /** - * Set/Change the 7. custom-attribute. - * - * @param custom7 the seventh custom attribute - */ - void setCustom7(String custom7); - - /** - * Set/Change the 8. custom-attribute. - * - * @param custom8 the eight custom attribute - */ - void setCustom8(String custom8); + void setCustomAttribute(ClassificationCustomField customField, String value); /** * Return a summary of the current Classification. diff --git a/lib/taskana-core/src/main/java/pro/taskana/classification/api/models/ClassificationSummary.java b/lib/taskana-core/src/main/java/pro/taskana/classification/api/models/ClassificationSummary.java index 493c863dd..b8f77f6a9 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/classification/api/models/ClassificationSummary.java +++ b/lib/taskana-core/src/main/java/pro/taskana/classification/api/models/ClassificationSummary.java @@ -1,5 +1,7 @@ package pro.taskana.classification.api.models; +import pro.taskana.classification.api.ClassificationCustomField; + /** * Interface for ClassificationSummaries. This is a specific short model-object which only requieres * the most important informations. Specific ones can be load afterwards via ID. @@ -85,60 +87,12 @@ public interface ClassificationSummary { int getPriority(); /** - * Get the 1. custom-attribute. + * Gets the custom attribute of the classification. * - * @return custom1 + * @param customField identifies which custom attribute is requested. + * @return the value for the given customField */ - String getCustom1(); - - /** - * Get the 2. custom-attribute. - * - * @return custom2 - */ - String getCustom2(); - - /** - * Get the 3. custom-attribute. - * - * @return custom3 - */ - String getCustom3(); - - /** - * Get the 4. custom-attribute. - * - * @return custom4 - */ - String getCustom4(); - - /** - * Get the 5. custom-attribute. - * - * @return custom5 - */ - String getCustom5(); - - /** - * Get the 6. custom-attribute. - * - * @return custom6 - */ - String getCustom6(); - - /** - * Get the 7. custom-attribute. - * - * @return custom7 - */ - String getCustom7(); - - /** - * Get the 8. custom-attribute. - * - * @return custom8 - */ - String getCustom8(); + String getCustomAttribute(ClassificationCustomField customField); /** * Duplicates this ClassificationSummary without the id. diff --git a/lib/taskana-core/src/main/java/pro/taskana/classification/internal/ClassificationQueryImpl.java b/lib/taskana-core/src/main/java/pro/taskana/classification/internal/ClassificationQueryImpl.java index 94938aae3..63d3afdf4 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/classification/internal/ClassificationQueryImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/classification/internal/ClassificationQueryImpl.java @@ -8,11 +8,13 @@ import org.apache.ibatis.session.RowBounds; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import pro.taskana.classification.api.ClassificationCustomField; import pro.taskana.classification.api.ClassificationQuery; import pro.taskana.classification.api.ClassificationQueryColumnName; import pro.taskana.classification.api.models.ClassificationSummary; import pro.taskana.common.api.TimeInterval; import pro.taskana.common.api.exceptions.InvalidArgumentException; +import pro.taskana.common.api.exceptions.SystemException; import pro.taskana.common.api.exceptions.TaskanaRuntimeException; import pro.taskana.common.internal.InternalTaskanaEngine; @@ -31,7 +33,9 @@ public class ClassificationQueryImpl implements ClassificationQuery { "pro.taskana.classification.internal.ClassificationQueryMapper." + "queryClassificationColumnValues"; private static final Logger LOGGER = LoggerFactory.getLogger(ClassificationQueryImpl.class); - private InternalTaskanaEngine taskanaEngine; + private final InternalTaskanaEngine taskanaEngine; + private final List orderBy; + private final List orderColumns; private ClassificationQueryColumnName columnName; private String[] key; private String[] idIn; @@ -67,8 +71,6 @@ public class ClassificationQueryImpl implements ClassificationQuery { private String[] custom7Like; private String[] custom8In; private String[] custom8Like; - private List orderBy; - private List orderColumns; ClassificationQueryImpl(InternalTaskanaEngine taskanaEngine) { this.taskanaEngine = taskanaEngine; @@ -195,106 +197,80 @@ public class ClassificationQueryImpl implements ClassificationQuery { } @Override - public ClassificationQuery customAttributeIn(String number, String... customIn) - throws InvalidArgumentException { - int num = 0; - try { - num = Integer.parseInt(number); - } catch (NumberFormatException e) { - throw new InvalidArgumentException( - "Argument '" - + number - + "' to getCustomAttribute cannot be converted to a number between 1 and 8", - e.getCause()); - } + public ClassificationQuery customAttributeIn( + ClassificationCustomField customField, String... customIn) throws InvalidArgumentException { if (customIn.length == 0) { throw new InvalidArgumentException( "At least one string has to be provided as a search parameter"); } - switch (num) { - case 1: + switch (customField) { + case CUSTOM_1: this.custom1In = customIn; break; - case 2: + case CUSTOM_2: this.custom2In = customIn; break; - case 3: + case CUSTOM_3: this.custom3In = customIn; break; - case 4: + case CUSTOM_4: this.custom4In = customIn; break; - case 5: + case CUSTOM_5: this.custom5In = customIn; break; - case 6: + case CUSTOM_6: this.custom6In = customIn; break; - case 7: + case CUSTOM_7: this.custom7In = customIn; break; - case 8: + case CUSTOM_8: this.custom8In = customIn; break; default: - throw new InvalidArgumentException( - "Argument '" - + number - + "' to getCustomAttribute does not represent a number between 1 and 8"); + throw new SystemException("Unknown customField '" + customField + "'"); } return this; } @Override - public ClassificationQuery customAttributeLike(String number, String... customLike) - throws InvalidArgumentException { - int num = 0; - try { - num = Integer.parseInt(number); - } catch (NumberFormatException e) { - throw new InvalidArgumentException( - "Argument '" - + number - + "' to getCustomAttribute cannot be converted to a number between 1 and 16", - e.getCause()); - } + public ClassificationQuery customAttributeLike( + ClassificationCustomField customField, String... customLike) throws InvalidArgumentException { if (customLike.length == 0) { throw new InvalidArgumentException( "At least one string has to be provided as a search parameter"); } - switch (num) { - case 1: + switch (customField) { + case CUSTOM_1: this.custom1Like = toUpperCopy(customLike); break; - case 2: + case CUSTOM_2: this.custom2Like = toUpperCopy(customLike); break; - case 3: + case CUSTOM_3: this.custom3Like = toUpperCopy(customLike); break; - case 4: + case CUSTOM_4: this.custom4Like = toUpperCopy(customLike); break; - case 5: + case CUSTOM_5: this.custom5Like = toUpperCopy(customLike); break; - case 6: + case CUSTOM_6: this.custom6Like = toUpperCopy(customLike); break; - case 7: + case CUSTOM_7: this.custom7Like = toUpperCopy(customLike); break; - case 8: + case CUSTOM_8: this.custom8Like = toUpperCopy(customLike); break; default: - throw new InvalidArgumentException( - "Argument '" - + number - + "' to getCustomAttribute does not represent a number between 1 and 16"); + throw new SystemException("Unknown customField '" + customField + "'"); } return this; @@ -346,42 +322,9 @@ public class ClassificationQueryImpl implements ClassificationQuery { } @Override - public ClassificationQuery orderByCustomAttribute(String number, SortDirection sortDirection) - throws InvalidArgumentException { - int num = 0; - try { - num = Integer.parseInt(number); - } catch (NumberFormatException e) { - throw new InvalidArgumentException( - "Argument '" - + number - + "' to getCustomAttribute cannot be converted to a number between 1 and 16", - e.getCause()); - } - - switch (num) { - case 1: - return addOrderCriteria("CUSTOM_1", sortDirection); - case 2: - return addOrderCriteria("CUSTOM_2", sortDirection); - case 3: - return addOrderCriteria("CUSTOM_3", sortDirection); - case 4: - return addOrderCriteria("CUSTOM_4", sortDirection); - case 5: - return addOrderCriteria("CUSTOM_5", sortDirection); - case 6: - return addOrderCriteria("CUSTOM_6", sortDirection); - case 7: - return addOrderCriteria("CUSTOM_7", sortDirection); - case 8: - return addOrderCriteria("CUSTOM_8", sortDirection); - default: - throw new InvalidArgumentException( - "Argument '" - + number - + "' to getCustomAttribute does not represent a number between 1 and 16"); - } + public ClassificationQuery orderByCustomAttribute( + ClassificationCustomField customField, SortDirection sortDirection) { + return addOrderCriteria(customField.name(), sortDirection); } @Override @@ -410,15 +353,13 @@ public class ClassificationQueryImpl implements ClassificationQuery { RowBounds rowBounds = new RowBounds(offset, limit); result = taskanaEngine.getSqlSession().selectList(LINK_TO_SUMMARYMAPPER, this, rowBounds); return result; - } catch (Exception e) { - if (e instanceof PersistenceException) { - if (e.getMessage().contains("ERRORCODE=-4470")) { - TaskanaRuntimeException ex = - new TaskanaRuntimeException( - "The offset beginning was set over the amount of result-rows.", e.getCause()); - ex.setStackTrace(e.getStackTrace()); - throw ex; - } + } catch (PersistenceException e) { + if (e.getMessage().contains("ERRORCODE=-4470")) { + TaskanaRuntimeException ex = + new TaskanaRuntimeException( + "The offset beginning was set over the amount of result-rows.", e.getCause()); + ex.setStackTrace(e.getStackTrace()); + throw ex; } throw e; } finally { diff --git a/lib/taskana-core/src/main/java/pro/taskana/classification/internal/models/ClassificationImpl.java b/lib/taskana-core/src/main/java/pro/taskana/classification/internal/models/ClassificationImpl.java index ab50e4a58..b55712dfd 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/classification/internal/models/ClassificationImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/classification/internal/models/ClassificationImpl.java @@ -3,8 +3,10 @@ package pro.taskana.classification.internal.models; import java.time.Instant; import java.util.Objects; +import pro.taskana.classification.api.ClassificationCustomField; import pro.taskana.classification.api.models.Classification; import pro.taskana.classification.api.models.ClassificationSummary; +import pro.taskana.common.api.exceptions.SystemException; /** Classification entity. */ public class ClassificationImpl extends ClassificationSummaryImpl implements Classification { @@ -78,6 +80,38 @@ public class ClassificationImpl extends ClassificationSummaryImpl implements Cla this.description = description; } + @Override + public void setCustomAttribute(ClassificationCustomField customField, String value) { + switch (customField) { + case CUSTOM_1: + custom1 = value; + break; + case CUSTOM_2: + custom2 = value; + break; + case CUSTOM_3: + custom3 = value; + break; + case CUSTOM_4: + custom4 = value; + break; + case CUSTOM_5: + custom5 = value; + break; + case CUSTOM_6: + custom6 = value; + break; + case CUSTOM_7: + custom7 = value; + break; + case CUSTOM_8: + custom8 = value; + break; + default: + throw new SystemException("Unknown customField '" + customField + "'"); + } + } + @Override public ClassificationSummary asSummary() { ClassificationSummaryImpl summary = new ClassificationSummaryImpl(); diff --git a/lib/taskana-core/src/main/java/pro/taskana/classification/internal/models/ClassificationSummaryImpl.java b/lib/taskana-core/src/main/java/pro/taskana/classification/internal/models/ClassificationSummaryImpl.java index ed035d12e..17c20210b 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/classification/internal/models/ClassificationSummaryImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/classification/internal/models/ClassificationSummaryImpl.java @@ -2,7 +2,9 @@ package pro.taskana.classification.internal.models; import java.util.Objects; +import pro.taskana.classification.api.ClassificationCustomField; import pro.taskana.classification.api.models.ClassificationSummary; +import pro.taskana.common.api.exceptions.SystemException; /** Implementation for the short summaries of a classification entity. */ public class ClassificationSummaryImpl implements ClassificationSummary { @@ -149,6 +151,29 @@ public class ClassificationSummaryImpl implements ClassificationSummary { } @Override + public String getCustomAttribute(ClassificationCustomField customField) { + switch (customField) { + case CUSTOM_1: + return custom1; + case CUSTOM_2: + return custom2; + case CUSTOM_3: + return custom3; + case CUSTOM_4: + return custom4; + case CUSTOM_5: + return custom5; + case CUSTOM_6: + return custom6; + case CUSTOM_7: + return custom7; + case CUSTOM_8: + return custom8; + default: + throw new SystemException("Unknown customField '" + customField + "'"); + } + } + public String getCustom1() { return custom1; } @@ -157,7 +182,6 @@ public class ClassificationSummaryImpl implements ClassificationSummary { this.custom1 = custom1; } - @Override public String getCustom2() { return custom2; } @@ -166,7 +190,6 @@ public class ClassificationSummaryImpl implements ClassificationSummary { this.custom2 = custom2; } - @Override public String getCustom3() { return custom3; } @@ -175,7 +198,6 @@ public class ClassificationSummaryImpl implements ClassificationSummary { this.custom3 = custom3; } - @Override public String getCustom4() { return custom4; } @@ -184,7 +206,6 @@ public class ClassificationSummaryImpl implements ClassificationSummary { this.custom4 = custom4; } - @Override public String getCustom5() { return custom5; } @@ -193,7 +214,6 @@ public class ClassificationSummaryImpl implements ClassificationSummary { this.custom5 = custom5; } - @Override public String getCustom6() { return custom6; } @@ -202,7 +222,6 @@ public class ClassificationSummaryImpl implements ClassificationSummary { this.custom6 = custom6; } - @Override public String getCustom7() { return custom7; } @@ -211,7 +230,6 @@ public class ClassificationSummaryImpl implements ClassificationSummary { this.custom7 = custom7; } - @Override public String getCustom8() { return custom8; } diff --git a/lib/taskana-core/src/main/java/pro/taskana/monitor/api/MonitorService.java b/lib/taskana-core/src/main/java/pro/taskana/monitor/api/MonitorService.java index 4a636e53c..0ea735aef 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/monitor/api/MonitorService.java +++ b/lib/taskana-core/src/main/java/pro/taskana/monitor/api/MonitorService.java @@ -2,11 +2,11 @@ package pro.taskana.monitor.api; import pro.taskana.monitor.api.reports.ClassificationCategoryReport; import pro.taskana.monitor.api.reports.ClassificationReport; -import pro.taskana.monitor.api.reports.CustomFieldValueReport; +import pro.taskana.monitor.api.reports.TaskCustomFieldValueReport; import pro.taskana.monitor.api.reports.TaskStatusReport; import pro.taskana.monitor.api.reports.TimestampReport; import pro.taskana.monitor.api.reports.WorkbasketReport; -import pro.taskana.task.api.CustomField; +import pro.taskana.task.api.TaskCustomField; /** The Monitor Service manages operations on tasks regarding the monitoring. */ public interface MonitorService { @@ -38,13 +38,14 @@ public interface MonitorService { ClassificationReport.Builder createClassificationReportBuilder(); /** - * Provides a {@link CustomFieldValueReport.Builder} for creating a {@link CustomFieldValueReport} - * and list the values of an entered custom attribute. + * Provides a {@link TaskCustomFieldValueReport.Builder} for creating a {@link + * TaskCustomFieldValueReport} and list the values of an entered custom attribute. * - * @param customField the customField whose values should appear in the report - * @return a {@link CustomFieldValueReport.Builder} + * @param taskCustomField the customField whose values should appear in the report + * @return a {@link TaskCustomFieldValueReport.Builder} */ - CustomFieldValueReport.Builder createCustomFieldValueReportBuilder(CustomField customField); + TaskCustomFieldValueReport.Builder createCustomFieldValueReportBuilder( + TaskCustomField taskCustomField); /** * Provides a {@link TaskStatusReport.Builder} for creating a {@link TaskStatusReport}. diff --git a/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/CustomFieldValueReport.java b/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/TaskCustomFieldValueReport.java similarity index 70% rename from lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/CustomFieldValueReport.java rename to lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/TaskCustomFieldValueReport.java index 889cb247b..479ffe850 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/CustomFieldValueReport.java +++ b/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/TaskCustomFieldValueReport.java @@ -16,21 +16,22 @@ import pro.taskana.monitor.api.reports.item.MonitorQueryItem; * contains also the number of tasks of the respective cluster. The age of the tasks can be counted * in days or in working days. Tasks with Timestamp DUE = null are not considered. */ -public class CustomFieldValueReport extends Report { +public class TaskCustomFieldValueReport extends Report { - public CustomFieldValueReport(List timeIntervalColumnHeaders) { - super(timeIntervalColumnHeaders, new String[] {"CUSTOM FIELDS"}); + public TaskCustomFieldValueReport(List timeIntervalColumnHeaders) { + super(timeIntervalColumnHeaders, new String[] {"TASK CUSTOM FIELDS"}); } - /** Builder for {@link CustomFieldValueReport}. */ + /** Builder for {@link TaskCustomFieldValueReport}. */ public interface Builder extends TimeIntervalReportBuilder { @Override - CustomFieldValueReport buildReport() throws NotAuthorizedException, InvalidArgumentException; + TaskCustomFieldValueReport buildReport() + throws NotAuthorizedException, InvalidArgumentException; @Override - CustomFieldValueReport buildReport(TaskTimestamp timestamp) + TaskCustomFieldValueReport buildReport(TaskTimestamp timestamp) throws NotAuthorizedException, InvalidArgumentException; } } diff --git a/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/TimeIntervalReportBuilder.java b/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/TimeIntervalReportBuilder.java index 8a6ab74d8..2bc81dba0 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/TimeIntervalReportBuilder.java +++ b/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/TimeIntervalReportBuilder.java @@ -9,7 +9,7 @@ import pro.taskana.monitor.api.SelectedItem; import pro.taskana.monitor.api.TaskTimestamp; import pro.taskana.monitor.api.reports.header.TimeIntervalColumnHeader; import pro.taskana.monitor.api.reports.item.AgeQueryItem; -import pro.taskana.task.api.CustomField; +import pro.taskana.task.api.TaskCustomField; import pro.taskana.task.api.TaskState; /** @@ -102,7 +102,7 @@ public interface TimeIntervalReportBuilder< * @param customAttributeFilter a map of custom attributes and custom attribute value * @return the TimeIntervalReportBuilder */ - B customAttributeFilterIn(Map customAttributeFilter); + B customAttributeFilterIn(Map customAttributeFilter); /** * Returns a list of all taskIds of the report that are in the list of selected items. @@ -118,11 +118,11 @@ public interface TimeIntervalReportBuilder< /** * Returns a list of all values of an entered custom field that are in the report. * - * @param customField the customField whose values should appear in the list + * @param taskCustomField the customField whose values should appear in the list * @return the list of all custom attribute values * @throws NotAuthorizedException if the user has no rights to access the monitor */ - List listCustomAttributeValuesForCustomAttributeName(CustomField customField) + List listCustomAttributeValuesForCustomAttributeName(TaskCustomField taskCustomField) throws NotAuthorizedException; Report buildReport(TaskTimestamp timestamp) diff --git a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/MonitorMapper.java b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/MonitorMapper.java index 0d603882f..78429911c 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/MonitorMapper.java +++ b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/MonitorMapper.java @@ -14,7 +14,7 @@ import pro.taskana.monitor.api.reports.item.DetailedMonitorQueryItem; import pro.taskana.monitor.api.reports.item.MonitorQueryItem; import pro.taskana.monitor.api.reports.item.TaskQueryItem; import pro.taskana.monitor.api.reports.item.TimestampQueryItem; -import pro.taskana.task.api.CustomField; +import pro.taskana.task.api.TaskCustomField; import pro.taskana.task.api.TaskState; /** This class is the mybatis mapping of task monitoring. */ @@ -74,7 +74,7 @@ public interface MonitorMapper { @Param("timestamp") TaskTimestamp timestamp, @Param("classificationIds") List classificationIds, @Param("excludedClassificationIds") List excludedClassificationIds, - @Param("customAttributeFilter") Map customAttributeFilter, + @Param("customAttributeFilter") Map customAttributeFilter, @Param("combinedClassificationFilter") List combinedClassificationFilter); @@ -125,7 +125,7 @@ public interface MonitorMapper { @Param("timestamp") TaskTimestamp timestamp, @Param("classificationIds") List classificationIds, @Param("excludedClassificationIds") List excludedClassificationIds, - @Param("customAttributeFilter") Map customAttributeFilter); + @Param("customAttributeFilter") Map customAttributeFilter); @Select( "