pro.taskana.monitor.rest.assembler.ReportRepresentationModelAssembler Maven / Gradle / Ivy
package pro.taskana.monitor.rest.assembler;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
import java.time.Instant;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.monitor.api.reports.ClassificationReport;
import pro.taskana.monitor.api.reports.Report;
import pro.taskana.monitor.api.reports.TaskStatusReport;
import pro.taskana.monitor.api.reports.TimestampReport;
import pro.taskana.monitor.api.reports.WorkbasketReport;
import pro.taskana.monitor.api.reports.header.ColumnHeader;
import pro.taskana.monitor.api.reports.item.QueryItem;
import pro.taskana.monitor.api.reports.row.FoldableRow;
import pro.taskana.monitor.api.reports.row.Row;
import pro.taskana.monitor.api.reports.row.SingleRow;
import pro.taskana.monitor.rest.MonitorController;
import pro.taskana.monitor.rest.models.ReportRepresentationModel;
import pro.taskana.task.api.TaskState;
/** Transforms any {@link Report} into its {@link ReportRepresentationModel}. */
@Component
public class ReportRepresentationModelAssembler {
@NonNull
public ReportRepresentationModel toModel(
@NonNull TaskStatusReport report,
@NonNull List domains,
@NonNull List states)
throws NotAuthorizedException, InvalidArgumentException {
ReportRepresentationModel resource = toReportResource(report);
resource.add(
linkTo(methodOn(MonitorController.class).getTasksStatusReport(domains, states))
.withSelfRel()
.expand());
return resource;
}
@NonNull
public ReportRepresentationModel toModel(@NonNull ClassificationReport report)
throws NotAuthorizedException, InvalidArgumentException {
ReportRepresentationModel resource = toReportResource(report);
resource.add(
linkTo(methodOn(MonitorController.class).getTasksClassificationReport())
.withSelfRel()
.expand());
return resource;
}
@NonNull
public ReportRepresentationModel toModel(
@NonNull WorkbasketReport report, @NonNull List states)
throws NotAuthorizedException, InvalidArgumentException {
ReportRepresentationModel resource = toReportResource(report);
resource.add(
linkTo(methodOn(MonitorController.class).getTasksWorkbasketReport(states))
.withSelfRel()
.expand());
return resource;
}
@NonNull
public ReportRepresentationModel toModel(
@NonNull WorkbasketReport report, int daysInPast, @NonNull List states)
throws NotAuthorizedException, InvalidArgumentException {
ReportRepresentationModel resource = toReportResource(report);
resource.add(
linkTo(
methodOn(MonitorController.class)
.getTasksWorkbasketPlannedDateReport(daysInPast, states))
.withSelfRel()
.expand());
return resource;
}
@NonNull
public ReportRepresentationModel toModel(@NonNull TimestampReport report)
throws NotAuthorizedException, InvalidArgumentException {
ReportRepresentationModel resource = toReportResource(report);
resource.add(
linkTo(methodOn(MonitorController.class).getDailyEntryExitReport()).withSelfRel().expand());
return resource;
}
public >
ReportRepresentationModel toReportResource(Report report, Instant time) {
String[] header =
report.getColumnHeaders().stream().map(H::getDisplayName).toArray(String[]::new);
ReportRepresentationModel.MetaInformation meta =
new ReportRepresentationModel.MetaInformation(
report.getClass().getSimpleName(), time.toString(), header, report.getRowDesc());
// iterate over each Row and transform it to a RowResource while keeping the domain key.
List rows =
report.getRows().entrySet().stream()
.sorted(Comparator.comparing(e -> e.getKey().toLowerCase()))
.map(
i ->
transformRow(
i.getValue(), i.getKey(), new String[report.getRowDesc().length], 0))
.flatMap(Collection::stream)
.collect(Collectors.toList());
List sumRow =
transformRow(
report.getSumRow(), meta.getTotalDesc(), new String[report.getRowDesc().length], 0);
return new ReportRepresentationModel(meta, rows, sumRow);
}
>
ReportRepresentationModel toReportResource(Report report) {
return toReportResource(report, Instant.now());
}
private List transformRow(
Row row, String currentDesc, String[] desc, int depth) {
// This is a very dirty solution.. Personally I'd prefer to use a visitor-like pattern here.
// The issue with that: Addition of the visitor code within taskana-core - and having clean code
// is not
// a reason to append code somewhere where it doesn't belong.
if (row.getClass() == SingleRow.class) {
return Collections.singletonList(
transformSingleRow((SingleRow) row, currentDesc, desc, depth));
}
return transformFoldableRow((FoldableRow) row, currentDesc, desc, depth);
}
private ReportRepresentationModel.RowResource transformSingleRow(
SingleRow row, String currentDesc, String[] previousRowDesc, int depth) {
String[] rowDesc = new String[previousRowDesc.length];
System.arraycopy(previousRowDesc, 0, rowDesc, 0, depth);
rowDesc[depth] = currentDesc;
return new ReportRepresentationModel.RowResource(
row.getCells(), row.getTotalValue(), depth, rowDesc, depth == 0);
}
private List transformFoldableRow(
FoldableRow row, String currentDesc, String[] previousRowDesc, int depth) {
ReportRepresentationModel.RowResource baseRow =
transformSingleRow(row, currentDesc, previousRowDesc, depth);
List rowList = new LinkedList<>();
rowList.add(baseRow);
row.getFoldableRowKeySet().stream()
.sorted(String.CASE_INSENSITIVE_ORDER)
.map(s -> transformRow(row.getFoldableRow(s), s, baseRow.getDesc(), depth + 1))
.flatMap(Collection::stream)
.forEachOrdered(rowList::add);
return rowList;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy