Compare commits
4 Commits
Author | SHA1 | Date |
---|---|---|
Robert von Burg | 3054d5fca5 | |
Robert von Burg | 19825b37a8 | |
Robert von Burg | c65c6624fb | |
Robert von Burg | 4d7b3faf3f |
|
@ -91,12 +91,12 @@ public class Report implements AutoCloseable {
|
|||
return this.reportPolicy.doReportWithPage(offset, limit);
|
||||
}
|
||||
|
||||
public MapOfSets<String, StrolchRootElement> generateFilterCriteria(int limit) {
|
||||
public MapOfSets<String, JsonObject> generateFilterCriteria(int limit) {
|
||||
return this.reportPolicy.generateFilterCriteria(limit);
|
||||
}
|
||||
|
||||
public Stream<StrolchRootElement> generateFilterCriteria(String type) {
|
||||
return this.reportPolicy.generateFilterCriteria(type);
|
||||
public Stream<JsonObject> generateFilterCriteria(String type, int limit, String query) {
|
||||
return this.reportPolicy.generateFilterCriteria(type,limit, query);
|
||||
}
|
||||
|
||||
public long getCounter() {
|
||||
|
|
|
@ -1,17 +1,5 @@
|
|||
package li.strolch.report.policy;
|
||||
|
||||
import static java.util.Comparator.comparing;
|
||||
import static java.util.Comparator.comparingInt;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static li.strolch.model.StrolchModelConstants.*;
|
||||
import static li.strolch.report.ReportConstants.*;
|
||||
import static li.strolch.utils.helper.StringHelper.EMPTY;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import li.strolch.model.*;
|
||||
import li.strolch.model.parameter.AbstractParameter;
|
||||
|
@ -33,6 +21,20 @@ import li.strolch.utils.collections.TypedTuple;
|
|||
import li.strolch.utils.dbc.DBC;
|
||||
import li.strolch.utils.iso8601.ISO8601;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.text.MessageFormat.format;
|
||||
import static java.util.Comparator.comparing;
|
||||
import static java.util.Comparator.comparingInt;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static li.strolch.model.StrolchModelConstants.*;
|
||||
import static li.strolch.report.ReportConstants.*;
|
||||
import static li.strolch.utils.ObjectHelper.*;
|
||||
import static li.strolch.utils.helper.StringHelper.EMPTY;
|
||||
|
||||
/**
|
||||
* A Generic Report defines a report as is described at <a href="https://strolch.li/documentation-reports.html">Strolch
|
||||
* Reports</a>
|
||||
|
@ -88,9 +90,11 @@ public class GenericReport extends ReportPolicy {
|
|||
|
||||
this.columnsBag = this.reportRes.getParameterBag(BAG_COLUMNS, true);
|
||||
|
||||
this.columnIds = this.columnsBag.getParameters().stream() //
|
||||
.sorted(comparingInt(Parameter::getIndex)) //
|
||||
.map(StrolchElement::getId) //
|
||||
this.columnIds = this.columnsBag
|
||||
.getParameters()
|
||||
.stream()
|
||||
.sorted(comparingInt(Parameter::getIndex))
|
||||
.map(StrolchElement::getId)
|
||||
.collect(toList());
|
||||
|
||||
this.parallel = this.reportRes.getBoolean(PARAM_PARALLEL);
|
||||
|
@ -167,36 +171,21 @@ public class GenericReport extends ReportPolicy {
|
|||
List<ParameterBag> filterBags = this.reportRes.getParameterBagsByType(TYPE_FILTER);
|
||||
for (ParameterBag filterBag : filterBags) {
|
||||
|
||||
if (filterBag.hasParameter(PARAM_FIELD_REF) && (filterBag.hasParameter(PARAM_FIELD_REF1)
|
||||
|| filterBag.hasParameter(PARAM_FIELD_REF2))) {
|
||||
throw new IllegalArgumentException("Filter "
|
||||
+ filterBag.getLocator()
|
||||
+ " can not have combination of "
|
||||
+ PARAM_FIELD_REF
|
||||
+ " and any of "
|
||||
+ PARAM_FIELD_REF1
|
||||
+ ", "
|
||||
+ PARAM_FIELD_REF2);
|
||||
if (filterBag.hasParameter(PARAM_FIELD_REF) && (
|
||||
filterBag.hasParameter(PARAM_FIELD_REF1) || filterBag.hasParameter(PARAM_FIELD_REF2))) {
|
||||
throw new IllegalArgumentException(
|
||||
format("Filter {0} can not have combination of {1} and any of {2}, {3}", filterBag.getLocator(),
|
||||
PARAM_FIELD_REF, PARAM_FIELD_REF1, PARAM_FIELD_REF2));
|
||||
} else if ((filterBag.hasParameter(PARAM_FIELD_REF1) && !filterBag.hasParameter(PARAM_FIELD_REF2))
|
||||
|| (!filterBag.hasParameter(PARAM_FIELD_REF1) && filterBag.hasParameter(PARAM_FIELD_REF2))) {
|
||||
throw new IllegalArgumentException("Filter "
|
||||
+ filterBag.getLocator()
|
||||
+ " must have both "
|
||||
+ PARAM_FIELD_REF1
|
||||
+ " and "
|
||||
+ PARAM_FIELD_REF2);
|
||||
} else if (!filterBag.hasParameter(PARAM_FIELD_REF) && (!filterBag.hasParameter(PARAM_FIELD_REF1)
|
||||
|| !filterBag.hasParameter(
|
||||
PARAM_FIELD_REF2))) {
|
||||
throw new IllegalArgumentException("Filter "
|
||||
+ filterBag.getLocator()
|
||||
+ " is missing the "
|
||||
+ PARAM_FIELD_REF
|
||||
+ " or "
|
||||
+ PARAM_FIELD_REF1
|
||||
+ ", "
|
||||
+ PARAM_FIELD_REF2
|
||||
+ " combination!");
|
||||
throw new IllegalArgumentException(
|
||||
format("Filter {0} must have both {1} and {2}", filterBag.getLocator(), PARAM_FIELD_REF1,
|
||||
PARAM_FIELD_REF2));
|
||||
} else if (!filterBag.hasParameter(PARAM_FIELD_REF) && (
|
||||
!filterBag.hasParameter(PARAM_FIELD_REF1) || !filterBag.hasParameter(PARAM_FIELD_REF2))) {
|
||||
throw new IllegalArgumentException(
|
||||
format("Filter {0} is missing the {1} or {2}, {3} combination!", filterBag.getLocator(),
|
||||
PARAM_FIELD_REF, PARAM_FIELD_REF1, PARAM_FIELD_REF2));
|
||||
}
|
||||
|
||||
// prepare filter function policy
|
||||
|
@ -379,7 +368,7 @@ public class GenericReport extends ReportPolicy {
|
|||
Stream<Map<String, StrolchRootElement>> stream;
|
||||
|
||||
// query the main objects and return a stream
|
||||
stream = queryRows() //
|
||||
stream = queryRows()
|
||||
|
||||
// transform each element into a map of Type,Value pairs
|
||||
.map(this::evaluateRow);
|
||||
|
@ -458,10 +447,9 @@ public class GenericReport extends ReportPolicy {
|
|||
StringParameter joinParamP = additionalTypeBag.getStringP(PARAM_JOIN_PARAM);
|
||||
String[] locatorParts = joinParamP.getValue().split(Locator.PATH_SEPARATOR);
|
||||
if (locatorParts.length != 3)
|
||||
throw new IllegalStateException("Parameter reference ("
|
||||
+ joinParamP.getValue()
|
||||
+ ") is invalid as it does not have 3 parts for "
|
||||
+ joinParamP.getLocator());
|
||||
throw new IllegalStateException(
|
||||
format("Parameter reference ({0}) is invalid as it does not have 3 parts for {1}",
|
||||
joinParamP.getValue(), joinParamP.getLocator()));
|
||||
String bagKey = locatorParts[1];
|
||||
String paramKey = locatorParts[2];
|
||||
|
||||
|
@ -476,19 +464,15 @@ public class GenericReport extends ReportPolicy {
|
|||
|
||||
StrolchRootElement joinElement = row.get(joinWithP.getUom());
|
||||
if (joinElement == null)
|
||||
throw new IllegalStateException("Additional join type "
|
||||
+ joinWithP.getUom()
|
||||
+ " is not available on row for "
|
||||
+ joinWithP.getLocator());
|
||||
throw new IllegalStateException(
|
||||
format("Additional join type {0} is not available on row for {1}", joinWithP.getUom(),
|
||||
joinWithP.getLocator()));
|
||||
|
||||
Optional<Parameter<?>> refP = lookupParameter(joinWithP, joinElement, false);
|
||||
if (refP.isEmpty()) {
|
||||
throw new IllegalStateException("Parameter reference ("
|
||||
+ joinWithP.getValue()
|
||||
+ ") for "
|
||||
+ joinWithP.getLocator()
|
||||
+ " not found on "
|
||||
+ joinElement.getLocator());
|
||||
throw new IllegalStateException(
|
||||
format("Parameter reference ({0}) for {1} not found on {2}", joinWithP.getValue(),
|
||||
joinWithP.getLocator(), joinElement.getLocator()));
|
||||
}
|
||||
|
||||
StringParameter joinP = (StringParameter) refP.get();
|
||||
|
@ -520,14 +504,12 @@ public class GenericReport extends ReportPolicy {
|
|||
protected String formatColumn(Map<String, StrolchRootElement> row, String columnId) {
|
||||
StringParameter columnDefP = this.columnsBag.getParameter(columnId, true);
|
||||
Object value = evaluateColumnValue(columnDefP, row, false);
|
||||
if (value instanceof ZonedDateTime) {
|
||||
return ISO8601.toString((ZonedDateTime) value);
|
||||
} else if (value instanceof Date) {
|
||||
return ISO8601.toString((Date) value);
|
||||
} else if (value instanceof Parameter) {
|
||||
return formatColumn((Parameter<?>) value);
|
||||
} else
|
||||
return value.toString();
|
||||
return switch (value) {
|
||||
case ZonedDateTime zonedDateTime -> ISO8601.toString(zonedDateTime);
|
||||
case Date date -> ISO8601.toString(date);
|
||||
case Parameter<?> parameter -> formatColumn(parameter);
|
||||
default -> value.toString();
|
||||
};
|
||||
}
|
||||
|
||||
protected String formatColumn(Parameter<?> param) {
|
||||
|
@ -570,76 +552,29 @@ public class GenericReport extends ReportPolicy {
|
|||
* @return the filter criteria as a map of sets
|
||||
*/
|
||||
@Override
|
||||
public MapOfSets<String, StrolchRootElement> generateFilterCriteria(int limit) {
|
||||
public MapOfSets<String, JsonObject> generateFilterCriteria(int limit) {
|
||||
int maxFacetValues = getMaxFacetValues(limit);
|
||||
|
||||
if (limit <= 0 || limit >= MAX_FACET_VALUE_LIMIT) {
|
||||
logger.warn("Overriding invalid limit " + limit + " with " + MAX_FACET_VALUE_LIMIT);
|
||||
limit = 100;
|
||||
}
|
||||
|
||||
int maxFacetValues;
|
||||
int reportMaxFacetValues = this.reportRes.getInteger(PARAM_MAX_FACET_VALUES);
|
||||
if (reportMaxFacetValues != 0 && reportMaxFacetValues != limit) {
|
||||
logger.warn("Report "
|
||||
+ this.reportRes.getId()
|
||||
+ " has "
|
||||
+ PARAM_MAX_FACET_VALUES
|
||||
+ " defined as "
|
||||
+ reportMaxFacetValues
|
||||
+ ". Ignoring requested limit "
|
||||
+ limit);
|
||||
maxFacetValues = reportMaxFacetValues;
|
||||
} else {
|
||||
maxFacetValues = limit;
|
||||
}
|
||||
|
||||
MapOfSets<String, StrolchRootElement> result = new MapOfSets<>(true);
|
||||
MapOfSets<String, JsonObject> result = new MapOfSets<>(true);
|
||||
|
||||
// we need the list of possible element types, which designate the criteria
|
||||
List<String> criteria = this.filterCriteriaParams.values().stream() //
|
||||
.filter(p -> {
|
||||
if (p.getUom().equals(UOM_NONE))
|
||||
throw new IllegalStateException(
|
||||
"Join UOM " + p.getUom() + " invalid: " + p.getId() + " for " + p.getLocator());
|
||||
if (p.getId().equals(PARAM_OBJECT_TYPE))
|
||||
return filterCriteriaAllowed(p.getUom());
|
||||
return filterCriteriaAllowed(p.getId());
|
||||
}) //
|
||||
.sorted(comparing(StringParameter::getIndex)) //
|
||||
.map(StringParameter::getUom) //
|
||||
.collect(toList());
|
||||
List<String> criteria = this.filterCriteriaParams.values().stream().filter(p -> {
|
||||
if (p.getUom().equals(UOM_NONE))
|
||||
throw new IllegalStateException(
|
||||
format("Join UOM {0} invalid: {1} for {2}", p.getUom(), p.getId(), p.getLocator()));
|
||||
if (p.getId().equals(PARAM_OBJECT_TYPE))
|
||||
return filterCriteriaAllowed(p.getUom());
|
||||
return filterCriteriaAllowed(p.getId());
|
||||
}).sorted(comparing(StringParameter::getIndex)).map(StringParameter::getUom).collect(toList());
|
||||
criteria.addAll(this.directCriteria);
|
||||
|
||||
int maxRowsForFacetGeneration = this.reportRes.getInteger(PARAM_MAX_ROWS_FOR_FACET_GENERATION);
|
||||
|
||||
if (!this.directCriteria.isEmpty()) {
|
||||
criteria.forEach(type -> {
|
||||
if (!this.directCriteria.contains(type))
|
||||
return;
|
||||
StringParameter filterCriteriaP = this.filterCriteriaParams.get(type);
|
||||
if (filterCriteriaP == null) {
|
||||
logger.warn("Filter criteria not found for " + type);
|
||||
return;
|
||||
}
|
||||
Stream<? extends StrolchRootElement> stream = switch (filterCriteriaP.getInterpretation()) {
|
||||
case INTERPRETATION_RESOURCE_REF -> tx().streamResources(filterCriteriaP.getUom());
|
||||
case INTERPRETATION_ORDER_REF -> tx().streamOrders(filterCriteriaP.getUom());
|
||||
case INTERPRETATION_ACTIVITY_REF -> tx().streamActivities(filterCriteriaP.getUom());
|
||||
default -> throw new IllegalArgumentException("Unhandled filter criteria interpretation "
|
||||
+ filterCriteriaP.getInterpretation()
|
||||
+ " for "
|
||||
+ filterCriteriaP.getLocator());
|
||||
};
|
||||
|
||||
stream = stream.map(this::mapFilterCriteria).filter(this::filterDirectCriteria);
|
||||
|
||||
if (hasOrdering())
|
||||
stream = stream.sorted(this::sortDirectCriteria);
|
||||
|
||||
if (maxFacetValues > 0)
|
||||
stream = stream.limit(maxFacetValues);
|
||||
|
||||
stream.forEachOrdered(e -> result.addElement(e.getType(), e));
|
||||
if (this.directCriteria.contains(type))
|
||||
prepareStreamForDirectCriteria(type, maxFacetValues).forEachOrdered(
|
||||
e -> result.addElement(e.getType(), mapCriteriaToJson(e)));
|
||||
});
|
||||
|
||||
criteria.removeAll(this.directCriteria);
|
||||
|
@ -656,7 +591,7 @@ public class GenericReport extends ReportPolicy {
|
|||
|
||||
for (String criterion : criteria) {
|
||||
if (row.containsKey(criterion) && result.size(criterion) < maxFacetValues)
|
||||
result.addElement(criterion, row.get(criterion));
|
||||
result.addElement(criterion, mapCriteriaToJson(row.get(criterion)));
|
||||
}
|
||||
|
||||
// stop if we have enough data
|
||||
|
@ -671,13 +606,80 @@ public class GenericReport extends ReportPolicy {
|
|||
return result;
|
||||
}
|
||||
|
||||
protected StrolchRootElement mapFilterCriteria(StrolchRootElement element) {
|
||||
return element;
|
||||
@Override
|
||||
public Stream<JsonObject> generateFilterCriteria(String type, int limit, String query) {
|
||||
int maxFacetValues = getMaxFacetValues(limit);
|
||||
|
||||
Stream<StrolchRootElement> stream;
|
||||
if (this.directCriteria.contains(type)) {
|
||||
stream = prepareStreamForDirectCriteria(type, 0).map(e -> (StrolchRootElement) e);
|
||||
} else {
|
||||
stream = buildStream().filter(row -> row.containsKey(type)).map(row -> row.get(type)).distinct();
|
||||
}
|
||||
|
||||
Stream<JsonObject> resultStream = filterAndMapFilterCriteria(stream, query);
|
||||
if (maxFacetValues != 0)
|
||||
resultStream = resultStream.limit(maxFacetValues);
|
||||
return resultStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<StrolchRootElement> generateFilterCriteria(String type) {
|
||||
return buildStream().filter(row -> row.containsKey(type)).map(row -> row.get(type)).distinct();
|
||||
protected Stream<JsonObject> filterAndMapFilterCriteria(Stream<StrolchRootElement> stream, String query) {
|
||||
Stream<JsonObject> resultStream = stream.map(this::mapCriteriaToJson);
|
||||
String[] queryParts = query == null || query.isEmpty() ? null : query.split(" ");
|
||||
if (queryParts != null)
|
||||
resultStream = resultStream.filter(f -> contains(f.get(Tags.Json.NAME).getAsString(), queryParts, true));
|
||||
return resultStream;
|
||||
}
|
||||
|
||||
protected JsonObject mapCriteriaToJson(StrolchRootElement criterion) {
|
||||
JsonObject result = new JsonObject();
|
||||
result.addProperty(Tags.Json.ID, criterion.getId());
|
||||
result.addProperty(Tags.Json.NAME, criterion.getName());
|
||||
return result;
|
||||
}
|
||||
|
||||
protected Stream<? extends StrolchRootElement> prepareStreamForDirectCriteria(String type, int maxFacetValues) {
|
||||
StringParameter filterCriteriaP = this.filterCriteriaParams.get(type);
|
||||
if (filterCriteriaP == null) {
|
||||
logger.warn("Filter criteria not found for {}", type);
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
Stream<? extends StrolchRootElement> stream = switch (filterCriteriaP.getInterpretation()) {
|
||||
case INTERPRETATION_RESOURCE_REF -> tx().streamResources(filterCriteriaP.getUom());
|
||||
case INTERPRETATION_ORDER_REF -> tx().streamOrders(filterCriteriaP.getUom());
|
||||
case INTERPRETATION_ACTIVITY_REF -> tx().streamActivities(filterCriteriaP.getUom());
|
||||
default -> throw new IllegalArgumentException(
|
||||
format("Unhandled filter criteria interpretation {0} for {1}", filterCriteriaP.getInterpretation(),
|
||||
filterCriteriaP.getLocator()));
|
||||
};
|
||||
|
||||
stream = stream.filter(this::filterDirectCriteria);
|
||||
|
||||
if (hasOrdering())
|
||||
stream = stream.sorted(this::sortDirectCriteria);
|
||||
|
||||
if (maxFacetValues > 0)
|
||||
stream = stream.limit(maxFacetValues);
|
||||
return stream;
|
||||
}
|
||||
|
||||
private int getMaxFacetValues(int limit) {
|
||||
if (limit <= 0 || limit >= MAX_FACET_VALUE_LIMIT) {
|
||||
logger.warn("Overriding invalid limit {} with " + MAX_FACET_VALUE_LIMIT, limit);
|
||||
limit = 100;
|
||||
}
|
||||
|
||||
int maxFacetValues;
|
||||
int reportMaxFacetValues = this.reportRes.getInteger(PARAM_MAX_FACET_VALUES);
|
||||
if (reportMaxFacetValues != 0 && reportMaxFacetValues != limit) {
|
||||
logger.warn("Report {} has " + PARAM_MAX_FACET_VALUES + " defined as {}. Ignoring requested limit {}",
|
||||
this.reportRes.getId(), reportMaxFacetValues, limit);
|
||||
maxFacetValues = reportMaxFacetValues;
|
||||
} else {
|
||||
maxFacetValues = limit;
|
||||
}
|
||||
return maxFacetValues;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -705,31 +707,9 @@ public class GenericReport extends ReportPolicy {
|
|||
|
||||
int sortVal;
|
||||
if (fieldRefP.getValue().startsWith("$")) {
|
||||
Object columnValue1 = evaluateColumnValue(fieldRefP, Map.of(column1.getType(), column1), false);
|
||||
Object columnValue2 = evaluateColumnValue(fieldRefP, Map.of(column2.getType(), column2), false);
|
||||
|
||||
if (this.descending) {
|
||||
sortVal = ObjectHelper.compare(columnValue2, columnValue1, true);
|
||||
} else {
|
||||
sortVal = ObjectHelper.compare(columnValue1, columnValue2, true);
|
||||
}
|
||||
|
||||
sortVal = compareFieldRef(fieldRefP, column1, column2);
|
||||
} else {
|
||||
Optional<Parameter<?>> param1 = lookupParameter(fieldRefP, column1, false);
|
||||
Optional<Parameter<?>> param2 = lookupParameter(fieldRefP, column2, false);
|
||||
|
||||
if (param1.isEmpty() && param2.isEmpty())
|
||||
continue;
|
||||
|
||||
if (param1.isPresent() && param2.isEmpty())
|
||||
return 1;
|
||||
else if (param1.isEmpty())
|
||||
return -1;
|
||||
|
||||
if (this.descending)
|
||||
sortVal = param2.get().compareTo(param1.get());
|
||||
else
|
||||
sortVal = param1.get().compareTo(param2.get());
|
||||
sortVal = compareParamFieldRefP(fieldRefP, column1, column2);
|
||||
}
|
||||
|
||||
if (sortVal != 0)
|
||||
|
@ -765,31 +745,9 @@ public class GenericReport extends ReportPolicy {
|
|||
|
||||
int sortVal;
|
||||
if (fieldRefP.getValue().startsWith("$")) {
|
||||
Object columnValue1 = evaluateColumnValue(fieldRefP, row1, false);
|
||||
Object columnValue2 = evaluateColumnValue(fieldRefP, row2, false);
|
||||
|
||||
if (this.descending) {
|
||||
sortVal = ObjectHelper.compare(columnValue2, columnValue1, true);
|
||||
} else {
|
||||
sortVal = ObjectHelper.compare(columnValue1, columnValue2, true);
|
||||
}
|
||||
|
||||
sortVal = compareFieldRef(fieldRefP, row1, row2);
|
||||
} else {
|
||||
Optional<Parameter<?>> param1 = lookupParameter(fieldRefP, column1, false);
|
||||
Optional<Parameter<?>> param2 = lookupParameter(fieldRefP, column2, false);
|
||||
|
||||
if (param1.isEmpty() && param2.isEmpty())
|
||||
continue;
|
||||
|
||||
if (param1.isPresent() && param2.isEmpty())
|
||||
return 1;
|
||||
else if (param1.isEmpty())
|
||||
return -1;
|
||||
|
||||
if (this.descending)
|
||||
sortVal = param2.get().compareTo(param1.get());
|
||||
else
|
||||
sortVal = param1.get().compareTo(param2.get());
|
||||
sortVal = compareParamFieldRefP(fieldRefP, column1, column2);
|
||||
}
|
||||
|
||||
if (sortVal != 0)
|
||||
|
@ -799,6 +757,41 @@ public class GenericReport extends ReportPolicy {
|
|||
return 0;
|
||||
}
|
||||
|
||||
private int compareFieldRef(StringParameter fieldRefP, Map<String, StrolchRootElement> row1,
|
||||
Map<String, StrolchRootElement> row2) {
|
||||
Object columnValue1 = evaluateColumnValue(fieldRefP, row1, false);
|
||||
Object columnValue2 = evaluateColumnValue(fieldRefP, row2, false);
|
||||
if (this.descending)
|
||||
return compare(columnValue2, columnValue1, true);
|
||||
return compare(columnValue1, columnValue2, true);
|
||||
}
|
||||
|
||||
private int compareFieldRef(StringParameter fieldRefP, StrolchRootElement column1, StrolchRootElement column2) {
|
||||
Object columnValue1 = evaluateColumnValue(fieldRefP, Map.of(column1.getType(), column1), false);
|
||||
Object columnValue2 = evaluateColumnValue(fieldRefP, Map.of(column2.getType(), column2), false);
|
||||
if (this.descending)
|
||||
return compare(columnValue2, columnValue1, true);
|
||||
return compare(columnValue1, columnValue2, true);
|
||||
}
|
||||
|
||||
private int compareParamFieldRefP(StringParameter fieldRefP, StrolchRootElement column1,
|
||||
StrolchRootElement column2) {
|
||||
Optional<Parameter<?>> param1 = lookupParameter(fieldRefP, column1, false);
|
||||
Optional<Parameter<?>> param2 = lookupParameter(fieldRefP, column2, false);
|
||||
|
||||
if (param1.isEmpty() && param2.isEmpty())
|
||||
return 0;
|
||||
|
||||
if (param1.isPresent() && param2.isEmpty())
|
||||
return 1;
|
||||
else if (param1.isEmpty())
|
||||
return -1;
|
||||
|
||||
if (this.descending)
|
||||
return param2.get().compareTo(param1.get());
|
||||
return param1.get().compareTo(param2.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a filter is defined, i.e. {@link ParameterBag ParameterBags} of type
|
||||
* {@link ReportConstants#TYPE_FILTER}, a date range
|
||||
|
@ -806,8 +799,8 @@ public class GenericReport extends ReportPolicy {
|
|||
* @return true if a filter is defined
|
||||
*/
|
||||
protected boolean hasFilter() {
|
||||
return !this.filtersByPolicy.isEmpty() || this.dateRange != null || (this.filtersById != null
|
||||
&& !this.filtersById.isEmpty());
|
||||
return !this.filtersByPolicy.isEmpty() || this.dateRange != null || (
|
||||
this.filtersById != null && !this.filtersById.isEmpty());
|
||||
}
|
||||
|
||||
protected boolean filterDirectCriteria(StrolchRootElement element) {
|
||||
|
@ -893,7 +886,7 @@ public class GenericReport extends ReportPolicy {
|
|||
Optional<Parameter<?>> param = lookupParameter(this.dateRangeSelP, element, false);
|
||||
if (param.isEmpty() || param.get().getValueType() != StrolchValueType.DATE)
|
||||
throw new IllegalStateException(
|
||||
"Date Range selector is invalid, as referenced parameter is not a Date but " + (
|
||||
format("Date Range selector is invalid, as referenced parameter is not a Date but {0}",
|
||||
param.isPresent() ? param.get().getValueType() : "null"));
|
||||
|
||||
date = ((DateParameter) param.get()).getValueZdt();
|
||||
|
@ -961,8 +954,8 @@ public class GenericReport extends ReportPolicy {
|
|||
else
|
||||
columnValue = parameter;
|
||||
} else {
|
||||
columnValue = lookupParameter(columnDefP, column, allowNull) //
|
||||
.orElseGet(() -> allowNull ? null : new StringParameter(columnDefP.getValue(), columnDef, ""));
|
||||
columnValue = lookupParameter(columnDefP, column, allowNull).orElseGet(
|
||||
() -> allowNull ? null : new StringParameter(columnDefP.getValue(), columnDef, ""));
|
||||
}
|
||||
|
||||
return columnValue;
|
||||
|
@ -982,20 +975,18 @@ public class GenericReport extends ReportPolicy {
|
|||
|
||||
String[] searchParts = columnDef.split(SEARCH_SEPARATOR);
|
||||
if (searchParts.length != 3)
|
||||
throw new IllegalStateException("Parameter search reference ("
|
||||
+ columnDef
|
||||
+ ") is invalid as it does not have 3 parts for "
|
||||
+ columnDefP.getLocator());
|
||||
throw new IllegalStateException(
|
||||
format("Parameter search reference ({0}) is invalid as it does not have 3 parts for {1}", columnDef,
|
||||
columnDefP.getLocator()));
|
||||
|
||||
String parentParamId = searchParts[1];
|
||||
String paramRef = searchParts[2];
|
||||
|
||||
String[] locatorParts = paramRef.split(Locator.PATH_SEPARATOR);
|
||||
if (locatorParts.length != 3)
|
||||
throw new IllegalStateException("Parameter search reference ("
|
||||
+ paramRef
|
||||
+ ") is invalid as it does not have 3 parts for "
|
||||
+ columnDefP.getLocator());
|
||||
throw new IllegalStateException(
|
||||
format("Parameter search reference ({0}) is invalid as it does not have 3 parts for {1}", paramRef,
|
||||
columnDefP.getLocator()));
|
||||
|
||||
String bagKey = locatorParts[1];
|
||||
String paramKey = locatorParts[2];
|
||||
|
@ -1018,22 +1009,18 @@ public class GenericReport extends ReportPolicy {
|
|||
|
||||
String[] locatorParts = paramRef.split(Locator.PATH_SEPARATOR);
|
||||
if (locatorParts.length != 3)
|
||||
throw new IllegalStateException("Parameter reference ("
|
||||
+ paramRef
|
||||
+ ") is invalid as it does not have 3 parts for "
|
||||
+ paramRefP.getLocator());
|
||||
throw new IllegalStateException(
|
||||
format("Parameter reference ({0}) is invalid as it does not have 3 parts for {1}", paramRef,
|
||||
paramRefP.getLocator()));
|
||||
|
||||
String bagKey = locatorParts[1];
|
||||
String paramKey = locatorParts[2];
|
||||
|
||||
Parameter<?> param = element.getParameter(bagKey, paramKey);
|
||||
if (!overrideAllowMissingColumns && !this.allowMissingColumns && param == null)
|
||||
throw new IllegalStateException("Parameter reference ("
|
||||
+ paramRef
|
||||
+ ") for "
|
||||
+ paramRefP.getLocator()
|
||||
+ " not found on "
|
||||
+ element.getLocator());
|
||||
throw new IllegalStateException(
|
||||
format("Parameter reference ({0}) for {1} not found on {2}", paramRef, paramRefP.getLocator(),
|
||||
element.getLocator()));
|
||||
|
||||
return Optional.ofNullable(param);
|
||||
}
|
||||
|
@ -1058,15 +1045,17 @@ public class GenericReport extends ReportPolicy {
|
|||
}
|
||||
|
||||
protected boolean hasJoinOnType(String type) {
|
||||
return (this.reportRes.hasParameterBag(BAG_JOINS) //
|
||||
&& this.reportRes.getParameterBag(BAG_JOINS).hasParameter(type)) //
|
||||
|| (this.reportRes.hasParameterBag(BAG_ADDITIONAL_TYPE) //
|
||||
&& this.reportRes
|
||||
.getParameterBag(BAG_ADDITIONAL_TYPE)
|
||||
.getString(PARAM_OBJECT_TYPE)
|
||||
.equals(type)) //
|
||||
|| (this.reportRes.hasParameterBag(BAG_ADDITIONAL_JOINS) //
|
||||
&& this.reportRes.getParameterBag(BAG_ADDITIONAL_JOINS).hasParameter(type));
|
||||
return (
|
||||
this.reportRes.hasParameterBag(BAG_JOINS) && this.reportRes
|
||||
.getParameterBag(BAG_JOINS)
|
||||
.hasParameter(type)) || (
|
||||
this.reportRes.hasParameterBag(BAG_ADDITIONAL_TYPE) && this.reportRes
|
||||
.getParameterBag(BAG_ADDITIONAL_TYPE)
|
||||
.getString(PARAM_OBJECT_TYPE)
|
||||
.equals(type)) || (
|
||||
this.reportRes.hasParameterBag(BAG_ADDITIONAL_JOINS) && this.reportRes
|
||||
.getParameterBag(BAG_ADDITIONAL_JOINS)
|
||||
.hasParameter(type));
|
||||
}
|
||||
|
||||
protected Stream<? extends StrolchRootElement> getStreamFor(StringParameter objectTypeP) {
|
||||
|
@ -1146,38 +1135,7 @@ public class GenericReport extends ReportPolicy {
|
|||
return null;
|
||||
}
|
||||
|
||||
ParameterBag relationsBag = dependency.getParameterBag(BAG_RELATIONS);
|
||||
if (relationsBag == null)
|
||||
throw new IllegalStateException("Invalid join definition value: "
|
||||
+ joinP.getValue()
|
||||
+ " on: "
|
||||
+ joinP.getLocator()
|
||||
+ " as "
|
||||
+ dependency.getLocator()
|
||||
+ " has no ParameterBag "
|
||||
+ BAG_RELATIONS);
|
||||
|
||||
List<Parameter<?>> relationParams = relationsBag
|
||||
.getParametersByInterpretationAndUom(interpretation, joinType)
|
||||
.stream()
|
||||
.filter(p -> p.getValueType() == StrolchValueType.STRING)
|
||||
.toList();
|
||||
|
||||
if (relationParams.isEmpty())
|
||||
throw new IllegalStateException("Found no relation parameters with UOM "
|
||||
+ joinType
|
||||
+ " of type "
|
||||
+ StrolchValueType.STRING.getType()
|
||||
+ " on dependency "
|
||||
+ dependency.getLocator());
|
||||
if (relationParams.size() > 1)
|
||||
throw new IllegalStateException("Found multiple possible relation parameters for UOM "
|
||||
+ joinType
|
||||
+ " on dependency "
|
||||
+ dependency.getLocator());
|
||||
|
||||
Parameter<?> relationParam = relationParams.get(0);
|
||||
StringParameter relationP = (StringParameter) relationParam;
|
||||
StringParameter relationP = getJoinRelationParam(dependency, joinP, joinType, interpretation);
|
||||
if (relationP.getValue().isEmpty() && optional)
|
||||
return null;
|
||||
|
||||
|
@ -1189,4 +1147,33 @@ public class GenericReport extends ReportPolicy {
|
|||
refs.put(joinType, joinElem);
|
||||
return joinElem;
|
||||
}
|
||||
|
||||
private static StringParameter getJoinRelationParam(StrolchRootElement dependency, StringParameter joinP,
|
||||
String joinType, String interpretation) {
|
||||
|
||||
ParameterBag relationsBag = dependency.getParameterBag(BAG_RELATIONS);
|
||||
if (relationsBag == null)
|
||||
throw new IllegalStateException(
|
||||
format("Invalid join definition value: {0} on: {1} as {2} has no ParameterBag {3}",
|
||||
joinP.getValue(), joinP.getLocator(), dependency.getLocator(), BAG_RELATIONS));
|
||||
|
||||
List<Parameter<?>> relationParams = relationsBag
|
||||
.getParametersByInterpretationAndUom(interpretation, joinType)
|
||||
.stream()
|
||||
.filter(p -> p.getValueType() == StrolchValueType.STRING)
|
||||
.toList();
|
||||
|
||||
if (relationParams.isEmpty())
|
||||
throw new IllegalStateException(
|
||||
format("Found no relation parameters with UOM {0} of type {1} on dependency {2}", joinType,
|
||||
StrolchValueType.STRING.getType(), dependency.getLocator()));
|
||||
if (relationParams.size() > 1)
|
||||
throw new IllegalStateException("Found multiple possible relation parameters for UOM "
|
||||
+ joinType
|
||||
+ " on dependency "
|
||||
+ dependency.getLocator());
|
||||
|
||||
Parameter<?> relationParam = relationParams.getFirst();
|
||||
return (StringParameter) relationParam;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
package li.strolch.report.policy;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import li.strolch.model.Resource;
|
||||
import li.strolch.model.StrolchRootElement;
|
||||
|
@ -14,6 +9,11 @@ import li.strolch.report.ReportElement;
|
|||
import li.strolch.utils.collections.DateRange;
|
||||
import li.strolch.utils.collections.MapOfSets;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public abstract class ReportPolicy extends StrolchPolicy {
|
||||
|
||||
public ReportPolicy(StrolchTransaction tx) {
|
||||
|
@ -48,9 +48,9 @@ public abstract class ReportPolicy extends StrolchPolicy {
|
|||
|
||||
public abstract Stream<ReportElement> doReportWithPage(int offset, int limit);
|
||||
|
||||
public abstract MapOfSets<String, StrolchRootElement> generateFilterCriteria(int limit);
|
||||
public abstract MapOfSets<String, JsonObject> generateFilterCriteria(int limit);
|
||||
|
||||
public abstract Stream<StrolchRootElement> generateFilterCriteria(String type);
|
||||
public abstract Stream<JsonObject> generateFilterCriteria(String type, int limit, String query);
|
||||
|
||||
public abstract long getCounter();
|
||||
|
||||
|
|
|
@ -1,18 +1,7 @@
|
|||
package li.strolch.report;
|
||||
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import li.strolch.model.StrolchElement;
|
||||
import li.strolch.model.StrolchRootElement;
|
||||
import li.strolch.model.Tags;
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
import li.strolch.privilege.model.Certificate;
|
||||
import li.strolch.testbase.runtime.RuntimeMock;
|
||||
|
@ -23,6 +12,16 @@ import org.junit.AfterClass;
|
|||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class GenericReportTest {
|
||||
|
||||
private static final String RUNTIME_PATH = "target/GenericReportTest/";
|
||||
|
@ -48,49 +47,49 @@ public class GenericReportTest {
|
|||
public void shouldGenerateJsonReport() {
|
||||
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, true);
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
|
||||
report.doReportAsJson() //
|
||||
.forEach(e -> {
|
||||
|
||||
switch (e.get("slot").getAsString()) {
|
||||
case "Slot 1" -> {
|
||||
assertEquals("Product 01", e.get("product").getAsString());
|
||||
assertEquals("20.0", e.get("quantity").getAsString());
|
||||
assertEquals("40.0", e.get("maxQuantity").getAsString());
|
||||
assertEquals("4.0", e.get("minQuantity").getAsString());
|
||||
assertEquals("Section 001", e.get("section").getAsString());
|
||||
assertEquals("Storage 01", e.get("storage").getAsString());
|
||||
assertEquals("Location 01", e.get("location").getAsString());
|
||||
}
|
||||
case "Slot 2" -> {
|
||||
assertEquals("Product 02", e.get("product").getAsString());
|
||||
assertEquals("18.0", e.get("quantity").getAsString());
|
||||
assertEquals("20.0", e.get("maxQuantity").getAsString());
|
||||
assertEquals("4.0", e.get("minQuantity").getAsString());
|
||||
assertEquals("Section 001", e.get("section").getAsString());
|
||||
assertEquals("Storage 01", e.get("storage").getAsString());
|
||||
assertEquals("Location 01", e.get("location").getAsString());
|
||||
}
|
||||
case "Slot 3" -> {
|
||||
assertEquals("Product 01", e.get("product").getAsString());
|
||||
assertEquals("11.0", e.get("quantity").getAsString());
|
||||
assertEquals("40.0", e.get("maxQuantity").getAsString());
|
||||
assertEquals("6.0", e.get("minQuantity").getAsString());
|
||||
assertEquals("Section 002", e.get("section").getAsString());
|
||||
assertEquals("Storage 02", e.get("storage").getAsString());
|
||||
assertEquals("Location 02", e.get("location").getAsString());
|
||||
}
|
||||
case "Slot 4" -> {
|
||||
assertEquals("Product 02", e.get("product").getAsString());
|
||||
assertEquals("16.0", e.get("quantity").getAsString());
|
||||
assertEquals("20.0", e.get("maxQuantity").getAsString());
|
||||
assertEquals("6.0", e.get("minQuantity").getAsString());
|
||||
assertEquals("Section 002", e.get("section").getAsString());
|
||||
assertEquals("Storage 02", e.get("storage").getAsString());
|
||||
assertEquals("Location 02", e.get("location").getAsString());
|
||||
}
|
||||
default -> fail("Unhandled result element: \n" + e);
|
||||
case "Slot 1" -> {
|
||||
assertEquals("Product 01", e.get("product").getAsString());
|
||||
assertEquals("20.0", e.get("quantity").getAsString());
|
||||
assertEquals("40.0", e.get("maxQuantity").getAsString());
|
||||
assertEquals("4.0", e.get("minQuantity").getAsString());
|
||||
assertEquals("Section 001", e.get("section").getAsString());
|
||||
assertEquals("Storage 01", e.get("storage").getAsString());
|
||||
assertEquals("Location 01", e.get("location").getAsString());
|
||||
}
|
||||
case "Slot 2" -> {
|
||||
assertEquals("Product 02", e.get("product").getAsString());
|
||||
assertEquals("18.0", e.get("quantity").getAsString());
|
||||
assertEquals("20.0", e.get("maxQuantity").getAsString());
|
||||
assertEquals("4.0", e.get("minQuantity").getAsString());
|
||||
assertEquals("Section 001", e.get("section").getAsString());
|
||||
assertEquals("Storage 01", e.get("storage").getAsString());
|
||||
assertEquals("Location 01", e.get("location").getAsString());
|
||||
}
|
||||
case "Slot 3" -> {
|
||||
assertEquals("Product 01", e.get("product").getAsString());
|
||||
assertEquals("11.0", e.get("quantity").getAsString());
|
||||
assertEquals("40.0", e.get("maxQuantity").getAsString());
|
||||
assertEquals("6.0", e.get("minQuantity").getAsString());
|
||||
assertEquals("Section 002", e.get("section").getAsString());
|
||||
assertEquals("Storage 02", e.get("storage").getAsString());
|
||||
assertEquals("Location 02", e.get("location").getAsString());
|
||||
}
|
||||
case "Slot 4" -> {
|
||||
assertEquals("Product 02", e.get("product").getAsString());
|
||||
assertEquals("16.0", e.get("quantity").getAsString());
|
||||
assertEquals("20.0", e.get("maxQuantity").getAsString());
|
||||
assertEquals("6.0", e.get("minQuantity").getAsString());
|
||||
assertEquals("Section 002", e.get("section").getAsString());
|
||||
assertEquals("Storage 02", e.get("storage").getAsString());
|
||||
assertEquals("Location 02", e.get("location").getAsString());
|
||||
}
|
||||
default -> fail("Unhandled result element: \n" + e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -100,7 +99,7 @@ public class GenericReportTest {
|
|||
public void shouldFilterReport1() {
|
||||
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, true);
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
|
||||
report.filter("Product", "product01") //
|
||||
.doReportAsJson() //
|
||||
|
@ -108,12 +107,12 @@ public class GenericReportTest {
|
|||
|
||||
String slotName = e.get("slot").getAsString();
|
||||
switch (slotName) {
|
||||
case "Slot 1":
|
||||
case "Slot 3":
|
||||
break;
|
||||
default:
|
||||
fail("Unexpected slot name " + slotName + ", should have been filtered!");
|
||||
break;
|
||||
case "Slot 1":
|
||||
case "Slot 3":
|
||||
break;
|
||||
default:
|
||||
fail("Unexpected slot name " + slotName + ", should have been filtered!");
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -123,7 +122,7 @@ public class GenericReportTest {
|
|||
public void shouldFilterReport2() {
|
||||
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, true);
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
|
||||
report.filter("Product", "product01") //
|
||||
.filter("Location", "location02") //
|
||||
|
@ -144,7 +143,7 @@ public class GenericReportTest {
|
|||
Date from = new Date(LocalDate.of(2016, 1, 1).toEpochDay() * 86400000);
|
||||
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, true);
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
|
||||
Date to = new Date(LocalDate.of(2017, 1, 1).toEpochDay() * 86400000);
|
||||
DateRange dateRange = new DateRange().from(from, true).to(to, false);
|
||||
|
@ -158,7 +157,7 @@ public class GenericReportTest {
|
|||
}
|
||||
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, true);
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
|
||||
Date to = new Date(LocalDate.of(2017, 3, 1).toEpochDay() * 86400000);
|
||||
DateRange dateRange = new DateRange().from(from, true).to(to, false);
|
||||
|
@ -185,7 +184,10 @@ public class GenericReportTest {
|
|||
Date to = new Date(LocalDate.of(2017, 1, 1).toEpochDay() * 86400000);
|
||||
DateRange dateRange = new DateRange().from(from, true).to(to, false);
|
||||
|
||||
List<JsonObject> result = report.filter("Product", "product01").dateRange(dateRange).doReportAsJson()
|
||||
List<JsonObject> result = report
|
||||
.filter("Product", "product01")
|
||||
.dateRange(dateRange)
|
||||
.doReportAsJson()
|
||||
.toList();
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
@ -196,7 +198,10 @@ public class GenericReportTest {
|
|||
Date to = new Date(LocalDate.of(2017, 3, 1).toEpochDay() * 86400000);
|
||||
DateRange dateRange = new DateRange().from(from, true).to(to, false);
|
||||
|
||||
List<JsonObject> result = report.filter("Product", "product01").dateRange(dateRange).doReportAsJson()
|
||||
List<JsonObject> result = report
|
||||
.filter("Product", "product01")
|
||||
.dateRange(dateRange)
|
||||
.doReportAsJson()
|
||||
.toList();
|
||||
assertEquals(2, result.size());
|
||||
}
|
||||
|
@ -207,8 +212,11 @@ public class GenericReportTest {
|
|||
Date to = new Date(LocalDate.of(2017, 3, 2).toEpochDay() * 86400000);
|
||||
DateRange dateRange = new DateRange().from(from, true).to(to, false);
|
||||
|
||||
List<JsonObject> result = report.filter("Product", "product01", "product02").dateRange(dateRange)
|
||||
.doReportAsJson().toList();
|
||||
List<JsonObject> result = report
|
||||
.filter("Product", "product01", "product02")
|
||||
.dateRange(dateRange)
|
||||
.doReportAsJson()
|
||||
.toList();
|
||||
assertEquals(4, result.size());
|
||||
}
|
||||
}
|
||||
|
@ -218,21 +226,27 @@ public class GenericReportTest {
|
|||
public void shouldCreateFilterCriteria() {
|
||||
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, true);
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
|
||||
MapOfSets<String, StrolchRootElement> filterCriteria = report.generateFilterCriteria(1000);
|
||||
MapOfSets<String, JsonObject> filterCriteria = report.generateFilterCriteria(1000);
|
||||
|
||||
assertFalse(filterCriteria.containsSet("Location"));
|
||||
assertFalse(filterCriteria.containsSet("Slot"));
|
||||
MatcherAssert
|
||||
.assertThat(filterCriteria.getSet("Product").stream().map(StrolchElement::getId).collect(toSet()),
|
||||
containsInAnyOrder("product01", "product02"));
|
||||
MatcherAssert
|
||||
.assertThat(filterCriteria.getSet("Storage").stream().map(StrolchElement::getId).collect(toSet()),
|
||||
containsInAnyOrder("storage01", "storage02"));
|
||||
MatcherAssert
|
||||
.assertThat(filterCriteria.getSet("Section").stream().map(StrolchElement::getId).collect(toSet()),
|
||||
containsInAnyOrder("section001", "section002"));
|
||||
MatcherAssert.assertThat(filterCriteria
|
||||
.getSet("Product")
|
||||
.stream()
|
||||
.map(e -> e.get(Tags.Json.ID).getAsString())
|
||||
.collect(toSet()), containsInAnyOrder("product01", "product02"));
|
||||
MatcherAssert.assertThat(filterCriteria
|
||||
.getSet("Storage")
|
||||
.stream()
|
||||
.map(e -> e.get(Tags.Json.ID).getAsString())
|
||||
.collect(toSet()), containsInAnyOrder("storage01", "storage02"));
|
||||
MatcherAssert.assertThat(filterCriteria
|
||||
.getSet("Section")
|
||||
.stream()
|
||||
.map(e -> e.get(Tags.Json.ID).getAsString())
|
||||
.collect(toSet()), containsInAnyOrder("section001", "section002"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -240,9 +254,10 @@ public class GenericReportTest {
|
|||
public void shouldCreateFilterCriteriaFiltered1() {
|
||||
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, true);
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
|
||||
MapOfSets<String, StrolchRootElement> filterCriteria = report.filter("Product", "product01")
|
||||
MapOfSets<String, JsonObject> filterCriteria = report
|
||||
.filter("Product", "product01")
|
||||
.generateFilterCriteria(1000);
|
||||
|
||||
// assert sequence of filter criteria is correct
|
||||
|
@ -254,15 +269,21 @@ public class GenericReportTest {
|
|||
|
||||
assertFalse(filterCriteria.containsSet("Location"));
|
||||
assertFalse(filterCriteria.containsSet("Slot"));
|
||||
MatcherAssert
|
||||
.assertThat(filterCriteria.getSet("Product").stream().map(StrolchElement::getId).collect(toSet()),
|
||||
containsInAnyOrder("product01"));
|
||||
MatcherAssert
|
||||
.assertThat(filterCriteria.getSet("Storage").stream().map(StrolchElement::getId).collect(toSet()),
|
||||
containsInAnyOrder("storage01", "storage02"));
|
||||
MatcherAssert
|
||||
.assertThat(filterCriteria.getSet("Section").stream().map(StrolchElement::getId).collect(toSet()),
|
||||
containsInAnyOrder("section001", "section002"));
|
||||
MatcherAssert.assertThat(filterCriteria
|
||||
.getSet("Product")
|
||||
.stream()
|
||||
.map(e -> e.get(Tags.Json.ID).getAsString())
|
||||
.collect(toSet()), containsInAnyOrder("product01"));
|
||||
MatcherAssert.assertThat(filterCriteria
|
||||
.getSet("Storage")
|
||||
.stream()
|
||||
.map(e -> e.get(Tags.Json.ID).getAsString())
|
||||
.collect(toSet()), containsInAnyOrder("storage01", "storage02"));
|
||||
MatcherAssert.assertThat(filterCriteria
|
||||
.getSet("Section")
|
||||
.stream()
|
||||
.map(e -> e.get(Tags.Json.ID).getAsString())
|
||||
.collect(toSet()), containsInAnyOrder("section001", "section002"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -270,13 +291,13 @@ public class GenericReportTest {
|
|||
public void shouldCreateFilterCriteriaFiltered2() {
|
||||
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, true);
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
Report report = new Report(tx, "stockReport")) {
|
||||
|
||||
Date from = new Date(LocalDate.of(2017, 3, 1).toEpochDay() * 86400000);
|
||||
Date to = new Date(LocalDate.of(2017, 3, 5).toEpochDay() * 86400000);
|
||||
DateRange dateRange = new DateRange().from(from, true).to(to, false);
|
||||
|
||||
MapOfSets<String, StrolchRootElement> filterCriteria = report //
|
||||
MapOfSets<String, JsonObject> filterCriteria = report //
|
||||
.dateRange(dateRange) //
|
||||
.filter("Product", "product01") //
|
||||
.generateFilterCriteria(1000);
|
||||
|
@ -289,26 +310,26 @@ public class GenericReportTest {
|
|||
public void shouldDoAdditionalJoin() {
|
||||
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, true);
|
||||
Report report = new Report(tx, "slotsByOrderUsageReport")) {
|
||||
Report report = new Report(tx, "slotsByOrderUsageReport")) {
|
||||
|
||||
AtomicInteger slotsFound = new AtomicInteger();
|
||||
report.doReportAsJson().forEach(e -> {
|
||||
|
||||
switch (e.get("slot").getAsString()) {
|
||||
case "Slot 1", "Slot 3" -> {
|
||||
assertEquals("Harry", e.get("firstName").getAsString());
|
||||
assertEquals("Barns", e.get("lastName").getAsString());
|
||||
slotsFound.getAndIncrement();
|
||||
}
|
||||
case "Slot 2", "Slot 4", "Slot 5" -> {
|
||||
assertEquals("Geoffrey", e.get("firstName").getAsString());
|
||||
assertEquals("Bobcat", e.get("lastName").getAsString());
|
||||
slotsFound.getAndIncrement();
|
||||
}
|
||||
case "Slot 6" -> {
|
||||
assertEquals("", e.get("firstName").getAsString());
|
||||
slotsFound.getAndIncrement();
|
||||
}
|
||||
case "Slot 1", "Slot 3" -> {
|
||||
assertEquals("Harry", e.get("firstName").getAsString());
|
||||
assertEquals("Barns", e.get("lastName").getAsString());
|
||||
slotsFound.getAndIncrement();
|
||||
}
|
||||
case "Slot 2", "Slot 4", "Slot 5" -> {
|
||||
assertEquals("Geoffrey", e.get("firstName").getAsString());
|
||||
assertEquals("Bobcat", e.get("lastName").getAsString());
|
||||
slotsFound.getAndIncrement();
|
||||
}
|
||||
case "Slot 6" -> {
|
||||
assertEquals("", e.get("firstName").getAsString());
|
||||
slotsFound.getAndIncrement();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -104,8 +104,8 @@ public class I18nMessage {
|
|||
|
||||
} catch (MissingResourceException e) {
|
||||
if (!missingKeysMap.containsSet(baseName + "_" + locale.toLanguageTag())) {
|
||||
logger.error("Failed to find resource bundle " + baseName + " " + locale.toLanguageTag()
|
||||
+ ", returning current bundle " + this.bundle.getLocale().toLanguageTag());
|
||||
logger.error("Failed to find resource bundle {} {}, returning current bundle {}", baseName,
|
||||
locale.toLanguageTag(), this.bundle.getLocale().toLanguageTag());
|
||||
missingKeysMap.addSet(baseName + "_" + locale.toLanguageTag(), emptySet());
|
||||
}
|
||||
return this.bundle;
|
||||
|
@ -123,10 +123,10 @@ public class I18nMessage {
|
|||
if (isEmpty(this.bundleName))
|
||||
return getMessage();
|
||||
if (!missingKeysMap.containsSet(this.bundleName + "_" + locale.toLanguageTag())) {
|
||||
logger.warn("No bundle found for " + this.bundleName + " " + locale + ". Available are: ");
|
||||
logger.warn("No bundle found for {} {}. Available are: ", this.bundleName, locale);
|
||||
getBundleMap().forEach((s, map) -> {
|
||||
logger.info(" " + s);
|
||||
map.forEach((l, resourceBundle) -> logger.info(" " + l + ": " + map.keySet()));
|
||||
logger.info(" {}", s);
|
||||
map.forEach((l, resourceBundle) -> logger.info(" {}: {}", l, map.keySet()));
|
||||
});
|
||||
missingKeysMap.addSet(this.bundleName + "_" + locale.toLanguageTag(), emptySet());
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ public class I18nMessage {
|
|||
String languageTag = bundle.getLocale().toLanguageTag();
|
||||
String bundleKey = baseName + "_" + languageTag;
|
||||
if (!missingKeysMap.containsElement(bundleKey, this.key)) {
|
||||
logger.error("Key " + this.key + " is missing in bundle " + baseName + " for locale " + languageTag);
|
||||
logger.error("Key {} is missing in bundle {} for locale {}", this.key, baseName, languageTag);
|
||||
missingKeysMap.addElement(bundleKey, this.key);
|
||||
}
|
||||
|
||||
|
@ -265,14 +265,14 @@ public class I18nMessage {
|
|||
try {
|
||||
CodeSource src = I18nMessage.class.getProtectionDomain().getCodeSource();
|
||||
if (src == null) {
|
||||
logger.error(
|
||||
"Failed to find CodeSource for ProtectionDomain " + I18nMessage.class.getProtectionDomain());
|
||||
logger.error("Failed to find CodeSource for ProtectionDomain {}",
|
||||
I18nMessage.class.getProtectionDomain());
|
||||
return;
|
||||
}
|
||||
|
||||
File jarLocationF = new File(src.getLocation().toURI());
|
||||
if (!(jarLocationF.exists() && jarLocationF.getParentFile().isDirectory())) {
|
||||
logger.info("Found JAR repository at " + jarLocationF.getParentFile());
|
||||
logger.info("Found JAR repository at {}", jarLocationF.getParentFile());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -292,16 +292,10 @@ public class I18nMessage {
|
|||
JarEntry je = entries.nextElement();
|
||||
|
||||
String entryName = je.getName();
|
||||
|
||||
if (entryName.startsWith("META-INF") //
|
||||
|| entryName.equals("ENV.properties") //
|
||||
|| entryName.equals("agentVersion.properties") //
|
||||
|| entryName.equals("appVersion.properties") //
|
||||
|| entryName.equals("componentVersion.properties") //
|
||||
|| entryName.equals("strolch_db_version.properties"))
|
||||
if (!entryName.endsWith(".properties"))
|
||||
continue;
|
||||
|
||||
if (!entryName.endsWith(".properties"))
|
||||
if (shouldIgnorePropertyFile(entryName))
|
||||
continue;
|
||||
|
||||
TypedTuple<String, Locale> tuple = parsePropertyName(entryName);
|
||||
|
@ -316,23 +310,21 @@ public class I18nMessage {
|
|||
bundleMap.addElement(bundle.getBaseBundleName(), bundle.getLocale(), bundle);
|
||||
|
||||
String propertyName = entryName.replace('/', '.');
|
||||
logger.info(
|
||||
" Loaded bundle " + bundle.getBaseBundleName() + " " + bundle.getLocale() + " from "
|
||||
+ propertyName + " from JAR " + file.getName());
|
||||
logger.info(" Loaded bundle {} {} from {} from JAR {}", bundle.getBaseBundleName(),
|
||||
bundle.getLocale(), propertyName, file.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File classesD = new File(jarD.getParentFile(), "classes");
|
||||
if (classesD.isDirectory()) {
|
||||
File[] propertyFiles = classesD.listFiles(
|
||||
(dir, name) -> name.endsWith(".properties") && !(name.equals("appVersion.properties")
|
||||
|| name.equals("ENV.properties")));
|
||||
File[] propertyFiles = classesD.listFiles((dir, name) -> name.endsWith(".properties") && !(
|
||||
name.equals("appVersion.properties") || name.equals("ENV.properties")));
|
||||
if (propertyFiles != null) {
|
||||
for (File propertyFile : propertyFiles) {
|
||||
|
||||
logger.info(" Found property file " + propertyFile.getName() + " in classes "
|
||||
+ classesD.getAbsolutePath());
|
||||
logger.info(" Found property file {} in classes {}", propertyFile.getName(),
|
||||
classesD.getAbsolutePath());
|
||||
|
||||
TypedTuple<String, Locale> tuple = parsePropertyName(propertyFile.getName());
|
||||
if (tuple == null)
|
||||
|
@ -346,8 +338,8 @@ public class I18nMessage {
|
|||
}
|
||||
|
||||
bundleMap.addElement(bundle.getBaseBundleName(), bundle.getLocale(), bundle);
|
||||
logger.info(" Loaded bundle " + bundle.getBaseBundleName() + " " + bundle.getLocale()
|
||||
+ " from file " + propertyFile.getName());
|
||||
logger.info(" Loaded bundle {} {} from file {}", bundle.getBaseBundleName(),
|
||||
bundle.getLocale(), propertyFile.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -378,17 +370,17 @@ public class I18nMessage {
|
|||
int languageI = Arrays.binarySearch(Locale.getISOLanguages(), language);
|
||||
int countryI = Arrays.binarySearch(Locale.getISOCountries(), country);
|
||||
if (languageI >= 0 && countryI >= 0)
|
||||
locale = new Locale(language, country);
|
||||
locale = Locale.of(language, country);
|
||||
else {
|
||||
logger.warn("Ignoring bad bundle locale for " + entryName);
|
||||
logger.warn("Ignoring malformed bad bundle locale for {}", entryName);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
int languageI = Arrays.binarySearch(Locale.getISOLanguages(), localeS);
|
||||
if (languageI >= 0)
|
||||
locale = new Locale(localeS);
|
||||
locale = Locale.forLanguageTag(localeS);
|
||||
else {
|
||||
logger.warn("Ignoring bad bundle locale for " + entryName);
|
||||
logger.warn("Ignoring bad bundle locale for {}", entryName);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -401,6 +393,7 @@ public class I18nMessage {
|
|||
}
|
||||
|
||||
private static class CustomControl extends ResourceBundle.Control {
|
||||
|
||||
private final InputStream stream;
|
||||
|
||||
public CustomControl(InputStream stream) {
|
||||
|
@ -414,65 +407,76 @@ public class I18nMessage {
|
|||
}
|
||||
}
|
||||
|
||||
private static boolean shouldIgnorePropertyFile(String name) {
|
||||
return name.startsWith("META-INF")
|
||||
|| name.equals("ENV.properties")
|
||||
|| name.equals("agentVersion.properties")
|
||||
|| name.equals("appVersion.properties")
|
||||
|| name.equals("componentVersion.properties")
|
||||
|| name.contains("_db_version");
|
||||
}
|
||||
|
||||
private static boolean shouldIgnoreFile(File file) {
|
||||
return file.getName().contains("aopalliance") //
|
||||
|| file.getName().contains("activation") //
|
||||
|| file.getName().contains("antlr") //
|
||||
|| file.getName().contains("assertj-core") //
|
||||
|| file.getName().startsWith("com.sun") //
|
||||
|| file.getName().startsWith("commonj.") //
|
||||
|| file.getName().startsWith("commons-") //
|
||||
|| file.getName().startsWith("jackson-") //
|
||||
|| file.getName().startsWith("hapi-") //
|
||||
|| file.getName().startsWith("jaxb-") //
|
||||
|| file.getName().startsWith("org.hl7.") //
|
||||
|| file.getName().startsWith("listenablefuture-") //
|
||||
|| file.getName().startsWith("j2objc-annotations") //
|
||||
|| file.getName().startsWith("failureaccess-") //
|
||||
|| file.getName().startsWith("error_prone_") //
|
||||
|| file.getName().startsWith("guava-") //
|
||||
|| file.getName().startsWith("org.eclipse") //
|
||||
|| file.getName().startsWith("javax") //
|
||||
|| file.getName().startsWith("jaxws") //
|
||||
|| file.getName().startsWith("jaxrs") //
|
||||
|| file.getName().startsWith("jaxb") //
|
||||
|| file.getName().contains("jsr305") //
|
||||
|| file.getName().contains("c3p0") //
|
||||
|| file.getName().contains("camel") //
|
||||
|| file.getName().contains("checker-qual") //
|
||||
|| file.getName().contains("cron") //
|
||||
|| file.getName().contains("FastInfoset") //
|
||||
|| file.getName().contains("gmbal") //
|
||||
|| file.getName().contains("grizzly") //
|
||||
|| file.getName().contains("gson") //
|
||||
|| file.getName().contains("ha-api") //
|
||||
|| file.getName().contains("HikariCP") //
|
||||
|| file.getName().contains("hk2") //
|
||||
|| file.getName().contains("icu4j") //
|
||||
|| file.getName().contains("jakarta") //
|
||||
|| file.getName().contains("javassist") //
|
||||
|| file.getName().contains("jersey") //
|
||||
|| file.getName().contains("joda-time") //
|
||||
|| file.getName().contains("logback") //
|
||||
|| file.getName().contains("management-api") //
|
||||
|| file.getName().contains("mchange-commons-java") //
|
||||
|| file.getName().contains("mimepull") //
|
||||
|| file.getName().contains("org.abego.treelayout") //
|
||||
|| file.getName().contains("osgi") //
|
||||
|| file.getName().contains("pfl-basic") //
|
||||
|| file.getName().contains("pfl-tf") //
|
||||
|| file.getName().contains("policy-2.7.10") //
|
||||
|| file.getName().contains("postgresql") //
|
||||
|| file.getName().contains("quartz") //
|
||||
|| file.getName().contains("saaj-impl") //
|
||||
|| file.getName().contains("sax") //
|
||||
|| file.getName().contains("slf4j") //
|
||||
|| file.getName().contains("ST4") //
|
||||
|| file.getName().contains("stax-ex") //
|
||||
|| file.getName().contains("stax2-api") //
|
||||
|| file.getName().contains("streambuffer") //
|
||||
|| file.getName().contains("tyrus") //
|
||||
|| file.getName().contains("validation-api") //
|
||||
|| file.getName().contains("yasson");
|
||||
String name = file.getName();
|
||||
return name.contains("aopalliance")
|
||||
|| name.contains("activation")
|
||||
|| name.contains("antlr")
|
||||
|| name.contains("assertj-core")
|
||||
|| name.startsWith("com.sun")
|
||||
|| name.startsWith("commonj.")
|
||||
|| name.startsWith("commons-")
|
||||
|| name.startsWith("jackson-")
|
||||
|| name.startsWith("hapi-")
|
||||
|| name.startsWith("jaxb-")
|
||||
|| name.startsWith("org.hl7.")
|
||||
|| name.startsWith("org.glassfish.")
|
||||
|| name.startsWith("listenablefuture-")
|
||||
|| name.startsWith("j2objc-annotations")
|
||||
|| name.startsWith("failureaccess-")
|
||||
|| name.startsWith("error_prone_")
|
||||
|| name.startsWith("guava-")
|
||||
|| name.startsWith("org.eclipse")
|
||||
|| name.startsWith("javax")
|
||||
|| name.startsWith("jaxws")
|
||||
|| name.startsWith("jaxrs")
|
||||
|| name.startsWith("jaxb")
|
||||
|| name.contains("jsr305")
|
||||
|| name.contains("c3p0")
|
||||
|| name.contains("camel")
|
||||
|| name.contains("checker-qual")
|
||||
|| name.contains("cron")
|
||||
|| name.contains("FastInfoset")
|
||||
|| name.contains("gmbal")
|
||||
|| name.contains("grizzly")
|
||||
|| name.contains("gson")
|
||||
|| name.contains("ha-api")
|
||||
|| name.contains("HikariCP")
|
||||
|| name.contains("hk2")
|
||||
|| name.contains("icu4j")
|
||||
|| name.contains("jakarta")
|
||||
|| name.contains("javassist")
|
||||
|| name.contains("jersey")
|
||||
|| name.contains("joda-time")
|
||||
|| name.contains("logback")
|
||||
|| name.contains("management-api")
|
||||
|| name.contains("mchange-commons-java")
|
||||
|| name.contains("mimepull")
|
||||
|| name.contains("org.abego.treelayout")
|
||||
|| name.contains("osgi")
|
||||
|| name.contains("pfl-basic")
|
||||
|| name.contains("pfl-tf")
|
||||
|| name.contains("policy-2.7.10")
|
||||
|| name.contains("postgresql")
|
||||
|| name.contains("quartz")
|
||||
|| name.contains("saaj-impl")
|
||||
|| name.contains("sax")
|
||||
|| name.contains("slf4j")
|
||||
|| name.contains("ST4")
|
||||
|| name.contains("stax-ex")
|
||||
|| name.contains("stax2-api")
|
||||
|| name.contains("streambuffer")
|
||||
|| name.contains("tyrus")
|
||||
|| name.contains("validation-api")
|
||||
|| name.contains("yasson");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -224,6 +224,19 @@ public class ExceptionHelper {
|
|||
return getExceptionMessage(getRootCause(throwable), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link #getExceptionMessage(Throwable, boolean)} for the root cause of the given {@link Throwable}
|
||||
*
|
||||
* @param throwable the throwable for which to get the message of the root cause
|
||||
* @param withClassName if true, then exception class name is prepended to the exception message, if the exception
|
||||
* message is null, then this param is ignored
|
||||
*
|
||||
* @return {@link #getExceptionMessage(Throwable, boolean)} for the root cause of the given {@link Throwable}
|
||||
*/
|
||||
public static String getRootCauseMessage(Throwable throwable, boolean withClassName) {
|
||||
return getExceptionMessage(getRootCause(throwable), withClassName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks the causes for the given {@link Throwable} and sees if the given cause exists
|
||||
*
|
||||
|
|
|
@ -204,10 +204,7 @@ public class RestfulStrolchComponent extends StrolchComponent {
|
|||
|
||||
@Override
|
||||
public void start() throws Exception {
|
||||
if (instance == null)
|
||||
instance = this;
|
||||
else if (instance != this)
|
||||
throw new IllegalStateException("Instance is already set! This component is a singleton resource!");
|
||||
instance = this;
|
||||
super.start();
|
||||
}
|
||||
|
||||
|
|
|
@ -75,13 +75,21 @@ public class ReportResource {
|
|||
|
||||
try (StrolchTransaction tx = getInstance().openTx(cert, realm, getContext())) {
|
||||
|
||||
StrolchRootElementToJsonVisitor visitor = new StrolchRootElementToJsonVisitor().flat().withoutVersion()
|
||||
.withoutObjectType().withoutPolicies().withoutStateVariables()
|
||||
.ignoreBags(BAG_JOINS, BAG_COLUMNS, BAG_ORDERING, BAG_ADDITIONAL_TYPE).ignoreBagByType(TYPE_FILTER)
|
||||
StrolchRootElementToJsonVisitor visitor = new StrolchRootElementToJsonVisitor()
|
||||
.flat()
|
||||
.withoutVersion()
|
||||
.withoutObjectType()
|
||||
.withoutPolicies()
|
||||
.withoutStateVariables()
|
||||
.ignoreBags(BAG_JOINS, BAG_COLUMNS, BAG_ORDERING, BAG_ADDITIONAL_TYPE)
|
||||
.ignoreBagByType(TYPE_FILTER)
|
||||
.resourceHook((reportRes, reportJ) -> reportJ.addProperty(PARAM_DATE_RANGE,
|
||||
reportRes.hasParameter(BAG_PARAMETERS, PARAM_DATE_RANGE_SEL)));
|
||||
JsonArray result = new ReportSearch(tx).search(tx).orderByName(false)
|
||||
.map(resource -> resource.accept(visitor)).asStream()
|
||||
JsonArray result = new ReportSearch(tx)
|
||||
.search(tx)
|
||||
.orderByName(false)
|
||||
.map(resource -> resource.accept(visitor))
|
||||
.asStream()
|
||||
.collect(JsonArray::new, JsonArray::add, JsonArray::addAll);
|
||||
|
||||
return ResponseUtil.toResponse(DATA, result);
|
||||
|
@ -103,7 +111,8 @@ public class ReportResource {
|
|||
File localesF = new File(request.getServletContext().getRealPath(LOCALES_JSON));
|
||||
JsonObject localeJ = null;
|
||||
if (localesF.exists()) {
|
||||
JsonObject localesJ = JsonParser.parseString(new String(Files.readAllBytes(localesF.toPath())))
|
||||
JsonObject localesJ = JsonParser
|
||||
.parseString(new String(Files.readAllBytes(localesF.toPath())))
|
||||
.getAsJsonObject();
|
||||
if (localesJ.has(cert.getLocale().toLanguageTag()))
|
||||
localeJ = localesJ.get(cert.getLocale().toLanguageTag()).getAsJsonObject();
|
||||
|
@ -124,21 +133,19 @@ public class ReportResource {
|
|||
JsonArray facetsJ = new JsonArray();
|
||||
JsonObject finalLocaleJ = localeJ;
|
||||
|
||||
MapOfSets<String, StrolchRootElement> criteria = report.generateFilterCriteria(limit);
|
||||
MapOfSets<String, JsonObject> criteria = report.generateFilterCriteria(limit);
|
||||
|
||||
criteria.keySet().stream().sorted(comparing(type -> {
|
||||
JsonElement translatedJ = finalLocaleJ == null ? null : finalLocaleJ.get(type);
|
||||
return translatedJ == null ? type : translatedJ.getAsString();
|
||||
})).forEach(type -> {
|
||||
Set<StrolchRootElement> elements = criteria.getSet(type);
|
||||
Set<JsonObject> elements = criteria.getSet(type);
|
||||
JsonObject filter = new JsonObject();
|
||||
filter.addProperty(Tags.Json.TYPE, type);
|
||||
filter.add(Tags.Json.VALUES, elements.stream().sorted(comparing(StrolchElement::getName)).map(f -> {
|
||||
JsonObject o = new JsonObject();
|
||||
o.addProperty(Tags.Json.ID, f.getId());
|
||||
o.addProperty(Tags.Json.NAME, f.getName());
|
||||
return o;
|
||||
}).collect(JsonArray::new, JsonArray::add, JsonArray::addAll));
|
||||
filter.add(Tags.Json.VALUES, elements
|
||||
.stream()
|
||||
.sorted(comparing(e -> e.get(Tags.Json.NAME).getAsString()))
|
||||
.collect(JsonArray::new, JsonArray::add, JsonArray::addAll));
|
||||
facetsJ.add(filter);
|
||||
});
|
||||
|
||||
|
@ -148,7 +155,7 @@ public class ReportResource {
|
|||
result.addProperty(PARAM_DURATION, duration);
|
||||
result.addProperty(PARAM_PARALLEL, report.isParallel());
|
||||
|
||||
logger.info("Facet Generation for " + id + " took: " + duration);
|
||||
logger.info("Facet Generation for {} took: {}", id, duration);
|
||||
return ResponseUtil.toResponse(DATA, result);
|
||||
}
|
||||
}
|
||||
|
@ -171,7 +178,8 @@ public class ReportResource {
|
|||
File localesF = new File(request.getServletContext().getRealPath(LOCALES_JSON));
|
||||
JsonObject localeJ = null;
|
||||
if (localesF.exists()) {
|
||||
JsonObject localesJ = JsonParser.parseString(new String(Files.readAllBytes(localesF.toPath())))
|
||||
JsonObject localesJ = JsonParser
|
||||
.parseString(new String(Files.readAllBytes(localesF.toPath())))
|
||||
.getAsJsonObject();
|
||||
if (localesJ.has(cert.getLocale().toLanguageTag()))
|
||||
localeJ = localesJ.get(cert.getLocale().toLanguageTag()).getAsJsonObject();
|
||||
|
@ -189,37 +197,13 @@ public class ReportResource {
|
|||
report.getReportPolicy().setI18nData(localeJ);
|
||||
|
||||
// get filter criteria
|
||||
Stream<StrolchRootElement> criteria = report.generateFilterCriteria(type);
|
||||
if (query != null && !query.isEmpty()) {
|
||||
String[] parts = query.split(" ");
|
||||
criteria = criteria.filter(f -> ObjectHelper.contains(f.getName(), parts, true));
|
||||
}
|
||||
|
||||
int maxFacetValues;
|
||||
int reportMaxFacetValues = report.getReportResource().getInteger(PARAM_MAX_FACET_VALUES);
|
||||
if (reportMaxFacetValues != 0 && reportMaxFacetValues != limit) {
|
||||
logger.warn("Report " + report.getReportResource().getId() + " has " + PARAM_MAX_FACET_VALUES +
|
||||
" defined as " + reportMaxFacetValues + ". Ignoring requested limit " + limit);
|
||||
maxFacetValues = reportMaxFacetValues;
|
||||
} else {
|
||||
maxFacetValues = limit;
|
||||
}
|
||||
|
||||
criteria = criteria.sorted(comparing(StrolchElement::getName));
|
||||
|
||||
if (maxFacetValues != 0)
|
||||
criteria = criteria.limit(maxFacetValues);
|
||||
|
||||
// add the data finally
|
||||
JsonArray array = criteria.map(f -> {
|
||||
JsonObject o = new JsonObject();
|
||||
o.addProperty(Tags.Json.ID, f.getId());
|
||||
o.addProperty(Tags.Json.NAME, f.getName());
|
||||
return o;
|
||||
}).collect(JsonArray::new, JsonArray::add, JsonArray::addAll);
|
||||
JsonArray array = report
|
||||
.generateFilterCriteria(type, limit, query)
|
||||
.sorted(comparing(e -> e.get(Tags.Json.NAME).getAsString()))
|
||||
.collect(JsonArray::new, JsonArray::add, JsonArray::addAll);
|
||||
|
||||
String duration = formatNanoDuration(System.nanoTime() - start);
|
||||
logger.info("Facet Generation for " + id + "." + type + " took: " + duration);
|
||||
logger.info("Facet Generation for {}.{} took: {}", id, type, duration);
|
||||
return ResponseUtil.toResponse(DATA, array);
|
||||
}
|
||||
}
|
||||
|
@ -273,7 +257,8 @@ public class ReportResource {
|
|||
File localesF = new File(request.getServletContext().getRealPath(LOCALES_JSON));
|
||||
JsonObject localeJ = null;
|
||||
if (localesF.exists()) {
|
||||
JsonObject localesJ = JsonParser.parseString(new String(Files.readAllBytes(localesF.toPath())))
|
||||
JsonObject localesJ = JsonParser
|
||||
.parseString(new String(Files.readAllBytes(localesF.toPath())))
|
||||
.getAsJsonObject();
|
||||
if (localesJ.has(cert.getLocale().toLanguageTag()))
|
||||
localeJ = localesJ.get(cert.getLocale().toLanguageTag()).getAsJsonObject();
|
||||
|
@ -349,7 +334,7 @@ public class ReportResource {
|
|||
finalResult.addProperty(PARAM_DURATION, duration);
|
||||
finalResult.addProperty(PARAM_PARALLEL, report.isParallel());
|
||||
|
||||
logger.info(id + " Report took: " + duration);
|
||||
logger.info("{} Report took: {}", id, duration);
|
||||
return ResponseUtil.toResponse(DATA, finalResult);
|
||||
}
|
||||
}
|
||||
|
@ -400,7 +385,8 @@ public class ReportResource {
|
|||
File localesF = new File(request.getServletContext().getRealPath(LOCALES_JSON));
|
||||
JsonObject localeJ = null;
|
||||
if (localesF.exists()) {
|
||||
JsonObject localesJ = JsonParser.parseString(new String(Files.readAllBytes(localesF.toPath())))
|
||||
JsonObject localesJ = JsonParser
|
||||
.parseString(new String(Files.readAllBytes(localesF.toPath())))
|
||||
.getAsJsonObject();
|
||||
if (localesJ.has(cert.getLocale().toLanguageTag()))
|
||||
localeJ = localesJ.get(cert.getLocale().toLanguageTag()).getAsJsonObject();
|
||||
|
@ -411,8 +397,10 @@ public class ReportResource {
|
|||
|
||||
// send
|
||||
String fileName = id + "_" + System.currentTimeMillis() + ".csv";
|
||||
return Response.ok(out, TEXT_CSV_TYPE)
|
||||
.header("Content-Disposition", "attachment; filename=\"" + fileName + "\"").build();
|
||||
return Response
|
||||
.ok(out, TEXT_CSV_TYPE)
|
||||
.header("Content-Disposition", "attachment; filename=\"" + fileName + "\"")
|
||||
.build();
|
||||
}
|
||||
|
||||
private StreamingOutput getOut(Certificate cert, String realm, String reportId, JsonObject localeJ,
|
||||
|
@ -485,12 +473,14 @@ public class ReportResource {
|
|||
// go through all filters and add to the map of sets
|
||||
for (JsonElement elem : filters.getAsJsonArray()) {
|
||||
if (!elem.isJsonObject()) {
|
||||
logger.warn("There are wrong formatted filters:\n" + elem);
|
||||
logger.warn("There are wrong formatted filters:\n{}", elem);
|
||||
continue;
|
||||
}
|
||||
|
||||
JsonObject filter = elem.getAsJsonObject();
|
||||
filter.get(PARAM_FACET_FILTERS).getAsJsonArray()
|
||||
filter
|
||||
.get(PARAM_FACET_FILTERS)
|
||||
.getAsJsonArray()
|
||||
.forEach(f -> result.addElement(filter.get(PARAM_FACET_TYPE).getAsString(), f.getAsString()));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue