Skip to content

Commit

Permalink
feat: add supports for !eq in dimension endpoint [DHIS2-13779]
Browse files Browse the repository at this point in the history
  • Loading branch information
gnespolino committed Nov 8, 2023
1 parent 9ecd184 commit 7556f6f
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,9 @@
import java.util.Objects;
import java.util.Optional;
import java.util.StringTokenizer;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
Expand Down Expand Up @@ -67,7 +66,7 @@ public static DimensionFilters of(Collection<String> filterStrings) {
.map(String::trim)
.map(SingleFilter::of)
.filter(Objects::nonNull)
.collect(Collectors.toList());
.toList();

if (filters.isEmpty()) {
return EMPTY_DATA_DIMENSION_FILTER;
Expand All @@ -94,28 +93,27 @@ private static class SingleFilter implements Predicate<DimensionResponse> {
"displayName", DimensionResponse::getDisplayName,
"displayShortName", DimensionResponse::getDisplayShortName);

private static final Map<String, BiFunction<String, String, Boolean>> OPERATOR_MAP =
new HashMap<>();
private static final Map<String, BiPredicate<String, String>> OPERATOR_MAP = new HashMap<>();

static {
putOperator("startsWith", String::startsWith, true);
putOperator("endsWith", String::endsWith, true);
putOperator("eq", String::equals);
putOperator("eq", String::equals, true);
putOperator("ieq", String::equalsIgnoreCase);
putOperator("ne", (fv, v) -> !fv.equals(v));
putOperator("like", String::contains, true);
putOperator("ilike", (fv, v) -> fv.toLowerCase().contains(v.toLowerCase()), true);
}

private static void putOperator(String operator, BiFunction<String, String, Boolean> function) {
private static void putOperator(String operator, BiPredicate<String, String> function) {
putOperator(operator, function, false);
}

private static void putOperator(
String operator, BiFunction<String, String, Boolean> function, boolean negateAlso) {
String operator, BiPredicate<String, String> function, boolean negateAlso) {
OPERATOR_MAP.put(operator, function);
if (negateAlso) {
OPERATOR_MAP.put("!" + operator, (s, s2) -> !function.apply(s, s2));
OPERATOR_MAP.put("!" + operator, (s, s2) -> !function.test(s, s2));
}
}

Expand Down Expand Up @@ -153,7 +151,7 @@ public boolean test(DimensionResponse dimension) {

private boolean applyOperator(String fieldValue) {
return Optional.ofNullable(OPERATOR_MAP.get(operator))
.map(operation -> operation.apply(fieldValue, value))
.map(operation -> operation.test(fieldValue, value))
.orElse(false);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
*/
package org.hisp.dhis.analytics.dimension;

import static org.apache.commons.lang3.tuple.Pair.of;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
Expand All @@ -47,6 +48,10 @@

class DimensionFiltersTest {

/**
* A map of all the fields in {@link DimensionResponse} and a function that creates a {@link DimensionResponse}
* with that field set to the given value.
*/
private static final Map<String, Function<String, DimensionResponse>> BUILDER_MAP =
Map.of(
"id", s -> DimensionResponse.builder().id(s).build(),
Expand All @@ -58,33 +63,35 @@ class DimensionFiltersTest {
"displayName", s -> DimensionResponse.builder().displayName(s).build(),
"displayShortName", s -> DimensionResponse.builder().displayShortName(s).build());

public static final String STRING_TO_TEST_FILTER_ON = "TeSt";

/**
* A map of all the operators and the expected result of applying them to the {@link DimensionResponse} created
* by the corresponding {@link Function} in {@link #BUILDER_MAP} with the given {@link #STRING_TO_TEST_FILTER_ON}.
* The left value is the value to test for positive assertion, the right value is the value to test for negative.
*/
private static final Map<String, Pair<String, String>> OPERATORS =
Stream.concat(
Map.of(
"startsWith", Pair.of("Te", "eS"),
"!startsWith", Pair.of("eS", "Te"),
"endsWith", Pair.of("St", "eS"),
"!endsWith", Pair.of("eS", "St"),
"eq", Pair.of("TeSt", "tEsT"),
"ieq", Pair.of("test", "random"))
"startsWith", of("Te", "eS"),
"!startsWith", of("eS", "Te"),
"endsWith", of("St", "eS"),
"!endsWith", of("eS", "St"),
"eq", of("TeSt", "tEsT"),
"!eq", of("whatever", "TeSt"),
"ieq", of("test", "random"))
.entrySet()
.stream(),
Map.of(
"ne",
Pair.of("random", "TeSt"),
"like",
Pair.of("eS", "es"),
"!like",
Pair.of("es", "eS"),
"ilike",
Pair.of("es", "et"),
"!ilike",
Pair.of("et", "es"))
"ne", of("random", "TeSt"),
"like", of("eS", "es"),
"!like", of("es", "eS"),
"ilike", of("es", "et"),
"!ilike", of("et", "es"))
.entrySet()
.stream())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

public static final String TEST_STRING = "TeSt";

@Test
void testDimensionFilterConstructor() {
Expand Down Expand Up @@ -133,7 +140,8 @@ void testOperators() {
@Test
void testFieldsAndOperators() {

BUILDER_MAP.forEach((s, builder) -> assertAllOpsOnField(s, builder.apply(TEST_STRING)));
BUILDER_MAP.forEach((s, builder) -> assertAllOpsOnField(s, builder.apply(
STRING_TO_TEST_FILTER_ON)));
}

private void assertAllOpsOnField(String fieldName, DimensionResponse response) {
Expand Down

0 comments on commit 7556f6f

Please sign in to comment.