TSK-697: refactored Report structure

This commit is contained in:
Mustapha Zorgati 2018-09-05 13:17:37 +02:00 committed by Martin Rojas Miguel Angel
parent 4c192d79a4
commit db70a89435
62 changed files with 590 additions and 1196 deletions

View File

@ -1,161 +0,0 @@
package pro.taskana;
import java.util.List;
import java.util.Map;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.SelectedItem;
import pro.taskana.impl.report.impl.ClassificationReport;
import pro.taskana.impl.report.impl.DetailedClassificationReport;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader;
/**
* The ClassificationReportBuilder is used to build a {@link ClassificationReport} or a
* {@link DetailedClassificationReport}. Furthermore the taskIds and values of an entered custom field of these reports
* can be listed. A ClassificationReport contains the total numbers of tasks of the respective classification as well as
* the total number of all tasks. A ReportLine of a DetailedClassificationReport contains an additional list of
* ReportLines for the classifications of the attachments of the tasks. The tasks of the report can be filtered by
* workbaskets, states, categories, domains, classifications and values of a custom field. Classifications can also be
* excluded from the report. If the {@link TimeIntervalColumnHeader}s are set, the report 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 interface ClassificationReportBuilder {
/**
* Adds a list {@link TimeIntervalColumnHeader}s to the builder to subdivide the report into clusters.
*
* @param columnHeaders
* the column headers the report should consist of.
* @return the ClassificationReportBuilder
*/
ClassificationReportBuilder withColumnHeaders(List<TimeIntervalColumnHeader> columnHeaders);
/**
* If this filter is used, the days of the report are counted in working days.
*
* @return the ClassificationReportBuilder
*/
ClassificationReportBuilder inWorkingDays();
/**
* Adds a list of workbasket ids to the builder. The created report contains only tasks with a workbasket id in this
* list.
*
* @param workbasketIds
* a list of workbasket ids
* @return the ClassificationReportBuilder
*/
ClassificationReportBuilder workbasketIdIn(List<String> workbasketIds);
/**
* Adds a list of states to the builder. The created report contains only tasks with a state in this list.
*
* @param states
* a list of states
* @return the ClassificationReportBuilder
*/
ClassificationReportBuilder stateIn(List<TaskState> states);
/**
* Adds a list of categories to the builder. The created report contains only tasks with a category in this list.
*
* @param categories
* a list of categories
* @return the ClassificationReportBuilder
*/
ClassificationReportBuilder categoryIn(List<String> categories);
/**
* Adds a list of classificationIds to the builder. The created report contains only tasks with a classificationId
* in this list.
*
* @param classificationIds
* a list of classificationIds
* @return the ClassificationReportBuilder
*/
ClassificationReportBuilder classificationIdIn(List<String> classificationIds);
/**
* Adds a list of excludedClassificationIds to the builder. The created report contains only tasks with a
* classificationId NOT in this list.
*
* @param excludedClassificationIds
* a list of excludedClassificationIds
* @return the ClassificationReportBuilder
*/
ClassificationReportBuilder excludedClassificationIdIn(List<String> excludedClassificationIds);
/**
* Adds a list of domains to the builder. The created report contains only tasks with a domain in this list.
*
* @param domains
* a list of domains
* @return the ClassificationReportBuilder
*/
ClassificationReportBuilder domainIn(List<String> domains);
/**
* Adds a map of custom attributes and custom attribute values to the builder. The created report contains only
* tasks with a custom attribute value in this list.
*
* @param customAttributeFilter
* a map of custom attributes and custom attribute value
* @return the ClassificationReportBuilder
*/
ClassificationReportBuilder customAttributeFilterIn(Map<CustomField, String> customAttributeFilter);
/**
* Returns a {@link ClassificationReport} containing all tasks after applying the filters. If the column headers are
* set the report is subdivided into clusters.
*
* @throws InvalidArgumentException
* if the column headers are not initialized
* @throws NotAuthorizedException
* if the user has no rights to access the monitor
* @return the ClassificationReport
*/
ClassificationReport buildReport() throws InvalidArgumentException, NotAuthorizedException;
/**
* Returns a {@link DetailedClassificationReport} containing all tasks after applying the filters. If the column
* headers are set the report is subdivided into clusters. Its
* {@link pro.taskana.impl.report.impl.DetailedReportRow}s contain an additional list of
* {@link pro.taskana.impl.report.ReportRow}s for the classifications of the attachments of the tasks.
*
* @throws InvalidArgumentException
* if the column headers are not initialized
* @throws NotAuthorizedException
* if the user has no rights to access the monitor
* @return the DetailedClassificationReport
*/
DetailedClassificationReport buildDetailedReport() throws InvalidArgumentException, NotAuthorizedException;
/**
* Returns a list of all taskIds of the report that are in the list of selected items.
*
* @param selectedItems
* a list of selectedItems
* @throws InvalidArgumentException
* if the column headers are not initialized
* @throws NotAuthorizedException
* if the user has no rights to access the monitor
* @return the list of all taskIds
*/
List<String> listTaskIdsForSelectedItems(List<SelectedItem> selectedItems)
throws NotAuthorizedException, InvalidArgumentException;
/**
* 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
* @throws NotAuthorizedException
* if the user has no rights to access the monitor
* @return the list of all custom attribute values
*/
List<String> listCustomAttributeValuesForCustomAttributeName(CustomField customField)
throws NotAuthorizedException;
}

View File

@ -1,149 +0,0 @@
package pro.taskana;
import java.util.List;
import java.util.Map;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.SelectedItem;
import pro.taskana.impl.report.impl.CustomFieldValueReport;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader;
/**
* The CustomFieldValueReportBuilder is used to build a {@link CustomFieldValueReport} and list the values of a entered
* custom field. A CustomFieldValueReport contains the total numbers of tasks of the respective custom field as well as
* the total number of all tasks. The tasks of the report can be filtered by workbaskets, states, categories, domains,
* classifications and values of a custom field. Classifications can also be excluded from the report. If the
* {@link TimeIntervalColumnHeader}s are set, the report 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 interface CustomFieldValueReportBuilder {
/**
* Adds a list {@link TimeIntervalColumnHeader}s to the builder to subdivide the report into clusters.
*
* @param columnHeaders
* the column headers the report should consist of.
* @return the CustomFieldValueReportBuilder
*/
CustomFieldValueReportBuilder withColumnHeaders(List<TimeIntervalColumnHeader> columnHeaders);
/**
* If this filter is used, the days of the report are counted in working days.
*
* @return the CustomFieldValueReportBuilder
*/
CustomFieldValueReportBuilder inWorkingDays();
/**
* Adds a list of workbasket ids to the builder. The created report contains only tasks with a workbasket id in this
* list.
*
* @param workbasketIds
* a list of workbasket ids
* @return the CustomFieldValueReportBuilder
*/
CustomFieldValueReportBuilder workbasketIdIn(List<String> workbasketIds);
/**
* Adds a list of states to the builder. The created report contains only tasks with a state in this list.
*
* @param states
* a list of states
* @return the CustomFieldValueReportBuilder
*/
CustomFieldValueReportBuilder stateIn(List<TaskState> states);
/**
* Adds a list of categories to the builder. The created report contains only tasks with a category in this list.
*
* @param categories
* a list of categories
* @return the CustomFieldValueReportBuilder
*/
CustomFieldValueReportBuilder categoryIn(List<String> categories);
/**
* Adds a list of classificationIds to the builder. The created report contains only tasks with a classificationId
* in this list.
*
* @param classificationIds
* a list of classificationIds
* @return the CustomFieldValueReportBuilder
*/
CustomFieldValueReportBuilder classificationIdIn(List<String> classificationIds);
/**
* Adds a list of excludedClassificationIds to the builder. The created report contains only tasks with a
* classificationId NOT in this list.
*
* @param excludedClassificationIds
* a list of excludedClassificationIds
* @return the CustomFieldValueReportBuilder
*/
CustomFieldValueReportBuilder excludedClassificationIdIn(List<String> excludedClassificationIds);
/**
* Adds a list of domains to the builder. The created report contains only tasks with a domain in this list.
*
* @param domains
* a list of domains
* @return the CustomFieldValueReportBuilder
*/
CustomFieldValueReportBuilder domainIn(List<String> domains);
/**
* Adds a map of custom attributes and custom attribute values to the builder. The created report contains only
* tasks with a custom attribute value in this list.
*
* @param customAttributeFilter
* a map of custom attributes and custom attribute value
* @return the CustomFieldValueReportBuilder
*/
CustomFieldValueReportBuilder customAttributeFilterIn(Map<CustomField, String> customAttributeFilter);
/**
* Returns a {@link CustomFieldValueReportBuilder} containing all tasks after applying the filters. If the column
* headers are set the report is subdivided into clusters.
*
* @throws InvalidArgumentException
* if the column headers are not initialized
* @throws NotAuthorizedException
* if the user has no rights to access the monitor
* @return the CustomFieldValueReportBuilder
*/
CustomFieldValueReport buildReport() throws InvalidArgumentException, NotAuthorizedException;
/**
* Returns a list of all taskIds of the report that are in the list of selected items.
*
* @param selectedItems
* a list of selectedItems
* @throws InvalidArgumentException
* if the column headers are not initialized
* @throws NotAuthorizedException
* if the user has no rights to access the monitor
* @return the list of all taskIds
*/
List<String> listTaskIdsForSelectedItems(List<SelectedItem> selectedItems)
throws NotAuthorizedException, InvalidArgumentException;
/**
* 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
* @throws NotAuthorizedException
* if the user has no rights to access the monitor
* @return the list of all custom attribute values
*/
List<String> listCustomAttributeValuesForCustomAttributeName(CustomField customField)
throws NotAuthorizedException;
/**
* Gets the customField property of the CustomFieldValueReportBuilder.
*
* @return the customField property
*/
CustomField getCustomField();
}

View File

@ -1,8 +1,10 @@
package pro.taskana; package pro.taskana;
import pro.taskana.impl.CustomFieldValueReportBuilderImpl; import pro.taskana.report.CategoryReport;
import pro.taskana.impl.TaskStatusReportBuilderImpl; import pro.taskana.report.ClassificationReport;
import pro.taskana.impl.WorkbasketReportBuilderImpl; import pro.taskana.report.CustomFieldValueReport;
import pro.taskana.report.TaskStatusReport;
import pro.taskana.report.WorkbasketReport;
/** /**
* The Task Monitor Service manages operations on tasks regarding the monitoring. * The Task Monitor Service manages operations on tasks regarding the monitoring.
@ -10,44 +12,44 @@ import pro.taskana.impl.WorkbasketReportBuilderImpl;
public interface TaskMonitorService { public interface TaskMonitorService {
/** /**
* Provides a {@link WorkbasketReportBuilderImpl} for creating a WorkbasketReport, list the task ids of this report * Provides a {@link WorkbasketReport.Builder} for creating a {@link WorkbasketReport}, list the task ids of this report
* and list the values of an entered custom attribute. * and list the values of an entered custom attribute.
* *
* @return a {@link WorkbasketReportBuilderImpl} * @return a {@link WorkbasketReport.Builder}
*/ */
WorkbasketReportBuilderImpl createWorkbasketReportBuilder(); WorkbasketReport.Builder createWorkbasketReportBuilder();
/** /**
* Provides a {@link CategoryReportBuilder} for creating a CategoryReport, list the task ids of this report and list * Provides a {@link CategoryReport.Builder} for creating a {@link CategoryReport}, list the task ids of this report and list
* the values of an entered custom attribute. * the values of an entered custom attribute.
* *
* @return a {@link CategoryReportBuilder} * @return a {@link CategoryReport.Builder}
*/ */
CategoryReportBuilder createCategoryReportBuilder(); CategoryReport.Builder createCategoryReportBuilder();
/** /**
* Provides a {@link ClassificationReportBuilder} for creating a ClassificationReport or a * Provides a {@link ClassificationReport.Builder} for creating a {@link ClassificationReport} or a
* DetailedClassificationReport, list the task ids of these reports and list the values of an entered custom * DetailedClassificationReport, list the task ids of these reports and list the values of an entered custom
* attribute. * attribute.
* *
* @return a {@link ClassificationReportBuilder} * @return a {@link ClassificationReport.Builder}
*/ */
ClassificationReportBuilder createClassificationReportBuilder(); ClassificationReport.Builder createClassificationReportBuilder();
/** /**
* Provides a {@link CustomFieldValueReportBuilderImpl} for creating a CustomFieldValueReport and list the values of * Provides a {@link CustomFieldValueReport.Builder} for creating a {@link CustomFieldValueReport} and list the values of
* an entered custom attribute. * an entered custom attribute.
* *
* @param customField * @param customField
* the customField whose values should appear in the report * the customField whose values should appear in the report
* @return a {@link CustomFieldValueReportBuilderImpl} * @return a {@link CustomFieldValueReport.Builder}
*/ */
CustomFieldValueReportBuilderImpl createCustomFieldValueReportBuilder(CustomField customField); CustomFieldValueReport.Builder createCustomFieldValueReportBuilder(CustomField customField);
/** /**
* Provides a {@link TaskStatusReportBuilderImpl} for creating a TaskStatusReport. * Provides a {@link TaskStatusReport.Builder} for creating a {@link TaskStatusReport}.
* *
* @return a {@link TaskStatusReportBuilderImpl} * @return a {@link TaskStatusReport.Builder}
*/ */
TaskStatusReportBuilderImpl createTaskStatusReportBuilder(); TaskStatusReport.Builder createTaskStatusReportBuilder();
} }

View File

@ -1,41 +0,0 @@
package pro.taskana;
import java.util.List;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.impl.TaskStatusReport;
/**
* The TaskStatusReportBuilder is used to build a {@link TaskStatusReport}. A TaskStatusReport contains the total number
* of tasks, clustered in their task status. Furthermore the report contains a sum line that contains the total numbers
* of the different clusters and the total number of all tasks.
*/
public interface TaskStatusReportBuilder {
/**
* Adds a list of states to the builder. The created report contains only tasks with a state in this list.
*
* @param states
* a list of states
* @return the TaskStatusReportBuilder
*/
TaskStatusReportBuilder stateIn(List<TaskState> states);
/**
* Adds a list of domains to the builder. The created report contains only tasks with a domain in this list.
*
* @param domains
* a list of domains
* @return the TaskStatusReportBuilder
*/
TaskStatusReportBuilder domainIn(List<String> domains);
/**
* Returns a {@link TaskStatusReport} containing all tasks after applying the filters.
*
* @throws NotAuthorizedException
* if the user has no rights to access the monitor
* @return the TaskStatusReport
*/
TaskStatusReport buildReport() throws NotAuthorizedException;
}

View File

@ -1,157 +0,0 @@
package pro.taskana;
import java.util.List;
import java.util.Map;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.SelectedItem;
import pro.taskana.impl.WorkbasketReportBuilderImpl;
import pro.taskana.impl.report.impl.CombinedClassificationFilter;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader;
import pro.taskana.impl.report.impl.WorkbasketReport;
/**
* The WorkbasketReportBuilder is used to build a {@link WorkbasketReport}, list the taskIds of a WorkbasketReport and
* list the values of a entered custom field. A WorkbasketReport contains the total numbers of tasks of the respective
* workbasket as well as the total number of all tasks. The tasks of the report can be filtered by workbaskets, states,
* categories, domains, classifications and values of a custom field. Classifications can also be excluded from the
* report. It is also possible to filter by the classifications of the attachments by using the
* {@link CombinedClassificationFilter}. If the {@link TimeIntervalColumnHeader}s are set, the report 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 interface WorkbasketReportBuilder {
/**
* Adds a list {@link TimeIntervalColumnHeader}s to the builder to subdivide the report into clusters.
*
* @param columnHeaders
* the column headers the report should consist of.
* @return the WorkbasketReportBuilder
*/
WorkbasketReportBuilder withColumnHeaders(List<TimeIntervalColumnHeader> columnHeaders);
/**
* If this filter is used, the days of the report are counted in working days.
*
* @return the WorkbasketReportBuilder
*/
WorkbasketReportBuilder inWorkingDays();
/**
* Adds a list of workbasket ids to the builder. The created report contains only tasks with a workbasket id in this
* list.
*
* @param workbasketIds
* a list of workbasket ids
* @return the WorkbasketReportBuilder
*/
WorkbasketReportBuilder workbasketIdIn(List<String> workbasketIds);
/**
* Adds a list of states to the builder. The created report contains only tasks with a state in this list.
*
* @param states
* a list of states
* @return the WorkbasketReportBuilder
*/
WorkbasketReportBuilder stateIn(List<TaskState> states);
/**
* Adds a list of categories to the builder. The created report contains only tasks with a category in this list.
*
* @param categories
* a list of categories
* @return the WorkbasketReportBuilder
*/
WorkbasketReportBuilder categoryIn(List<String> categories);
/**
* Adds a list of classificationIds to the builder. The created report contains only tasks with a classificationId
* in this list.
*
* @param classificationIds
* a list of classificationIds
* @return the WorkbasketReportBuilder
*/
WorkbasketReportBuilder classificationIdIn(List<String> classificationIds);
/**
* Adds a list of excludedClassificationIds to the builder. The created report contains only tasks with a
* classificationId NOT in this list.
*
* @param excludedClassificationIds
* a list of excludedClassificationIds
* @return the WorkbasketReportBuilder
*/
WorkbasketReportBuilder excludedClassificationIdIn(List<String> excludedClassificationIds);
/**
* Adds a list of domains to the builder. The created report contains only tasks with a domain in this list.
*
* @param domains
* a list of domains
* @return the WorkbasketReportBuilder
*/
WorkbasketReportBuilder domainIn(List<String> domains);
/**
* Adds a map of custom attributes and custom attribute values to the builder. The created report contains only
* tasks with a custom attribute value in this list.
*
* @param customAttributeFilter
* a map of custom attributes and custom attribute value
* @return the WorkbasketReportBuilder
*/
WorkbasketReportBuilder customAttributeFilterIn(Map<CustomField, String> customAttributeFilter);
/**
* Adds a list of {@link CombinedClassificationFilter} to the builder. The created report contains only tasks with a
* pair of a classificationId for a task and a classificationId for the corresponding attachment in this list.
*
* @param combinedClassificationFilter
* a list of combinedClassificationFilter
* @return the WorkbasketReportBuilder
*/
WorkbasketReportBuilderImpl combinedClassificationFilterIn(
List<CombinedClassificationFilter> combinedClassificationFilter);
/**
* Returns a {@link WorkbasketReport} containing all tasks after applying the filters. If the column headers are set
* the report is subdivided into clusters.
*
* @throws InvalidArgumentException
* if the column headers are not initialized
* @throws NotAuthorizedException
* if the user has no rights to access the monitor
* @return the WorkbasketReport
*/
WorkbasketReport buildReport() throws InvalidArgumentException, NotAuthorizedException;
/**
* Returns a list of all taskIds of the report that are in the list of selected items.
*
* @param selectedItems
* a list of selectedItems
* @throws InvalidArgumentException
* if the column headers are not initialized
* @throws NotAuthorizedException
* if the user has no rights to access the monitor
* @return the list of all taskIds
*/
List<String> listTaskIdsForSelectedItems(List<SelectedItem> selectedItems)
throws NotAuthorizedException, InvalidArgumentException;
/**
* 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
* @throws NotAuthorizedException
* if the user has no rights to access the monitor
* @return the list of all custom attribute values
*/
List<String> listCustomAttributeValuesForCustomAttributeName(CustomField customField)
throws NotAuthorizedException;
}

View File

@ -1,87 +1,41 @@
package pro.taskana.impl; package pro.taskana.impl;
import java.util.List; import java.util.List;
import java.util.Map;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pro.taskana.CategoryReportBuilder;
import pro.taskana.CustomField;
import pro.taskana.TaskState;
import pro.taskana.TaskanaEngine; import pro.taskana.TaskanaEngine;
import pro.taskana.TaskanaRole; import pro.taskana.TaskanaRole;
import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.impl.CategoryReport; import pro.taskana.impl.report.DaysToWorkingDaysPreProcessor;
import pro.taskana.impl.report.impl.DaysToWorkingDaysPreProcessor; import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.impl.MonitorQueryItem; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader;
import pro.taskana.mappings.TaskMonitorMapper; import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.CategoryReport;
/** /**
* The implementation of CategoryReportBuilder. * The implementation of CategoryReportBuilder.
*/ */
public class CategoryReportBuilderImpl extends ReportBuilder implements CategoryReportBuilder { public class CategoryReportBuilderImpl
extends TimeIntervalReportBuilderImpl<CategoryReport.Builder, TimeIntervalColumnHeader>
implements CategoryReport.Builder {
private static final Logger LOGGER = LoggerFactory.getLogger(CategoryReportBuilder.class); private static final Logger LOGGER = LoggerFactory.getLogger(CategoryReport.Builder.class);
public CategoryReportBuilderImpl(TaskanaEngine taskanaEngine, TaskMonitorMapper taskMonitorMapper) { CategoryReportBuilderImpl(TaskanaEngine taskanaEngine, TaskMonitorMapper taskMonitorMapper) {
super(taskanaEngine, taskMonitorMapper); super(taskanaEngine, taskMonitorMapper);
} }
@Override @Override
public CategoryReportBuilder withColumnHeaders(List<TimeIntervalColumnHeader> columnHeaders) { protected CategoryReport.Builder _this() {
this.columnHeaders = columnHeaders;
return this; return this;
} }
@Override @Override
public CategoryReportBuilder inWorkingDays() { protected String determineDimension() {
this.inWorkingDays = true; return "CLASSIFICATION_CATEGORY";
return this;
}
@Override
public CategoryReportBuilder workbasketIdIn(List<String> workbasketIds) {
this.workbasketIds = workbasketIds;
return this;
}
@Override
public CategoryReportBuilder stateIn(List<TaskState> states) {
this.states = states;
return this;
}
@Override
public CategoryReportBuilder categoryIn(List<String> categories) {
this.categories = categories;
return this;
}
@Override
public CategoryReportBuilder classificationIdIn(List<String> classificationIds) {
this.classificationIds = classificationIds;
return this;
}
@Override
public CategoryReportBuilder excludedClassificationIdIn(List<String> excludedClassificationIds) {
this.excludedClassificationIds = excludedClassificationIds;
return this;
}
@Override
public CategoryReportBuilder domainIn(List<String> domains) {
this.domains = domains;
return this;
}
@Override
public CategoryReportBuilder customAttributeFilterIn(Map<CustomField, String> customAttributeFilter) {
this.customAttributeFilter = customAttributeFilter;
return this;
} }
@Override @Override

View File

@ -1,89 +1,43 @@
package pro.taskana.impl; package pro.taskana.impl;
import java.util.List; import java.util.List;
import java.util.Map;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pro.taskana.ClassificationReportBuilder;
import pro.taskana.CustomField;
import pro.taskana.TaskState;
import pro.taskana.TaskanaEngine; import pro.taskana.TaskanaEngine;
import pro.taskana.TaskanaRole; import pro.taskana.TaskanaRole;
import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.impl.ClassificationReport; import pro.taskana.impl.report.DaysToWorkingDaysPreProcessor;
import pro.taskana.impl.report.impl.DaysToWorkingDaysPreProcessor; import pro.taskana.impl.report.DetailedMonitorQueryItem;
import pro.taskana.impl.report.impl.DetailedClassificationReport; import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.impl.DetailedMonitorQueryItem; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.impl.MonitorQueryItem;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader;
import pro.taskana.mappings.TaskMonitorMapper; import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.ClassificationReport;
import pro.taskana.report.ClassificationReport.DetailedClassificationReport;
/** /**
* The implementation of ClassificationReportBuilder. * The implementation of ClassificationReportBuilder.
*/ */
public class ClassificationReportBuilderImpl extends ReportBuilder implements ClassificationReportBuilder { public class ClassificationReportBuilderImpl
extends TimeIntervalReportBuilderImpl<ClassificationReport.Builder, TimeIntervalColumnHeader>
implements ClassificationReport.Builder {
private static final Logger LOGGER = LoggerFactory.getLogger(ClassificationReportBuilder.class); private static final Logger LOGGER = LoggerFactory.getLogger(ClassificationReport.Builder.class);
public ClassificationReportBuilderImpl(TaskanaEngine taskanaEngine, TaskMonitorMapper taskMonitorMapper) { ClassificationReportBuilderImpl(TaskanaEngine taskanaEngine, TaskMonitorMapper taskMonitorMapper) {
super(taskanaEngine, taskMonitorMapper); super(taskanaEngine, taskMonitorMapper);
} }
@Override @Override
public ClassificationReportBuilder withColumnHeaders(List<TimeIntervalColumnHeader> columnHeaders) { protected ClassificationReport.Builder _this() {
this.columnHeaders = columnHeaders;
return this; return this;
} }
@Override @Override
public ClassificationReportBuilder inWorkingDays() { protected String determineDimension() {
this.inWorkingDays = true; return "CLASSIFICATION_KEY";
return this;
}
@Override
public ClassificationReportBuilder workbasketIdIn(List<String> workbasketIds) {
this.workbasketIds = workbasketIds;
return this;
}
@Override
public ClassificationReportBuilder stateIn(List<TaskState> states) {
this.states = states;
return this;
}
@Override
public ClassificationReportBuilder categoryIn(List<String> categories) {
this.categories = categories;
return this;
}
@Override
public ClassificationReportBuilder domainIn(List<String> domains) {
this.domains = domains;
return this;
}
@Override
public ClassificationReportBuilder customAttributeFilterIn(Map<CustomField, String> customAttributeFilter) {
this.customAttributeFilter = customAttributeFilter;
return this;
}
@Override
public ClassificationReportBuilder classificationIdIn(List<String> classificationIds) {
this.classificationIds = classificationIds;
return this;
}
@Override
public ClassificationReportBuilder excludedClassificationIdIn(List<String> excludedClassificationIds) {
this.excludedClassificationIds = excludedClassificationIds;
return this;
} }
@Override @Override

View File

@ -1,91 +1,46 @@
package pro.taskana.impl; package pro.taskana.impl;
import java.util.List; import java.util.List;
import java.util.Map;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pro.taskana.CustomField; import pro.taskana.CustomField;
import pro.taskana.CustomFieldValueReportBuilder;
import pro.taskana.TaskState;
import pro.taskana.TaskanaEngine; import pro.taskana.TaskanaEngine;
import pro.taskana.TaskanaRole; import pro.taskana.TaskanaRole;
import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.impl.CustomFieldValueReport; import pro.taskana.impl.report.DaysToWorkingDaysPreProcessor;
import pro.taskana.impl.report.impl.DaysToWorkingDaysPreProcessor; import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.impl.MonitorQueryItem; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader;
import pro.taskana.mappings.TaskMonitorMapper; import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.CustomFieldValueReport;
/** /**
* The implementation of CustomFieldValueReportBuilder. * The implementation of CustomFieldValueReportBuilder.
*/ */
public class CustomFieldValueReportBuilderImpl extends ReportBuilder implements CustomFieldValueReportBuilder { public class CustomFieldValueReportBuilderImpl
extends TimeIntervalReportBuilderImpl<CustomFieldValueReport.Builder, TimeIntervalColumnHeader>
implements CustomFieldValueReport.Builder {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomFieldValueReportBuilderImpl.class); private static final Logger LOGGER = LoggerFactory.getLogger(CustomFieldValueReportBuilderImpl.class);
public CustomField customField; private CustomField customField;
public CustomFieldValueReportBuilderImpl(TaskanaEngine taskanaEngine, TaskMonitorMapper taskMonitorMapper, CustomFieldValueReportBuilderImpl(TaskanaEngine taskanaEngine, TaskMonitorMapper taskMonitorMapper,
CustomField customField) { CustomField customField) {
super(taskanaEngine, taskMonitorMapper); super(taskanaEngine, taskMonitorMapper);
this.customField = customField; this.customField = customField;
} }
@Override @Override
public CustomFieldValueReportBuilderImpl withColumnHeaders(List<TimeIntervalColumnHeader> columnHeaders) { protected CustomFieldValueReport.Builder _this() {
this.columnHeaders = columnHeaders;
return this; return this;
} }
@Override @Override
public CustomFieldValueReportBuilderImpl inWorkingDays() { protected String determineDimension() {
this.inWorkingDays = true; return customField.name();
return this;
}
@Override
public CustomFieldValueReportBuilderImpl workbasketIdIn(List<String> workbasketIds) {
this.workbasketIds = workbasketIds;
return this;
}
@Override
public CustomFieldValueReportBuilderImpl stateIn(List<TaskState> states) {
this.states = states;
return this;
}
@Override
public CustomFieldValueReportBuilderImpl categoryIn(List<String> categories) {
this.categories = categories;
return this;
}
@Override
public CustomFieldValueReportBuilderImpl domainIn(List<String> domains) {
this.domains = domains;
return this;
}
@Override
public CustomFieldValueReportBuilderImpl classificationIdIn(List<String> classificationIds) {
this.classificationIds = classificationIds;
return this;
}
@Override
public CustomFieldValueReportBuilderImpl excludedClassificationIdIn(List<String> excludedClassificationIds) {
this.excludedClassificationIds = excludedClassificationIds;
return this;
}
@Override
public CustomFieldValueReportBuilderImpl customAttributeFilterIn(Map<CustomField, String> customAttributeFilter) {
this.customAttributeFilter = customAttributeFilter;
return this;
} }
@Override @Override
@ -111,9 +66,4 @@ public class CustomFieldValueReportBuilderImpl extends ReportBuilder implements
} }
} }
@Override
public CustomField getCustomField() {
return customField;
}
} }

View File

@ -12,8 +12,8 @@ import java.util.List;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader;
import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.util.LoggerUtils; import pro.taskana.impl.util.LoggerUtils;
/** /**
@ -34,7 +34,7 @@ public final class DaysToWorkingDaysConverter {
private static boolean germanHolidaysEnabled; private static boolean germanHolidaysEnabled;
private static List<LocalDate> customHolidays; private static List<LocalDate> customHolidays;
private DaysToWorkingDaysConverter(List<TimeIntervalColumnHeader> columnHeaders, private DaysToWorkingDaysConverter(List<? extends TimeIntervalColumnHeader> columnHeaders,
Instant referenceDate) { Instant referenceDate) {
easterSunday = getEasterSunday(LocalDateTime.ofInstant(referenceDate, ZoneId.systemDefault()).getYear()); easterSunday = getEasterSunday(LocalDateTime.ofInstant(referenceDate, ZoneId.systemDefault()).getYear());
dateCreated = referenceDate; dateCreated = referenceDate;
@ -52,7 +52,7 @@ public final class DaysToWorkingDaysConverter {
* @throws InvalidArgumentException * @throws InvalidArgumentException
* thrown if columnHeaders is null * thrown if columnHeaders is null
*/ */
public static DaysToWorkingDaysConverter initialize(List<TimeIntervalColumnHeader> columnHeaders) public static DaysToWorkingDaysConverter initialize(List<? extends TimeIntervalColumnHeader> columnHeaders)
throws InvalidArgumentException { throws InvalidArgumentException {
return initialize(columnHeaders, Instant.now()); return initialize(columnHeaders, Instant.now());
} }
@ -69,7 +69,7 @@ public final class DaysToWorkingDaysConverter {
* @throws InvalidArgumentException * @throws InvalidArgumentException
* thrown if columnHeaders or referenceDate is null * thrown if columnHeaders or referenceDate is null
*/ */
public static DaysToWorkingDaysConverter initialize(List<TimeIntervalColumnHeader> columnHeaders, public static DaysToWorkingDaysConverter initialize(List<? extends TimeIntervalColumnHeader> columnHeaders,
Instant referenceDate) throws InvalidArgumentException { Instant referenceDate) throws InvalidArgumentException {
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Initialize DaysToWorkingDaysConverter with columnHeaders: {}", LOGGER.debug("Initialize DaysToWorkingDaysConverter with columnHeaders: {}",
@ -95,6 +95,30 @@ public final class DaysToWorkingDaysConverter {
return instance; return instance;
} }
private static int getSmallestUpperLimit(List<? extends TimeIntervalColumnHeader> columnHeaders) {
int smallestUpperLimit = 0;
for (TimeIntervalColumnHeader columnHeader : columnHeaders) {
if (columnHeader.getUpperAgeLimit() < smallestUpperLimit) {
smallestUpperLimit = columnHeader.getUpperAgeLimit();
}
}
return smallestUpperLimit;
}
private static int getLargestLowerLimit(List<? extends TimeIntervalColumnHeader> columnHeaders) {
int greatestLowerLimit = 0;
for (TimeIntervalColumnHeader columnHeader : columnHeaders) {
if (columnHeader.getUpperAgeLimit() > greatestLowerLimit) {
greatestLowerLimit = columnHeader.getLowerAgeLimit();
}
}
return greatestLowerLimit;
}
public static void setGermanPublicHolidaysEnabled(boolean germanPublicHolidaysEnabled) {
germanHolidaysEnabled = germanPublicHolidaysEnabled;
}
/** /**
* Converts an integer, that represents the age in days, to the age in working days by using the table that was * Converts an integer, that represents the age in days, to the age in working days by using the table that was
* created by initialization. If the age in days is beyond the limits of the table, the integer will be returned * created by initialization. If the age in days is beyond the limits of the table, the integer will be returned
@ -189,7 +213,7 @@ public final class DaysToWorkingDaysConverter {
} }
private ArrayList<Integer> generateNegativeDaysToWorkingDays( private ArrayList<Integer> generateNegativeDaysToWorkingDays(
List<TimeIntervalColumnHeader> columnHeaders, Instant referenceDate) { List<? extends TimeIntervalColumnHeader> columnHeaders, Instant referenceDate) {
int minUpperLimit = getSmallestUpperLimit(columnHeaders); int minUpperLimit = getSmallestUpperLimit(columnHeaders);
ArrayList<Integer> daysToWorkingDays = new ArrayList<>(); ArrayList<Integer> daysToWorkingDays = new ArrayList<>();
daysToWorkingDays.add(0); daysToWorkingDays.add(0);
@ -206,7 +230,7 @@ public final class DaysToWorkingDaysConverter {
} }
private ArrayList<Integer> generatePositiveDaysToWorkingDays( private ArrayList<Integer> generatePositiveDaysToWorkingDays(
List<TimeIntervalColumnHeader> columnHeaders, Instant referenceDate) { List<? extends TimeIntervalColumnHeader> columnHeaders, Instant referenceDate) {
int maxLowerLimit = getLargestLowerLimit(columnHeaders); int maxLowerLimit = getLargestLowerLimit(columnHeaders);
ArrayList<Integer> daysToWorkingDays = new ArrayList<>(); ArrayList<Integer> daysToWorkingDays = new ArrayList<>();
daysToWorkingDays.add(0); daysToWorkingDays.add(0);
@ -223,26 +247,6 @@ public final class DaysToWorkingDaysConverter {
return daysToWorkingDays; return daysToWorkingDays;
} }
private static int getSmallestUpperLimit(List<TimeIntervalColumnHeader> columnHeaders) {
int smallestUpperLimit = 0;
for (TimeIntervalColumnHeader columnHeader : columnHeaders) {
if (columnHeader.getUpperAgeLimit() < smallestUpperLimit) {
smallestUpperLimit = columnHeader.getUpperAgeLimit();
}
}
return smallestUpperLimit;
}
private static int getLargestLowerLimit(List<TimeIntervalColumnHeader> columnHeaders) {
int greatestLowerLimit = 0;
for (TimeIntervalColumnHeader columnHeader : columnHeaders) {
if (columnHeader.getUpperAgeLimit() > greatestLowerLimit) {
greatestLowerLimit = columnHeader.getLowerAgeLimit();
}
}
return greatestLowerLimit;
}
private boolean isWorkingDay(int day, Instant referenceDate) { private boolean isWorkingDay(int day, Instant referenceDate) {
LocalDateTime dateTime = LocalDateTime.ofInstant(referenceDate, ZoneId.systemDefault()).plusDays(day); LocalDateTime dateTime = LocalDateTime.ofInstant(referenceDate, ZoneId.systemDefault()).plusDays(day);
if (dateTime.getDayOfWeek().equals(DayOfWeek.SATURDAY) if (dateTime.getDayOfWeek().equals(DayOfWeek.SATURDAY)
@ -310,16 +314,12 @@ public final class DaysToWorkingDaysConverter {
return LocalDate.of(year, 3, 22).plusDays(d + e); return LocalDate.of(year, 3, 22).plusDays(d + e);
} }
public static void setCustomHolidays(List<LocalDate> holidays) {
customHolidays = holidays;
}
public List<LocalDate> getCustomHolidays() { public List<LocalDate> getCustomHolidays() {
return customHolidays; return customHolidays;
} }
public static void setGermanPublicHolidaysEnabled(boolean germanPublicHolidaysEnabled) { public static void setCustomHolidays(List<LocalDate> holidays) {
germanHolidaysEnabled = germanPublicHolidaysEnabled; customHolidays = holidays;
} }
public boolean isGermanPublicHolidayEnabled() { public boolean isGermanPublicHolidayEnabled() {

View File

@ -1,21 +1,20 @@
package pro.taskana.impl; package pro.taskana.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pro.taskana.CategoryReportBuilder;
import pro.taskana.ClassificationReportBuilder;
import pro.taskana.CustomField; import pro.taskana.CustomField;
import pro.taskana.TaskMonitorService; import pro.taskana.TaskMonitorService;
import pro.taskana.TaskanaEngine; import pro.taskana.TaskanaEngine;
import pro.taskana.mappings.TaskMonitorMapper; import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.CategoryReport;
import pro.taskana.report.ClassificationReport;
import pro.taskana.report.CustomFieldValueReport;
import pro.taskana.report.TaskStatusReport;
import pro.taskana.report.WorkbasketReport;
/** /**
* This is the implementation of TaskMonitorService. * This is the implementation of TaskMonitorService.
*/ */
public class TaskMonitorServiceImpl implements TaskMonitorService { public class TaskMonitorServiceImpl implements TaskMonitorService {
private static final Logger LOGGER = LoggerFactory.getLogger(TaskMonitorServiceImpl.class);
private TaskanaEngineImpl taskanaEngineImpl; private TaskanaEngineImpl taskanaEngineImpl;
private TaskMonitorMapper taskMonitorMapper; private TaskMonitorMapper taskMonitorMapper;
@ -26,27 +25,27 @@ public class TaskMonitorServiceImpl implements TaskMonitorService {
} }
@Override @Override
public WorkbasketReportBuilderImpl createWorkbasketReportBuilder() { public WorkbasketReport.Builder createWorkbasketReportBuilder() {
return new WorkbasketReportBuilderImpl(taskanaEngineImpl, taskMonitorMapper); return new WorkbasketReportBuilderImpl(taskanaEngineImpl, taskMonitorMapper);
} }
@Override @Override
public CategoryReportBuilder createCategoryReportBuilder() { public CategoryReport.Builder createCategoryReportBuilder() {
return new CategoryReportBuilderImpl(taskanaEngineImpl, taskMonitorMapper); return new CategoryReportBuilderImpl(taskanaEngineImpl, taskMonitorMapper);
} }
@Override @Override
public ClassificationReportBuilder createClassificationReportBuilder() { public ClassificationReport.Builder createClassificationReportBuilder() {
return new ClassificationReportBuilderImpl(taskanaEngineImpl, taskMonitorMapper); return new ClassificationReportBuilderImpl(taskanaEngineImpl, taskMonitorMapper);
} }
@Override @Override
public CustomFieldValueReportBuilderImpl createCustomFieldValueReportBuilder(CustomField customField) { public CustomFieldValueReport.Builder createCustomFieldValueReportBuilder(CustomField customField) {
return new CustomFieldValueReportBuilderImpl(taskanaEngineImpl, taskMonitorMapper, customField); return new CustomFieldValueReportBuilderImpl(taskanaEngineImpl, taskMonitorMapper, customField);
} }
@Override @Override
public TaskStatusReportBuilderImpl createTaskStatusReportBuilder() { public TaskStatusReport.Builder createTaskStatusReportBuilder() {
return new TaskStatusReportBuilderImpl(taskanaEngineImpl, taskMonitorMapper); return new TaskStatusReportBuilderImpl(taskanaEngineImpl, taskMonitorMapper);
} }

View File

@ -44,7 +44,7 @@ import pro.taskana.exceptions.TaskAlreadyExistException;
import pro.taskana.exceptions.TaskNotFoundException; import pro.taskana.exceptions.TaskNotFoundException;
import pro.taskana.exceptions.TaskanaException; import pro.taskana.exceptions.TaskanaException;
import pro.taskana.exceptions.WorkbasketNotFoundException; import pro.taskana.exceptions.WorkbasketNotFoundException;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.util.IdGenerator; import pro.taskana.impl.util.IdGenerator;
import pro.taskana.impl.util.LoggerUtils; import pro.taskana.impl.util.LoggerUtils;
import pro.taskana.mappings.AttachmentMapper; import pro.taskana.mappings.AttachmentMapper;

View File

@ -6,18 +6,17 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pro.taskana.TaskState; import pro.taskana.TaskState;
import pro.taskana.TaskStatusReportBuilder;
import pro.taskana.TaskanaEngine; import pro.taskana.TaskanaEngine;
import pro.taskana.TaskanaRole; import pro.taskana.TaskanaRole;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.impl.TaskQueryItem; import pro.taskana.impl.report.TaskQueryItem;
import pro.taskana.impl.report.impl.TaskStatusReport;
import pro.taskana.mappings.TaskMonitorMapper; import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.TaskStatusReport;
/** /**
* The implementation of TaskStatusReportBuilder. * The implementation of TaskStatusReportBuilder.
*/ */
public class TaskStatusReportBuilderImpl implements TaskStatusReportBuilder { public class TaskStatusReportBuilderImpl implements TaskStatusReport.Builder {
private static final Logger LOGGER = LoggerFactory.getLogger(TaskStatusReportBuilderImpl.class); private static final Logger LOGGER = LoggerFactory.getLogger(TaskStatusReportBuilderImpl.class);
private TaskanaEngineImpl taskanaEngine; private TaskanaEngineImpl taskanaEngine;
@ -25,7 +24,7 @@ public class TaskStatusReportBuilderImpl implements TaskStatusReportBuilder {
private List<String> domains; private List<String> domains;
private List<TaskState> states; private List<TaskState> states;
public TaskStatusReportBuilderImpl(TaskanaEngine taskanaEngine, TaskMonitorMapper taskMonitorMapper) { TaskStatusReportBuilderImpl(TaskanaEngine taskanaEngine, TaskMonitorMapper taskMonitorMapper) {
this.taskanaEngine = (TaskanaEngineImpl) taskanaEngine; this.taskanaEngine = (TaskanaEngineImpl) taskanaEngine;
this.taskMonitorMapper = taskMonitorMapper; this.taskMonitorMapper = taskMonitorMapper;
} }

View File

@ -1,42 +1,37 @@
package pro.taskana.impl; package pro.taskana.impl;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pro.taskana.CategoryReportBuilder;
import pro.taskana.ClassificationReportBuilder;
import pro.taskana.CustomField; import pro.taskana.CustomField;
import pro.taskana.CustomFieldValueReportBuilder;
import pro.taskana.TaskState; import pro.taskana.TaskState;
import pro.taskana.TaskanaEngine; import pro.taskana.TaskanaEngine;
import pro.taskana.TaskanaRole; import pro.taskana.TaskanaRole;
import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.exceptions.SystemException; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader;
import pro.taskana.impl.util.LoggerUtils; import pro.taskana.impl.util.LoggerUtils;
import pro.taskana.mappings.TaskMonitorMapper; import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.ClassificationReport;
import pro.taskana.report.TimeIntervalReportBuilder;
/** /**
* The super class of the different report builders. * Implementation of {@link TimeIntervalReportBuilder}.
* @param <B> the true Builder behind this Interface
* @param <H> the column header
*/ */
public abstract class ReportBuilder { abstract class TimeIntervalReportBuilderImpl<B extends TimeIntervalReportBuilder, H extends TimeIntervalColumnHeader>
implements TimeIntervalReportBuilder<B, H> {
private static final Logger LOGGER = LoggerFactory.getLogger(ReportBuilder.class); private static final Logger LOGGER = LoggerFactory.getLogger(TimeIntervalReportBuilder.class);
private static final String DIMENSION_CLASSIFICATION_CATEGORY = "CLASSIFICATION_CATEGORY";
private static final String DIMENSION_CLASSIFICATION_KEY = "CLASSIFICATION_KEY";
private static final String DIMENSION_WORKBASKET_KEY = "WORKBASKET_KEY";
protected TaskanaEngineImpl taskanaEngine; protected TaskanaEngineImpl taskanaEngine;
protected TaskMonitorMapper taskMonitorMapper; protected TaskMonitorMapper taskMonitorMapper;
protected List<TimeIntervalColumnHeader> columnHeaders; protected List<H> columnHeaders;
protected boolean inWorkingDays; protected boolean inWorkingDays;
protected List<String> workbasketIds; protected List<String> workbasketIds;
protected List<TaskState> states; protected List<TaskState> states;
@ -46,73 +41,87 @@ public abstract class ReportBuilder {
protected List<String> excludedClassificationIds; protected List<String> excludedClassificationIds;
protected Map<CustomField, String> customAttributeFilter; protected Map<CustomField, String> customAttributeFilter;
public ReportBuilder(TaskanaEngine taskanaEngine, TaskMonitorMapper taskMonitorMapper) { TimeIntervalReportBuilderImpl(TaskanaEngine taskanaEngine, TaskMonitorMapper taskMonitorMapper) {
this.taskanaEngine = (TaskanaEngineImpl) taskanaEngine; this.taskanaEngine = (TaskanaEngineImpl) taskanaEngine;
this.taskMonitorMapper = taskMonitorMapper; this.taskMonitorMapper = taskMonitorMapper;
this.columnHeaders = Collections.emptyList(); this.columnHeaders = Collections.emptyList();
configureDaysToWorkingDaysConverter(); configureDaysToWorkingDaysConverter();
} }
public List<TimeIntervalColumnHeader> getColumnHeaders() { protected abstract B _this();
if (columnHeaders == null) {
columnHeaders = new ArrayList<>(); @Override
} public B withColumnHeaders(List<H> columnHeaders) {
return this.columnHeaders; this.columnHeaders = columnHeaders;
return _this();
} }
public boolean isInWorkingDays() { @Override
return this.inWorkingDays; public B inWorkingDays() {
this.inWorkingDays = true;
return _this();
} }
public List<String> getWorkbasketIdIn() { @Override
if (workbasketIds == null) { public B workbasketIdIn(List<String> workbasketIds) {
workbasketIds = new ArrayList<>(); this.workbasketIds = workbasketIds;
} return _this();
return this.workbasketIds;
} }
public List<TaskState> getStateIn() { @Override
if (states == null) { public B stateIn(List<TaskState> states) {
states = new ArrayList<>(); this.states = states;
} return _this();
return this.states;
} }
public List<String> getCategoryIn() { @Override
if (categories == null) { public B categoryIn(List<String> categories) {
categories = new ArrayList<>(); this.categories = categories;
} return _this();
return this.categories;
} }
public List<String> getDomainIn() { @Override
if (domains == null) { public B classificationIdIn(List<String> classificationIds) {
domains = new ArrayList<>(); this.classificationIds = classificationIds;
} return _this();
return this.domains;
} }
public List<String> getClassificationIdsIn() { @Override
if (classificationIds == null) { public B excludedClassificationIdIn(List<String> excludedClassificationIds) {
classificationIds = new ArrayList<>(); this.excludedClassificationIds = excludedClassificationIds;
} return _this();
return this.classificationIds;
} }
public List<String> getExcludedClassificationIdsIn() { @Override
if (excludedClassificationIds == null) { public B domainIn(List<String> domains) {
excludedClassificationIds = new ArrayList<>(); this.domains = domains;
} return _this();
return this.excludedClassificationIds;
} }
public Map<CustomField, String> getCustomAttributeFilter() { @Override
if (customAttributeFilter == null) { public B customAttributeFilterIn(Map<CustomField, String> customAttributeFilter) {
customAttributeFilter = new HashMap<>(); this.customAttributeFilter = customAttributeFilter;
} return _this();
return this.customAttributeFilter;
} }
@Override
public List<String> listCustomAttributeValuesForCustomAttributeName(CustomField customField)
throws NotAuthorizedException {
LOGGER.debug("entry to listCustomAttributeValuesForCustomAttributeName(customField = {}), this = {}",
customField, this);
this.taskanaEngine.checkRoleMembership(TaskanaRole.MONITOR);
try {
this.taskanaEngine.openConnection();
return taskMonitorMapper.getCustomAttributeValuesForReport(this.workbasketIds,
this.states, this.categories, this.domains, this.classificationIds, this.excludedClassificationIds,
this.customAttributeFilter, customField);
} finally {
this.taskanaEngine.returnConnection();
LOGGER.debug("exit from listCustomAttributeValuesForCustomAttributeName().");
}
}
@Override
public List<String> listTaskIdsForSelectedItems(List<SelectedItem> selectedItems) public List<String> listTaskIdsForSelectedItems(List<SelectedItem> selectedItems)
throws NotAuthorizedException, InvalidArgumentException { throws NotAuthorizedException, InvalidArgumentException {
LOGGER.debug("entry to listTaskIdsForSelectedItems(selectedItems = {}), this = {}", LOGGER.debug("entry to listTaskIdsForSelectedItems(selectedItems = {}), this = {}",
@ -127,55 +136,23 @@ public abstract class ReportBuilder {
throw new InvalidArgumentException("SelectedItems must not be null or empty."); throw new InvalidArgumentException("SelectedItems must not be null or empty.");
} }
boolean joinWithAttachments = subKeyIsSet(selectedItems); boolean joinWithAttachments = subKeyIsSet(selectedItems);
if (!(this instanceof ClassificationReportBuilder) && joinWithAttachments) { if (!(this instanceof ClassificationReport.Builder) && joinWithAttachments) {
throw new InvalidArgumentException("SubKeys are supported for ClassificationReport only."); throw new InvalidArgumentException("SubKeys are supported for ClassificationReport only.");
} }
String dimension = determineDimension(); String dimension = determineDimension();
if (this.inWorkingDays) { if (this.inWorkingDays) {
selectedItems = convertWorkingDaysToDays(selectedItems, this.columnHeaders); selectedItems = convertWorkingDaysToDays(selectedItems, this.columnHeaders);
} }
List<String> taskIds = this.taskMonitorMapper.getTaskIdsForSelectedItems(this.workbasketIds, return this.taskMonitorMapper.getTaskIdsForSelectedItems(this.workbasketIds,
this.states, this.categories, this.domains, this.classificationIds, this.excludedClassificationIds, this.states, this.categories, this.domains, this.classificationIds, this.excludedClassificationIds,
this.customAttributeFilter, dimension, selectedItems, joinWithAttachments); this.customAttributeFilter, dimension, selectedItems, joinWithAttachments);
return taskIds;
} finally { } finally {
this.taskanaEngine.returnConnection(); this.taskanaEngine.returnConnection();
LOGGER.debug("exit from listTaskIdsForSelectedItems()."); LOGGER.debug("exit from listTaskIdsForSelectedItems().");
} }
} }
private String determineDimension() { protected abstract String determineDimension();
String dimension = null;
if (this instanceof CategoryReportBuilder) {
dimension = DIMENSION_CLASSIFICATION_CATEGORY;
} else if (this instanceof WorkbasketReportBuilderImpl) {
dimension = DIMENSION_WORKBASKET_KEY;
} else if (this instanceof ClassificationReportBuilder) {
dimension = DIMENSION_CLASSIFICATION_KEY;
} else if (this instanceof CustomFieldValueReportBuilder) {
dimension = ((CustomFieldValueReportBuilder) this).getCustomField().toString();
} else {
throw new SystemException("Internal error. listTaskIdsForSelectedItems() does not support " + this);
}
return dimension;
}
public List<String> listCustomAttributeValuesForCustomAttributeName(CustomField customField)
throws NotAuthorizedException {
LOGGER.debug("entry to listCustomAttributeValuesForCustomAttributeName(customField = {}), this = {}",
customField, this);
this.taskanaEngine.checkRoleMembership(TaskanaRole.MONITOR);
try {
this.taskanaEngine.openConnection();
List<String> customAttributeValues = taskMonitorMapper.getCustomAttributeValuesForReport(this.workbasketIds,
this.states, this.categories, this.domains, this.classificationIds, this.excludedClassificationIds,
this.customAttributeFilter, customField);
return customAttributeValues;
} finally {
this.taskanaEngine.returnConnection();
LOGGER.debug("exit from listCustomAttributeValuesForCustomAttributeName().");
}
}
private void configureDaysToWorkingDaysConverter() { private void configureDaysToWorkingDaysConverter() {
DaysToWorkingDaysConverter.setCustomHolidays(this.taskanaEngine.getConfiguration().getCustomHolidays()); DaysToWorkingDaysConverter.setCustomHolidays(this.taskanaEngine.getConfiguration().getCustomHolidays());
@ -184,7 +161,7 @@ public abstract class ReportBuilder {
} }
private List<SelectedItem> convertWorkingDaysToDays(List<SelectedItem> selectedItems, private List<SelectedItem> convertWorkingDaysToDays(List<SelectedItem> selectedItems,
List<TimeIntervalColumnHeader> columnHeaders) throws InvalidArgumentException { List<H> columnHeaders) throws InvalidArgumentException {
DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter.initialize(columnHeaders); DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter.initialize(columnHeaders);
for (SelectedItem selectedItem : selectedItems) { for (SelectedItem selectedItem : selectedItems) {
selectedItem selectedItem
@ -195,7 +172,7 @@ public abstract class ReportBuilder {
return selectedItems; return selectedItems;
} }
protected boolean subKeyIsSet(List<SelectedItem> selectedItems) { private boolean subKeyIsSet(List<SelectedItem> selectedItems) {
for (SelectedItem selectedItem : selectedItems) { for (SelectedItem selectedItem : selectedItems) {
if (selectedItem.getSubKey() != null && !selectedItem.getSubKey().isEmpty()) { if (selectedItem.getSubKey() != null && !selectedItem.getSubKey().isEmpty()) {
return true; return true;
@ -205,3 +182,4 @@ public abstract class ReportBuilder {
} }
} }

View File

@ -1,104 +1,43 @@
package pro.taskana.impl; package pro.taskana.impl;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pro.taskana.CustomField;
import pro.taskana.TaskState;
import pro.taskana.TaskanaEngine; import pro.taskana.TaskanaEngine;
import pro.taskana.TaskanaRole; import pro.taskana.TaskanaRole;
import pro.taskana.WorkbasketReportBuilder;
import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.impl.CombinedClassificationFilter; import pro.taskana.impl.report.CombinedClassificationFilter;
import pro.taskana.impl.report.impl.DaysToWorkingDaysPreProcessor; import pro.taskana.impl.report.DaysToWorkingDaysPreProcessor;
import pro.taskana.impl.report.impl.MonitorQueryItem; import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.impl.WorkbasketReport;
import pro.taskana.mappings.TaskMonitorMapper; import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.WorkbasketReport;
/** /**
* The implementation of WorkbasketReportBuilder. * The implementation of WorkbasketReportBuilder.
*/ */
public class WorkbasketReportBuilderImpl extends ReportBuilder implements WorkbasketReportBuilder { public class WorkbasketReportBuilderImpl
extends TimeIntervalReportBuilderImpl<WorkbasketReport.Builder, TimeIntervalColumnHeader>
implements WorkbasketReport.Builder {
private static final Logger LOGGER = LoggerFactory.getLogger(WorkbasketReportBuilderImpl.class); private static final Logger LOGGER = LoggerFactory.getLogger(WorkbasketReportBuilderImpl.class);
private List<CombinedClassificationFilter> combinedClassificationFilter; private List<CombinedClassificationFilter> combinedClassificationFilter;
public WorkbasketReportBuilderImpl(TaskanaEngine taskanaEngine, TaskMonitorMapper taskMonitorMapper) { WorkbasketReportBuilderImpl(TaskanaEngine taskanaEngine, TaskMonitorMapper taskMonitorMapper) {
super(taskanaEngine, taskMonitorMapper); super(taskanaEngine, taskMonitorMapper);
} }
@Override @Override
public WorkbasketReportBuilderImpl withColumnHeaders(List<TimeIntervalColumnHeader> columnHeaders) { protected WorkbasketReport.Builder _this() {
this.columnHeaders = columnHeaders;
return this; return this;
} }
@Override @Override
public WorkbasketReportBuilderImpl inWorkingDays() { protected String determineDimension() {
this.inWorkingDays = true; return "WORKBASKET_KEY";
return this;
}
@Override
public WorkbasketReportBuilderImpl workbasketIdIn(List<String> workbasketIds) {
this.workbasketIds = workbasketIds;
return this;
}
@Override
public WorkbasketReportBuilderImpl stateIn(List<TaskState> states) {
this.states = states;
return this;
}
@Override
public WorkbasketReportBuilderImpl categoryIn(List<String> categories) {
this.categories = categories;
return this;
}
@Override
public WorkbasketReportBuilderImpl domainIn(List<String> domains) {
this.domains = domains;
return this;
}
@Override
public WorkbasketReportBuilderImpl classificationIdIn(List<String> classificationIds) {
this.classificationIds = classificationIds;
return this;
}
@Override
public WorkbasketReportBuilderImpl excludedClassificationIdIn(List<String> excludedClassificationIds) {
this.excludedClassificationIds = excludedClassificationIds;
return this;
}
@Override
public WorkbasketReportBuilderImpl customAttributeFilterIn(Map<CustomField, String> customAttributeFilter) {
this.customAttributeFilter = customAttributeFilter;
return this;
}
@Override
public WorkbasketReportBuilderImpl combinedClassificationFilterIn(
List<CombinedClassificationFilter> combinedClassificationFilter) {
this.combinedClassificationFilter = combinedClassificationFilter;
return this;
}
public List<CombinedClassificationFilter> getCombinedClassificationFilterIn() {
if (combinedClassificationFilter == null) {
combinedClassificationFilter = new ArrayList<>();
}
return this.combinedClassificationFilter;
} }
@Override @Override
@ -120,4 +59,10 @@ public class WorkbasketReportBuilderImpl extends ReportBuilder implements Workba
} }
} }
@Override
public WorkbasketReport.Builder combinedClassificationFilterIn(
List<CombinedClassificationFilter> combinedClassificationFilter) {
this.combinedClassificationFilter = combinedClassificationFilter;
return this;
}
} }

View File

@ -1,8 +1,8 @@
package pro.taskana.impl.report.impl; package pro.taskana.impl.report;
/** /**
* The CombinedClassificationFilter is a pair of a classificationId for a task and a classificationId for the * The CombinedClassificationFilter is a pair of a classificationId for a task and a classificationId for the
* corresponding attachment that is used to filter the {@link WorkbasketReport} by the classification of the attachment. * corresponding attachment that is used to filter the {@link pro.taskana.report.WorkbasketReport} by the classification of the attachment.
* To filter by the classification of the task, the classificationId of the attachment should be null. * To filter by the classification of the task, the classificationId of the attachment should be null.
*/ */
public class CombinedClassificationFilter { public class CombinedClassificationFilter {

View File

@ -1,10 +1,10 @@
package pro.taskana.impl.report.impl; package pro.taskana.impl.report;
import java.util.List; import java.util.List;
import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.impl.DaysToWorkingDaysConverter; import pro.taskana.impl.DaysToWorkingDaysConverter;
import pro.taskana.impl.report.QueryItemPreprocessor; import pro.taskana.report.QueryItemPreprocessor;
/** /**
* Uses {@link DaysToWorkingDaysConverter} to convert an &lt;Item&gt;s age to working days. * Uses {@link DaysToWorkingDaysConverter} to convert an &lt;Item&gt;s age to working days.

View File

@ -1,4 +1,4 @@
package pro.taskana.impl.report.impl; package pro.taskana.impl.report;
/** /**
* The DetailedMonitorQueryItem extends the {@link MonitorQueryItem}. * The DetailedMonitorQueryItem extends the {@link MonitorQueryItem}.

View File

@ -1,9 +1,9 @@
package pro.taskana.impl.report.impl; package pro.taskana.impl.report;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import pro.taskana.impl.report.ReportRow; import pro.taskana.report.ReportRow;
/** /**
* The DetailedReportRow extends the {@link ReportRow}. * The DetailedReportRow extends the {@link ReportRow}.

View File

@ -1,6 +1,6 @@
package pro.taskana.impl.report.impl; package pro.taskana.impl.report;
import pro.taskana.impl.report.QueryItem; import pro.taskana.report.QueryItem;
/** /**
* The MonitorQueryItem entity contains the number of tasks for a key (e.g. workbasketKey) and age in days. * The MonitorQueryItem entity contains the number of tasks for a key (e.g. workbasketKey) and age in days.

View File

@ -1,7 +1,7 @@
package pro.taskana.impl.report.impl; package pro.taskana.impl.report;
import pro.taskana.TaskState; import pro.taskana.TaskState;
import pro.taskana.impl.report.QueryItem; import pro.taskana.report.QueryItem;
/** /**
* The TaskQueryItem entity contains the number of tasks for a domain which have a specific state. * The TaskQueryItem entity contains the number of tasks for a domain which have a specific state.

View File

@ -1,7 +1,7 @@
package pro.taskana.impl.report.impl; package pro.taskana.impl.report;
import pro.taskana.TaskState; import pro.taskana.TaskState;
import pro.taskana.impl.report.ReportColumnHeader; import pro.taskana.report.ReportColumnHeader;
/** /**
* The TaskStatusColumnHeader represents a column for each {@link TaskState}. * The TaskStatusColumnHeader represents a column for each {@link TaskState}.

View File

@ -1,6 +1,6 @@
package pro.taskana.impl.report.impl; package pro.taskana.impl.report;
import pro.taskana.impl.report.ReportColumnHeader; import pro.taskana.report.ReportColumnHeader;
/** /**
* A TimeIntervalColumnHeader has a lower and an upper age limit which subdivide the count of tasks into different * A TimeIntervalColumnHeader has a lower and an upper age limit which subdivide the count of tasks into different

View File

@ -1,16 +0,0 @@
package pro.taskana.impl.report.impl;
import java.util.List;
import pro.taskana.impl.report.Report;
/**
* TODO.
*/
public class CategoryReport extends Report<MonitorQueryItem, TimeIntervalColumnHeader> {
public CategoryReport(List<TimeIntervalColumnHeader> timeIntervalColumnHeaders) {
super(timeIntervalColumnHeaders, "CLASSIFICATION CATEGORIES");
}
}

View File

@ -1,17 +0,0 @@
package pro.taskana.impl.report.impl;
import java.util.List;
import pro.taskana.impl.report.Report;
/**
* The ClassificationReport extends the Report. The {@link pro.taskana.impl.report.ReportRow}s of the ClassificationReport are grouped by
* classifications.
*/
public class ClassificationReport extends Report<MonitorQueryItem, TimeIntervalColumnHeader> {
public ClassificationReport(List<TimeIntervalColumnHeader> timeIntervalColumnHeaders) {
super(timeIntervalColumnHeaders, "CLASSIFICATION KEYS");
}
}

View File

@ -1,15 +0,0 @@
package pro.taskana.impl.report.impl;
import java.util.List;
import pro.taskana.impl.report.Report;
/**
* TODO.
*/
public class CustomFieldValueReport extends Report<MonitorQueryItem, TimeIntervalColumnHeader> {
public CustomFieldValueReport(List<TimeIntervalColumnHeader> timeIntervalColumnHeaders) {
super(timeIntervalColumnHeaders, "CUSTOM FIELDS");
}
}

View File

@ -1,28 +0,0 @@
package pro.taskana.impl.report.impl;
import java.util.List;
import pro.taskana.impl.report.Report;
/**
* The DetailedClassificationReport is a functional extension of the {@link ClassificationReport}.
* Its {@link DetailedReportRow}s contain an additional list of {@link pro.taskana.impl.report.ReportRow}s
* for the classifications of the attachments of the tasks.
*/
public class DetailedClassificationReport extends Report<DetailedMonitorQueryItem, TimeIntervalColumnHeader> {
public DetailedClassificationReport(List<TimeIntervalColumnHeader> workbasketLevelReportColumnHeaders) {
super(workbasketLevelReportColumnHeaders, "TASK CLASSIFICATION KEYS");
}
@Override
protected DetailedReportRow createReportRow(int columnSize) {
return new DetailedReportRow(columnSize);
}
@Override
public DetailedReportRow getRow(String key) {
return (DetailedReportRow) super.getRow(key);
}
}

View File

@ -1,25 +0,0 @@
package pro.taskana.impl.report.impl;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import pro.taskana.TaskState;
import pro.taskana.impl.report.Report;
/**
* The TaskStatusReport displays the amount of tasks, differentiated by their state and grouped by domain.
*/
public class TaskStatusReport extends Report<TaskQueryItem, TaskStatusColumnHeader> {
public TaskStatusReport() {
this(null);
}
public TaskStatusReport(List<TaskState> filter) {
super((filter != null ? filter.stream() : Arrays.stream(TaskState.values()))
.map(TaskStatusColumnHeader::new)
.collect(Collectors.toList()), "DOMAINS");
}
}

View File

@ -1,16 +0,0 @@
package pro.taskana.impl.report.impl;
import java.util.List;
import pro.taskana.impl.report.Report;
/**
* TODO.
*/
public class WorkbasketReport extends Report<MonitorQueryItem, TimeIntervalColumnHeader> {
public WorkbasketReport(List<TimeIntervalColumnHeader> timeIntervalColumnHeaders) {
super(timeIntervalColumnHeaders, "WORKBASKET KEYS");
}
}

View File

@ -11,10 +11,10 @@ import org.apache.ibatis.annotations.Select;
import pro.taskana.CustomField; import pro.taskana.CustomField;
import pro.taskana.TaskState; import pro.taskana.TaskState;
import pro.taskana.impl.SelectedItem; import pro.taskana.impl.SelectedItem;
import pro.taskana.impl.report.impl.CombinedClassificationFilter; import pro.taskana.impl.report.CombinedClassificationFilter;
import pro.taskana.impl.report.impl.DetailedMonitorQueryItem; import pro.taskana.impl.report.DetailedMonitorQueryItem;
import pro.taskana.impl.report.impl.MonitorQueryItem; import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.impl.TaskQueryItem; import pro.taskana.impl.report.TaskQueryItem;
/** /**
* This class is the mybatis mapping of task monitoring. * This class is the mybatis mapping of task monitoring.

View File

@ -0,0 +1,32 @@
package pro.taskana.report;
import java.util.List;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
/**
* A CategoryReport contains the total numbers of tasks of the respective category as well as the total number of
* all tasks. The tasks of the report can be filtered by workbaskets, states, categories, domains, classifications
* and values of a custom field. Classifications can also be excluded from the report.
* If the {@link TimeIntervalColumnHeader}s are set, the report 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 CategoryReport extends Report<MonitorQueryItem, TimeIntervalColumnHeader> {
public CategoryReport(List<TimeIntervalColumnHeader> timeIntervalColumnHeaders) {
super(timeIntervalColumnHeaders, "CLASSIFICATION CATEGORIES");
}
/**
* Builder for {@link CategoryReport}.
*/
public interface Builder extends TimeIntervalReportBuilder<Builder, TimeIntervalColumnHeader> {
@Override
CategoryReport buildReport() throws NotAuthorizedException, InvalidArgumentException;
}
}

View File

@ -0,0 +1,67 @@
package pro.taskana.report;
import java.util.List;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.DetailedMonitorQueryItem;
import pro.taskana.impl.report.DetailedReportRow;
import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
/**
* The ClassificationReport extends the Report. The {@link ReportRow}s of the ClassificationReport are grouped by
* classifications.
*/
public class ClassificationReport extends Report<MonitorQueryItem, TimeIntervalColumnHeader> {
public ClassificationReport(List<TimeIntervalColumnHeader> timeIntervalColumnHeaders) {
super(timeIntervalColumnHeaders, "CLASSIFICATION KEYS");
}
/**
* Builder for {@link ClassificationReport}.
*/
public interface Builder extends TimeIntervalReportBuilder<Builder, TimeIntervalColumnHeader> {
@Override
ClassificationReport buildReport() throws NotAuthorizedException, InvalidArgumentException;
/**
* Returns a {@link DetailedClassificationReport} containing all tasks after applying the filters. If the column
* headers are set the report is subdivided into clusters. Its
* {@link pro.taskana.impl.report.DetailedReportRow}s contain an additional list of
* {@link ReportRow}s for the classifications of the attachments of the tasks.
*
* @throws InvalidArgumentException
* if the column headers are not initialized
* @throws NotAuthorizedException
* if the user has no rights to access the monitor
* @return the DetailedClassificationReport
*/
DetailedClassificationReport buildDetailedReport() throws InvalidArgumentException, NotAuthorizedException;
}
/**
* The DetailedClassificationReport is a functional extension of the {@link ClassificationReport}.
* Its {@link DetailedReportRow}s contain an additional list of {@link ReportRow}s
* for the classifications of the attachments of the tasks.
*/
public static class DetailedClassificationReport extends Report<DetailedMonitorQueryItem, TimeIntervalColumnHeader> {
public DetailedClassificationReport(List<TimeIntervalColumnHeader> workbasketLevelReportColumnHeaders) {
super(workbasketLevelReportColumnHeaders, "TASK CLASSIFICATION KEYS");
}
@Override
protected DetailedReportRow createReportRow(int columnSize) {
return new DetailedReportRow(columnSize);
}
@Override
public DetailedReportRow getRow(String key) {
return (DetailedReportRow) super.getRow(key);
}
}
}

View File

@ -0,0 +1,33 @@
package pro.taskana.report;
import java.util.List;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
/**
* A CustomFieldValueReport contains the total numbers of tasks of the respective custom field as well as
* the total number of all tasks. The tasks of the report can be filtered by workbaskets, states, categories, domains,
* classifications and values of a custom field. Classifications can also be excluded from the report. If the
* {@link TimeIntervalColumnHeader}s are set, the report 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<MonitorQueryItem, TimeIntervalColumnHeader> {
public CustomFieldValueReport(List<TimeIntervalColumnHeader> timeIntervalColumnHeaders) {
super(timeIntervalColumnHeaders, "CUSTOM FIELDS");
}
/**
* Builder for {@link CustomFieldValueReport}.
*/
public interface Builder extends TimeIntervalReportBuilder<Builder, TimeIntervalColumnHeader> {
@Override
CustomFieldValueReport buildReport() throws NotAuthorizedException, InvalidArgumentException;
}
}

View File

@ -1,4 +1,4 @@
package pro.taskana.impl.report; package pro.taskana.report;
/** /**
* A QueryItem is en entity on which a {@link Report} is based on. * A QueryItem is en entity on which a {@link Report} is based on.

View File

@ -1,4 +1,4 @@
package pro.taskana.impl.report; package pro.taskana.report;
/** /**
* The QueryItemPreprocessor is used when adding {@link QueryItem}s into a {@link Report}. It defines a processing * The QueryItemPreprocessor is used when adding {@link QueryItem}s into a {@link Report}. It defines a processing

View File

@ -1,4 +1,4 @@
package pro.taskana.impl.report; package pro.taskana.report;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -6,6 +6,9 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
/** /**
* A Report represents a an abstract table that consists of {@link ReportRow}s and a list of &lt;ColumnHeader&gt;s. * A Report represents a an abstract table that consists of {@link ReportRow}s and a list of &lt;ColumnHeader&gt;s.
* Since a report does not specify &lt;Item&gt; and &lt;ColumnHeader&gt; it does not contain functional logic. * Since a report does not specify &lt;Item&gt; and &lt;ColumnHeader&gt; it does not contain functional logic.
@ -22,7 +25,7 @@ public abstract class Report<Item extends QueryItem, ColumnHeader extends Report
private ReportRow<Item> sumRow; private ReportRow<Item> sumRow;
private String rowDesc; private String rowDesc;
public Report(List<ColumnHeader> columnHeaders, String rowDesc) { protected Report(List<ColumnHeader> columnHeaders, String rowDesc) {
this.rowDesc = rowDesc; this.rowDesc = rowDesc;
sumRow = new ReportRow<>(columnHeaders.size()); sumRow = new ReportRow<>(columnHeaders.size());
this.columnHeaders.addAll(columnHeaders); this.columnHeaders.addAll(columnHeaders);
@ -84,4 +87,14 @@ public abstract class Report<Item extends QueryItem, ColumnHeader extends Report
protected ReportRow<Item> createReportRow(int columnSize) { protected ReportRow<Item> createReportRow(int columnSize) {
return new ReportRow<>(columnSize); return new ReportRow<>(columnSize);
} }
/**
* Builder for {@link Report}.
* @param <I> {@link QueryItem} whose value is relevant for this report.
* @param <H> {@link ReportColumnHeader} which can determine if an &lt;Item&gt; belongs into that column or not.
*/
public interface Builder<I extends QueryItem, H extends ReportColumnHeader<? super I>> {
Report<I, H> buildReport() throws NotAuthorizedException, InvalidArgumentException;
}
} }

View File

@ -1,4 +1,4 @@
package pro.taskana.impl.report; package pro.taskana.report;
/** /**
* A ReportColumnHeader is an element of a {@link Report}. * A ReportColumnHeader is an element of a {@link Report}.

View File

@ -1,4 +1,4 @@
package pro.taskana.impl.report; package pro.taskana.report;
/** /**
* A ReportRow represents a row in a {@link Report}. * A ReportRow represents a row in a {@link Report}.

View File

@ -0,0 +1,52 @@
package pro.taskana.report;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import pro.taskana.TaskState;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.TaskQueryItem;
import pro.taskana.impl.report.TaskStatusColumnHeader;
/**
* A TaskStatusReport contains the total number of tasks, clustered in their task status.
* Furthermore the report contains a sum line that contains the total numbers
* of the different clusters and the total number of all tasks.
*/
public class TaskStatusReport extends Report<TaskQueryItem, TaskStatusColumnHeader> {
public TaskStatusReport(List<TaskState> filter) {
super((filter != null ? filter.stream() : Stream.of(TaskState.values()))
.map(TaskStatusColumnHeader::new)
.collect(Collectors.toList()), "DOMAINS");
}
/**
* Builder for {@link TaskStatusReport}.
*/
public interface Builder extends Report.Builder<TaskQueryItem, TaskStatusColumnHeader> {
/**
* Adds a list of states to the builder. The created report contains only tasks with a state in this list.
*
* @param states
* a list of states
* @return the Builder
*/
Builder stateIn(List<TaskState> states);
/**
* Adds a list of domains to the builder. The created report contains only tasks with a domain in this list.
*
* @param domains
* a list of domains
* @return the Builder
*/
Builder domainIn(List<String> domains);
@Override
TaskStatusReport buildReport() throws NotAuthorizedException, InvalidArgumentException;
}
}

View File

@ -1,68 +1,67 @@
package pro.taskana; package pro.taskana.report;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import pro.taskana.CustomField;
import pro.taskana.TaskState;
import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.SelectedItem; import pro.taskana.impl.SelectedItem;
import pro.taskana.impl.report.impl.CategoryReport; import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; import pro.taskana.impl.report.TimeIntervalColumnHeader;
/** /**
* The CategoryReportBuilder is used to build a {@link CategoryReport}, list the taskIds of a CategoryReport and list * "Super" Interface for all TimeIntervalReportBuilders.
* the values of an entered custom field. A CategoryReport contains the total numbers of tasks of the respective * @param <B> the true Builder behind this Interface.
* category as well as the total number of all tasks. The tasks of the report can be filtered by workbaskets, states, * @param <H> the column Header
* categories, domains, classifications and values of a custom field. Classifications can also be excluded from the
* report. If the {@link TimeIntervalColumnHeader}s are set, the report 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 interface CategoryReportBuilder { public interface TimeIntervalReportBuilder<B extends TimeIntervalReportBuilder, H extends TimeIntervalColumnHeader>
extends Report.Builder<MonitorQueryItem, H> {
/** /**
* Adds a list {@link TimeIntervalColumnHeader}s to the builder to subdivide the report into clusters. * Adds a list {@link TimeIntervalColumnHeader}s to the builder to subdivide the report into clusters.
* *
* @param columnHeaders * @param columnHeaders
* the column headers the report should consist of. * the column headers the report should consist of.
* @return the CategoryReportBuilder * @return the TimeIntervalReportBuilder
*/ */
CategoryReportBuilder withColumnHeaders(List<TimeIntervalColumnHeader> columnHeaders); B withColumnHeaders(List<H> columnHeaders);
/** /**
* If this filter is used, the days of the report are counted in working days. * If this filter is used, the days of the report are counted in working days.
* *
* @return the CategoryReportBuilder * @return the TimeIntervalReportBuilder
*/ */
CategoryReportBuilder inWorkingDays(); B inWorkingDays();
/** /**
* Adds a list of workbasketIds to the builder. The created report contains only tasks with a workbasketId in this * Adds a list of workbasket ids to the builder. The created report contains only tasks with a workbasket id in this
* list. * list.
* *
* @param workbasketIds * @param workbasketIds
* a list of workbasketIds * a list of workbasket ids
* @return the CategoryReportBuilder * @return the TimeIntervalReportBuilder
*/ */
CategoryReportBuilder workbasketIdIn(List<String> workbasketIds); B workbasketIdIn(List<String> workbasketIds);
/** /**
* Adds a list of states to the builder. The created report contains only tasks with a state in this list. * Adds a list of states to the builder. The created report contains only tasks with a state in this list.
* *
* @param states * @param states
* a list of states * a list of states
* @return the CategoryReportBuilder * @return the TimeIntervalReportBuilder
*/ */
CategoryReportBuilder stateIn(List<TaskState> states); B stateIn(List<TaskState> states);
/** /**
* Adds a list of categories to the builder. The created report contains only tasks with a category in this list. * Adds a list of categories to the builder. The created report contains only tasks with a category in this list.
* *
* @param categories * @param categories
* a list of categories * a list of categories
* @return the CategoryReportBuilder * @return the TimeIntervalReportBuilder
*/ */
CategoryReportBuilder categoryIn(List<String> categories); B categoryIn(List<String> categories);
/** /**
* Adds a list of classificationIds to the builder. The created report contains only tasks with a classificationId * Adds a list of classificationIds to the builder. The created report contains only tasks with a classificationId
@ -70,9 +69,9 @@ public interface CategoryReportBuilder {
* *
* @param classificationIds * @param classificationIds
* a list of classificationIds * a list of classificationIds
* @return the CategoryReportBuilder * @return the TimeIntervalReportBuilder
*/ */
CategoryReportBuilder classificationIdIn(List<String> classificationIds); B classificationIdIn(List<String> classificationIds);
/** /**
* Adds a list of excludedClassificationIds to the builder. The created report contains only tasks with a * Adds a list of excludedClassificationIds to the builder. The created report contains only tasks with a
@ -80,18 +79,18 @@ public interface CategoryReportBuilder {
* *
* @param excludedClassificationIds * @param excludedClassificationIds
* a list of excludedClassificationIds * a list of excludedClassificationIds
* @return the CategoryReportBuilder * @return the TimeIntervalReportBuilder
*/ */
CategoryReportBuilder excludedClassificationIdIn(List<String> excludedClassificationIds); B excludedClassificationIdIn(List<String> excludedClassificationIds);
/** /**
* Adds a list of domains to the builder. The created report contains only tasks with a domain in this list. * Adds a list of domains to the builder. The created report contains only tasks with a domain in this list.
* *
* @param domains * @param domains
* a list of domains * a list of domains
* @return the CategoryReportBuilder * @return the TimeIntervalReportBuilder
*/ */
CategoryReportBuilder domainIn(List<String> domains); B domainIn(List<String> domains);
/** /**
* Adds a map of custom attributes and custom attribute values to the builder. The created report contains only * Adds a map of custom attributes and custom attribute values to the builder. The created report contains only
@ -99,21 +98,9 @@ public interface CategoryReportBuilder {
* *
* @param customAttributeFilter * @param customAttributeFilter
* a map of custom attributes and custom attribute value * a map of custom attributes and custom attribute value
* @return the CategoryReportBuilder * @return the TimeIntervalReportBuilder
*/ */
CategoryReportBuilder customAttributeFilterIn(Map<CustomField, String> customAttributeFilter); B customAttributeFilterIn(Map<CustomField, String> customAttributeFilter);
/**
* Returns a {@link CategoryReport} containing all tasks after applying the filters. If the column headers are set
* the report is subdivided into clusters.
*
* @throws InvalidArgumentException
* if the column headers are not initialized
* @throws NotAuthorizedException
* if the user has no rights to access the monitor
* @return the CategoryReport
*/
CategoryReport buildReport() throws InvalidArgumentException, NotAuthorizedException;
/** /**
* Returns a list of all taskIds of the report that are in the list of selected items. * Returns a list of all taskIds of the report that are in the list of selected items.
@ -140,4 +127,5 @@ public interface CategoryReportBuilder {
*/ */
List<String> listCustomAttributeValuesForCustomAttributeName(CustomField customField) List<String> listCustomAttributeValuesForCustomAttributeName(CustomField customField)
throws NotAuthorizedException; throws NotAuthorizedException;
} }

View File

@ -0,0 +1,46 @@
package pro.taskana.report;
import java.util.List;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.CombinedClassificationFilter;
import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
/**
* A WorkbasketReport contains the total numbers of tasks of the respective workbasket as well as the
* total number of all tasks. The tasks of the report can be filtered by workbaskets, states,
* categories, domains, classifications and values of a custom field. Classifications can also be excluded from the
* report. It is also possible to filter by the classifications of the attachments by using the
* {@link CombinedClassificationFilter}. If the {@link TimeIntervalColumnHeader}s are set, the report 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 WorkbasketReport extends Report<MonitorQueryItem, TimeIntervalColumnHeader> {
public WorkbasketReport(List<TimeIntervalColumnHeader> timeIntervalColumnHeaders) {
super(timeIntervalColumnHeaders, "WORKBASKET KEYS");
}
/**
* Builder for {@link WorkbasketReport}.
*/
public interface Builder extends TimeIntervalReportBuilder<Builder, TimeIntervalColumnHeader> {
@Override
WorkbasketReport buildReport() throws NotAuthorizedException, InvalidArgumentException;
/**
* Adds a list of {@link CombinedClassificationFilter} to the builder. The created report contains only tasks with a
* pair of a classificationId for a task and a classificationId for the corresponding attachment in this list.
*
* @param combinedClassificationFilter
* a list of combinedClassificationFilter
* @return the WorkbasketReportBuilder
*/
WorkbasketReport.Builder combinedClassificationFilterIn(
List<CombinedClassificationFilter> combinedClassificationFilter);
}
}

View File

@ -29,7 +29,7 @@ import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.exceptions.TaskNotFoundException; import pro.taskana.exceptions.TaskNotFoundException;
import pro.taskana.impl.DaysToWorkingDaysConverter; import pro.taskana.impl.DaysToWorkingDaysConverter;
import pro.taskana.impl.TaskImpl; import pro.taskana.impl.TaskImpl;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.jobs.JobRunner; import pro.taskana.jobs.JobRunner;
import pro.taskana.security.JAASRunner; import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId; import pro.taskana.security.WithAccessId;

View File

@ -31,7 +31,7 @@ import pro.taskana.impl.SelectedItem;
import pro.taskana.impl.TaskanaEngineImpl; import pro.taskana.impl.TaskanaEngineImpl;
import pro.taskana.impl.configuration.DBCleaner; import pro.taskana.impl.configuration.DBCleaner;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.security.JAASRunner; import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId; import pro.taskana.security.WithAccessId;

View File

@ -25,7 +25,7 @@ import pro.taskana.impl.SelectedItem;
import pro.taskana.impl.TaskanaEngineImpl; import pro.taskana.impl.TaskanaEngineImpl;
import pro.taskana.impl.configuration.DBCleaner; import pro.taskana.impl.configuration.DBCleaner;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.security.JAASRunner; import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId; import pro.taskana.security.WithAccessId;

View File

@ -31,7 +31,7 @@ import pro.taskana.impl.SelectedItem;
import pro.taskana.impl.TaskanaEngineImpl; import pro.taskana.impl.TaskanaEngineImpl;
import pro.taskana.impl.configuration.DBCleaner; import pro.taskana.impl.configuration.DBCleaner;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.security.JAASRunner; import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId; import pro.taskana.security.WithAccessId;

View File

@ -26,7 +26,7 @@ import pro.taskana.impl.SelectedItem;
import pro.taskana.impl.TaskanaEngineImpl; import pro.taskana.impl.TaskanaEngineImpl;
import pro.taskana.impl.configuration.DBCleaner; import pro.taskana.impl.configuration.DBCleaner;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.security.JAASRunner; import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId; import pro.taskana.security.WithAccessId;

View File

@ -34,8 +34,8 @@ import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.TaskanaEngineImpl; import pro.taskana.impl.TaskanaEngineImpl;
import pro.taskana.impl.configuration.DBCleaner; import pro.taskana.impl.configuration.DBCleaner;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.impl.report.impl.CategoryReport; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; import pro.taskana.report.CategoryReport;
import pro.taskana.security.JAASRunner; import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId; import pro.taskana.security.WithAccessId;

View File

@ -34,8 +34,8 @@ import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.TaskanaEngineImpl; import pro.taskana.impl.TaskanaEngineImpl;
import pro.taskana.impl.configuration.DBCleaner; import pro.taskana.impl.configuration.DBCleaner;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.impl.report.impl.ClassificationReport; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; import pro.taskana.report.ClassificationReport;
import pro.taskana.security.JAASRunner; import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId; import pro.taskana.security.WithAccessId;

View File

@ -32,8 +32,8 @@ import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.configuration.DBCleaner; import pro.taskana.impl.configuration.DBCleaner;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.impl.report.impl.CustomFieldValueReport; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; import pro.taskana.report.CustomFieldValueReport;
import pro.taskana.security.JAASRunner; import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId; import pro.taskana.security.WithAccessId;
@ -57,7 +57,8 @@ public class ProvideCustomFieldValueReportAccTest {
DBCleaner cleaner = new DBCleaner(); DBCleaner cleaner = new DBCleaner();
cleaner.clearDb(dataSource, true); cleaner.clearDb(dataSource, true);
dataSource = TaskanaEngineConfigurationTest.getDataSource(); dataSource = TaskanaEngineConfigurationTest.getDataSource();
taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false, TaskanaEngineConfigurationTest.getSchemaName()); taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false,
TaskanaEngineConfigurationTest.getSchemaName());
taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false); taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false);
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);

View File

@ -33,11 +33,11 @@ import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.TaskanaEngineImpl; import pro.taskana.impl.TaskanaEngineImpl;
import pro.taskana.impl.configuration.DBCleaner; import pro.taskana.impl.configuration.DBCleaner;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.impl.report.ReportRow; import pro.taskana.impl.report.DetailedMonitorQueryItem;
import pro.taskana.impl.report.impl.DetailedClassificationReport; import pro.taskana.impl.report.DetailedReportRow;
import pro.taskana.impl.report.impl.DetailedMonitorQueryItem; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.impl.DetailedReportRow; import pro.taskana.report.ClassificationReport.DetailedClassificationReport;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; import pro.taskana.report.ReportRow;
import pro.taskana.security.JAASRunner; import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId; import pro.taskana.security.WithAccessId;

View File

@ -23,13 +23,14 @@ import pro.taskana.TaskState;
import pro.taskana.TaskanaEngine; import pro.taskana.TaskanaEngine;
import pro.taskana.configuration.TaskanaEngineConfiguration; import pro.taskana.configuration.TaskanaEngineConfiguration;
import pro.taskana.database.TestDataGenerator; import pro.taskana.database.TestDataGenerator;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.configuration.DBCleaner; import pro.taskana.impl.configuration.DBCleaner;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.impl.report.ReportRow; import pro.taskana.impl.report.TaskQueryItem;
import pro.taskana.impl.report.impl.TaskQueryItem; import pro.taskana.impl.report.TaskStatusColumnHeader;
import pro.taskana.impl.report.impl.TaskStatusColumnHeader; import pro.taskana.report.ReportRow;
import pro.taskana.impl.report.impl.TaskStatusReport; import pro.taskana.report.TaskStatusReport;
import pro.taskana.security.JAASRunner; import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId; import pro.taskana.security.WithAccessId;
@ -64,7 +65,7 @@ public class ProvideTaskStatusReportAccTest {
} }
@Test(expected = NotAuthorizedException.class) @Test(expected = NotAuthorizedException.class)
public void testRoleCheck() throws NotAuthorizedException { public void testRoleCheck() throws NotAuthorizedException, InvalidArgumentException {
TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService();
taskMonitorService.createTaskStatusReportBuilder().buildReport(); taskMonitorService.createTaskStatusReportBuilder().buildReport();
} }
@ -72,7 +73,7 @@ public class ProvideTaskStatusReportAccTest {
@WithAccessId( @WithAccessId(
userName = "monitor") userName = "monitor")
@Test @Test
public void testCompleteTaskStatusReport() throws NotAuthorizedException { public void testCompleteTaskStatusReport() throws NotAuthorizedException, InvalidArgumentException {
// given // given
TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService();
// when // when
@ -104,7 +105,7 @@ public class ProvideTaskStatusReportAccTest {
@WithAccessId( @WithAccessId(
userName = "admin") userName = "admin")
@Test @Test
public void testCompleteTaskStatusReportAsAdmin() throws NotAuthorizedException { public void testCompleteTaskStatusReportAsAdmin() throws NotAuthorizedException, InvalidArgumentException {
TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService();
taskMonitorService.createTaskStatusReportBuilder().buildReport(); taskMonitorService.createTaskStatusReportBuilder().buildReport();
} }
@ -112,7 +113,7 @@ public class ProvideTaskStatusReportAccTest {
@WithAccessId( @WithAccessId(
userName = "monitor") userName = "monitor")
@Test @Test
public void testCompleteTaskStatusReportWithDomainFilter() throws NotAuthorizedException { public void testCompleteTaskStatusReportWithDomainFilter() throws NotAuthorizedException, InvalidArgumentException {
// given // given
TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService();
// when // when
@ -143,7 +144,7 @@ public class ProvideTaskStatusReportAccTest {
@WithAccessId( @WithAccessId(
userName = "monitor") userName = "monitor")
@Test @Test
public void testCompleteTaskStatusReportWithStateFilter() throws NotAuthorizedException { public void testCompleteTaskStatusReportWithStateFilter() throws NotAuthorizedException, InvalidArgumentException {
// given // given
TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService();
// when // when

View File

@ -33,9 +33,9 @@ import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.configuration.DBCleaner; import pro.taskana.impl.configuration.DBCleaner;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.impl.report.impl.CombinedClassificationFilter; import pro.taskana.impl.report.CombinedClassificationFilter;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.impl.WorkbasketReport; import pro.taskana.report.WorkbasketReport;
import pro.taskana.security.JAASRunner; import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId; import pro.taskana.security.WithAccessId;
@ -59,7 +59,8 @@ public class ProvideWorkbasketReportAccTest {
DBCleaner cleaner = new DBCleaner(); DBCleaner cleaner = new DBCleaner();
cleaner.clearDb(dataSource, true); cleaner.clearDb(dataSource, true);
dataSource = TaskanaEngineConfigurationTest.getDataSource(); dataSource = TaskanaEngineConfigurationTest.getDataSource();
taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false, TaskanaEngineConfigurationTest.getSchemaName()); taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false,
TaskanaEngineConfigurationTest.getSchemaName());
taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false); taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false);
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);

View File

@ -33,7 +33,7 @@ import pro.taskana.exceptions.WorkbasketNotFoundException;
import pro.taskana.impl.DaysToWorkingDaysConverter; import pro.taskana.impl.DaysToWorkingDaysConverter;
import pro.taskana.impl.TaskanaEngineImpl; import pro.taskana.impl.TaskanaEngineImpl;
import pro.taskana.impl.TaskanaEngineProxyForTest; import pro.taskana.impl.TaskanaEngineProxyForTest;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.mappings.AttachmentMapper; import pro.taskana.mappings.AttachmentMapper;
import pro.taskana.mappings.TaskTestMapper; import pro.taskana.mappings.TaskTestMapper;
import pro.taskana.security.CurrentUserContext; import pro.taskana.security.CurrentUserContext;

View File

@ -34,7 +34,7 @@ import pro.taskana.exceptions.WorkbasketNotFoundException;
import pro.taskana.impl.AttachmentImpl; import pro.taskana.impl.AttachmentImpl;
import pro.taskana.impl.DaysToWorkingDaysConverter; import pro.taskana.impl.DaysToWorkingDaysConverter;
import pro.taskana.impl.TaskImpl; import pro.taskana.impl.TaskImpl;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.security.CurrentUserContext; import pro.taskana.security.CurrentUserContext;
import pro.taskana.security.JAASRunner; import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId; import pro.taskana.security.WithAccessId;

View File

@ -31,10 +31,10 @@ import pro.taskana.TaskState;
import pro.taskana.configuration.TaskanaEngineConfiguration; import pro.taskana.configuration.TaskanaEngineConfiguration;
import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.impl.CategoryReport; import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.impl.MonitorQueryItem; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader;
import pro.taskana.mappings.TaskMonitorMapper; import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.CategoryReport;
/** /**
* Unit Test for CategoryBuilderImpl. * Unit Test for CategoryBuilderImpl.

View File

@ -31,13 +31,13 @@ import pro.taskana.TaskState;
import pro.taskana.configuration.TaskanaEngineConfiguration; import pro.taskana.configuration.TaskanaEngineConfiguration;
import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.impl.ClassificationReport; import pro.taskana.impl.report.DetailedMonitorQueryItem;
import pro.taskana.impl.report.impl.DetailedClassificationReport; import pro.taskana.impl.report.DetailedReportRow;
import pro.taskana.impl.report.impl.DetailedMonitorQueryItem; import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.impl.DetailedReportRow; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.impl.MonitorQueryItem;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader;
import pro.taskana.mappings.TaskMonitorMapper; import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.ClassificationReport;
import pro.taskana.report.ClassificationReport.DetailedClassificationReport;
/** /**
* Unit Test for ClassificationReportBuilderImpl. * Unit Test for ClassificationReportBuilderImpl.

View File

@ -30,10 +30,10 @@ import pro.taskana.TaskState;
import pro.taskana.configuration.TaskanaEngineConfiguration; import pro.taskana.configuration.TaskanaEngineConfiguration;
import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.impl.CustomFieldValueReport; import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.impl.MonitorQueryItem; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader;
import pro.taskana.mappings.TaskMonitorMapper; import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.CustomFieldValueReport;
/** /**
* Unit Test for CustomFieldValueReportBuilderImpl. * Unit Test for CustomFieldValueReportBuilderImpl.

View File

@ -15,7 +15,7 @@ import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; import pro.taskana.impl.report.TimeIntervalColumnHeader;
/** /**
* Test for the DaysToWorkingDaysConverter. * Test for the DaysToWorkingDaysConverter.

View File

@ -23,10 +23,11 @@ import org.mockito.junit.MockitoJUnitRunner;
import pro.taskana.TaskState; import pro.taskana.TaskState;
import pro.taskana.configuration.TaskanaEngineConfiguration; import pro.taskana.configuration.TaskanaEngineConfiguration;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.impl.TaskQueryItem; import pro.taskana.impl.report.TaskQueryItem;
import pro.taskana.impl.report.impl.TaskStatusReport;
import pro.taskana.mappings.TaskMonitorMapper; import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.TaskStatusReport;
/** /**
* Unit Test for TaskStatusReportBuilderImpl. * Unit Test for TaskStatusReportBuilderImpl.
@ -54,7 +55,7 @@ public class TaskStatusReportBuilderImplTest {
} }
@Test @Test
public void testGetTaskStateReportWithoutFilters() throws NotAuthorizedException { public void testGetTaskStateReportWithoutFilters() throws NotAuthorizedException, InvalidArgumentException {
// given // given
TaskQueryItem queryItem1 = new TaskQueryItem(); TaskQueryItem queryItem1 = new TaskQueryItem();
queryItem1.setCount(50); queryItem1.setCount(50);
@ -85,7 +86,7 @@ public class TaskStatusReportBuilderImplTest {
} }
@Test @Test
public void testGetTotalNumberOfTaskStateReport() throws NotAuthorizedException { public void testGetTotalNumberOfTaskStateReport() throws NotAuthorizedException, InvalidArgumentException {
// given // given
TaskQueryItem queryItem1 = new TaskQueryItem(); TaskQueryItem queryItem1 = new TaskQueryItem();
queryItem1.setCount(50); queryItem1.setCount(50);

View File

@ -31,11 +31,11 @@ import pro.taskana.TaskState;
import pro.taskana.configuration.TaskanaEngineConfiguration; import pro.taskana.configuration.TaskanaEngineConfiguration;
import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.impl.CombinedClassificationFilter; import pro.taskana.impl.report.CombinedClassificationFilter;
import pro.taskana.impl.report.impl.MonitorQueryItem; import pro.taskana.impl.report.MonitorQueryItem;
import pro.taskana.impl.report.impl.TimeIntervalColumnHeader; import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.impl.report.impl.WorkbasketReport;
import pro.taskana.mappings.TaskMonitorMapper; import pro.taskana.mappings.TaskMonitorMapper;
import pro.taskana.report.WorkbasketReport;
/** /**
* Unit Test for WorkbasketReportBuilderImpl. * Unit Test for WorkbasketReportBuilderImpl.

View File

@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.RestController;
import pro.taskana.TaskMonitorService; import pro.taskana.TaskMonitorService;
import pro.taskana.TaskState; import pro.taskana.TaskState;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.rest.resource.ReportResource; import pro.taskana.rest.resource.ReportResource;
import pro.taskana.rest.resource.assembler.ReportAssembler; import pro.taskana.rest.resource.assembler.ReportAssembler;
@ -71,7 +72,8 @@ public class MonitorController {
@GetMapping(path = "/taskStatusReport") @GetMapping(path = "/taskStatusReport")
@Transactional(readOnly = true, rollbackFor = Exception.class) @Transactional(readOnly = true, rollbackFor = Exception.class)
public ResponseEntity<ReportResource> getTaskStatusReport(@RequestParam(required = false) List<String> domains, public ResponseEntity<ReportResource> getTaskStatusReport(@RequestParam(required = false) List<String> domains,
@RequestParam(required = false) List<TaskState> states) throws NotAuthorizedException { @RequestParam(required = false) List<TaskState> states) throws NotAuthorizedException,
InvalidArgumentException {
// return ResponseEntity.status(HttpStatus.OK) // return ResponseEntity.status(HttpStatus.OK)
// .body(reportAssembler.toResource(taskMonitorService.getTaskStatusReport(domains, states), domains, states)); // .body(reportAssembler.toResource(taskMonitorService.getTaskStatusReport(domains, states), domains, states));
return ResponseEntity.status(HttpStatus.OK) return ResponseEntity.status(HttpStatus.OK)

View File

@ -5,7 +5,7 @@ import java.util.Map;
import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.ResourceSupport;
/** /**
* Resource class for {@link pro.taskana.impl.report.Report}. * Resource class for {@link pro.taskana.report.Report}.
*/ */
public class ReportResource extends ResourceSupport { public class ReportResource extends ResourceSupport {
@ -74,7 +74,7 @@ public class ReportResource extends ResourceSupport {
} }
/** /**
* Resource class for {@link pro.taskana.impl.report.ReportRow}. * Resource class for {@link pro.taskana.report.ReportRow}.
*/ */
public static class RowResource { public static class RowResource {

View File

@ -12,12 +12,13 @@ import java.util.stream.Collectors;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import pro.taskana.TaskState; import pro.taskana.TaskState;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.QueryItem; import pro.taskana.report.QueryItem;
import pro.taskana.impl.report.Report; import pro.taskana.report.Report;
import pro.taskana.impl.report.ReportColumnHeader; import pro.taskana.report.ReportColumnHeader;
import pro.taskana.impl.report.ReportRow; import pro.taskana.report.ReportRow;
import pro.taskana.impl.report.impl.TaskStatusReport; import pro.taskana.report.TaskStatusReport;
import pro.taskana.rest.MonitorController; import pro.taskana.rest.MonitorController;
import pro.taskana.rest.resource.ReportResource; import pro.taskana.rest.resource.ReportResource;
@ -28,7 +29,7 @@ import pro.taskana.rest.resource.ReportResource;
public class ReportAssembler { public class ReportAssembler {
public ReportResource toResource(TaskStatusReport report, List<String> domains, List<TaskState> states) public ReportResource toResource(TaskStatusReport report, List<String> domains, List<TaskState> states)
throws NotAuthorizedException { throws NotAuthorizedException, InvalidArgumentException {
ReportResource resource = toResource(report); ReportResource resource = toResource(report);
resource.add( resource.add(
linkTo(methodOn(MonitorController.class).getTaskStatusReport(domains, states)) linkTo(methodOn(MonitorController.class).getTaskStatusReport(domains, states))