use of org.hisp.dhis.expression.MissingValueStrategy in project dhis2-core by dhis2.
the class DefaultExpressionService method generateExpression.
/**
* Generates an expression based on the given data maps.
*
* @param expression the expression.
* @param valueMap the value map.
* @param constantMap the constant map.
* @param orgUnitCountMap the organisation unit count map.
* @param days the number of days.
* @param missingValueStrategy the missing value strategy.
* @param aggregateMap the aggregate map.
* @return an expression.
*/
private String generateExpression(String expression, Map<? extends DimensionalItemObject, Double> valueMap, Map<String, Double> constantMap, Map<String, Integer> orgUnitCountMap, Integer days, MissingValueStrategy missingValueStrategy, Map<String, List<Double>> aggregateMap) {
if (expression == null || expression.isEmpty()) {
return null;
}
expression = ExpressionUtils.normalizeExpression(expression);
Map<String, Double> dimensionItemValueMap = valueMap.entrySet().stream().filter(e -> e.getValue() != null).collect(Collectors.toMap(e -> e.getKey().getDimensionItem(), e -> e.getValue()));
missingValueStrategy = ObjectUtils.firstNonNull(missingValueStrategy, NEVER_SKIP);
// ---------------------------------------------------------------------
// Aggregates
// ---------------------------------------------------------------------
StringBuffer sb = new StringBuffer();
Pattern prefix = CustomFunctions.AGGREGATE_PATTERN_PREFIX;
Matcher matcher = prefix.matcher(expression);
int scan = 0, len = expression.length(), tail = 0;
while (scan < len && matcher.find(scan)) {
int start = matcher.end();
int end = Expression.matchExpression(expression, start);
if (end < 0) {
sb.append(expression.substring(scan, start));
scan = start + 1;
tail = start;
} else if (aggregateMap == null || expression.charAt(start) == '<') {
sb.append(expression.substring(scan, end));
scan = end + 1;
tail = end;
} else {
String subExpression = expression.substring(start, end);
List<Double> samples = aggregateMap.get(subExpression);
if (samples == null) {
if (SKIP_IF_ANY_VALUE_MISSING.equals(missingValueStrategy)) {
return null;
}
} else {
String literal = (samples == null) ? ("[]") : (samples.toString());
sb.append(expression.substring(scan, start));
sb.append(literal);
}
scan = end;
tail = end;
}
}
sb.append(expression.substring(tail));
expression = sb.toString();
// ---------------------------------------------------------------------
// DimensionalItemObjects
// ---------------------------------------------------------------------
sb = new StringBuffer();
matcher = VARIABLE_PATTERN.matcher(expression);
int matchCount = 0;
int valueCount = 0;
while (matcher.find()) {
matchCount++;
String dimItem = matcher.group(GROUP_ID);
final Double value = dimensionItemValueMap.get(dimItem);
boolean missingValue = value == null;
if (missingValue && SKIP_IF_ANY_VALUE_MISSING.equals(missingValueStrategy)) {
return null;
}
if (!missingValue) {
valueCount++;
}
String replacement = value != null ? String.valueOf(value) : NULL_REPLACEMENT;
matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));
}
if (SKIP_IF_ALL_VALUES_MISSING.equals(missingValueStrategy) && matchCount > 0 && valueCount == 0) {
return null;
}
expression = TextUtils.appendTail(matcher, sb);
// ---------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------
sb = new StringBuffer();
matcher = CONSTANT_PATTERN.matcher(expression);
while (matcher.find()) {
final Double constant = constantMap != null ? constantMap.get(matcher.group(GROUP_ID)) : null;
String replacement = constant != null ? String.valueOf(constant) : NULL_REPLACEMENT;
matcher.appendReplacement(sb, replacement);
}
expression = TextUtils.appendTail(matcher, sb);
// ---------------------------------------------------------------------
// Org unit groups
// ---------------------------------------------------------------------
sb = new StringBuffer();
matcher = OU_GROUP_PATTERN.matcher(expression);
while (matcher.find()) {
final Integer count = orgUnitCountMap != null ? orgUnitCountMap.get(matcher.group(GROUP_ID)) : null;
String replacement = count != null ? String.valueOf(count) : NULL_REPLACEMENT;
matcher.appendReplacement(sb, replacement);
}
expression = TextUtils.appendTail(matcher, sb);
// ---------------------------------------------------------------------
// Days
// ---------------------------------------------------------------------
sb = new StringBuffer();
matcher = DAYS_PATTERN.matcher(expression);
while (matcher.find()) {
String replacement = days != null ? String.valueOf(days) : NULL_REPLACEMENT;
matcher.appendReplacement(sb, replacement);
}
return TextUtils.appendTail(matcher, sb);
}
Aggregations