diff --git a/core/src/main/java/org/genesys/blocks/model/filters/StringFilter.java b/core/src/main/java/org/genesys/blocks/model/filters/StringFilter.java index b24231faeb8bfe94a90014a001da791147c0340b..0b831b3580d9b28538c9850ae71f66875ccb4b67 100644 --- a/core/src/main/java/org/genesys/blocks/model/filters/StringFilter.java +++ b/core/src/main/java/org/genesys/blocks/model/filters/StringFilter.java @@ -15,7 +15,19 @@ */ package org.genesys.blocks.model.filters; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.google.common.collect.Sets; import com.querydsl.core.BooleanBuilder; +import com.querydsl.core.types.Predicate; import com.querydsl.core.types.dsl.StringPath; /** @@ -24,13 +36,16 @@ import com.querydsl.core.types.dsl.StringPath; public class StringFilter { /** Equal. */ - public String eq; + @JsonDeserialize(using = StringFilter.SetDeserializer.class) + public Set eq; /** Contains substring. */ - public String contains; + @JsonDeserialize(using = StringFilter.SetDeserializer.class) + public Set contains; /** Starts with. */ - public String sw; + @JsonDeserialize(using = StringFilter.SetDeserializer.class) + public Set sw; /** * Builds the query. @@ -40,30 +55,91 @@ public class StringFilter { */ public BooleanBuilder buildQuery(final StringPath val) { final BooleanBuilder and = new BooleanBuilder(); - if (eq != null) { - and.and(val.isNotNull()); - and.and(val.eq(eq)); + if (eq != null && !eq.isEmpty()) { + and.and(val.isNotNull()).and(val.in(eq)); } - if (sw != null) { - and.and(val.isNotNull()); - and.and(val.startsWith(sw)); + if (sw != null && !sw.isEmpty()) { + and.and(val.isNotNull()).andAnyOf(sw.stream().map(val::startsWith).toArray(Predicate[]::new)); } - if (contains != null) { - and.and(val.isNotNull()); - and.and(val.contains(contains)); + if (contains != null && !contains.isEmpty()) { + and.and(val.isNotNull()).andAnyOf(contains.stream().map(val::contains).toArray(Predicate[]::new)); } return and; } /** - * Eq. + * Equals. * * @param val the val * @return the string filter + * + * @deprecated Use {@link #eq(String[])} */ - public static StringFilter eq(final String val) { + public static StringFilter equals(final String... val) { final StringFilter filter = new StringFilter(); - filter.eq = val; + filter.eq = Sets.newHashSet(val); return filter; } + + /** + * Eq. + * + * @param val the val + * @return the string filter + */ + public StringFilter eq(final String... val) { + if (eq != null && !eq.isEmpty()) { + eq.addAll(Arrays.asList(val)); + } else { + eq = Sets.newHashSet(val); + } + return this; + } + + /** + * Contains. + * + * @param val the val + * @return the string filter + */ + public StringFilter contains(final String... val) { + if (contains != null && !contains.isEmpty()) { + contains.addAll(Arrays.asList(val)); + } else { + contains = Sets.newHashSet(val); + } + return this; + } + + /** + * Sw. + * + * @param val the val + * @return the string filter + */ + public StringFilter sw(final String... val) { + if (sw != null && !sw.isEmpty()) { + sw.addAll(Arrays.asList(val)); + } else { + sw = Sets.newHashSet(val); + } + return this; + } + + static class SetDeserializer extends JsonDeserializer> { + @Override + public Set deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { + final Set values = new HashSet<>(); + if (jsonParser.getCurrentToken() == JsonToken.START_ARRAY) { + while (jsonParser.getCurrentToken() != null && jsonParser.getCurrentToken() != JsonToken.END_ARRAY) { + if (jsonParser.nextToken() == JsonToken.VALUE_STRING) { + values.add(jsonParser.getText()); + } + } + } else if (jsonParser.getCurrentToken() == JsonToken.VALUE_STRING) { + values.add(jsonParser.getText()); + } + return values; + } + } } diff --git a/core/src/test/java/org/genesys/blocks/tests/filter/StringFilterTest.java b/core/src/test/java/org/genesys/blocks/tests/filter/StringFilterTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e69f5b717e0d850194a9d5a087c1b457ba1d5f90 --- /dev/null +++ b/core/src/test/java/org/genesys/blocks/tests/filter/StringFilterTest.java @@ -0,0 +1,76 @@ +/* + * Copyright 2020 Global Crop Diversity Trust + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.genesys.blocks.tests.filter; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.genesys.blocks.model.filters.StringFilter; +import org.junit.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.Arrays; + +/** + * The Class StringFilterTest. + */ +public class StringFilterTest { + + private static ObjectMapper objectMapper = new ObjectMapper(); + + @Test + public void testDeserializationOfEq() throws JsonProcessingException { + StringFilter filter1 = objectMapper.readValue("{ \"eq\": \"AAA\" }", StringFilter.class); + assertNotNull(filter1); + assertEquals(1, filter1.eq.size()); + assertEquals("AAA", filter1.eq.toArray()[0]); + + StringFilter filter2 = objectMapper.readValue("{ \"eq\": [ \"AAA\", \"BBB\" ] }", StringFilter.class); + assertNotNull(filter2); + assertEquals(2, filter2.eq.size()); + assertThat(Arrays.asList("AAA", "BBB"), containsInAnyOrder(filter2.eq.toArray())); + } + + @Test + public void testDeserializationOfContains() throws JsonProcessingException { + StringFilter filter1 = objectMapper.readValue("{ \"contains\": \"AAA\" }", StringFilter.class); + assertNotNull(filter1); + assertEquals(1, filter1.contains.size()); + assertEquals("AAA", filter1.contains.toArray()[0]); + + StringFilter filter2 = objectMapper.readValue("{ \"contains\": [ \"AAA\", \"BBB\" ] }", StringFilter.class); + assertNotNull(filter2); + assertEquals(2, filter2.contains.size()); + assertThat(Arrays.asList("AAA", "BBB"), containsInAnyOrder(filter2.contains.toArray())); + } + + @Test + public void testDeserializationOfStartsWith() throws JsonProcessingException { + StringFilter filter1 = objectMapper.readValue("{ \"sw\": \"AAA\" }", StringFilter.class); + assertNotNull(filter1); + assertEquals(1, filter1.sw.size()); + assertEquals("AAA", filter1.sw.toArray()[0]); + + StringFilter filter2 = objectMapper.readValue("{ \"sw\": [ \"AAA\", \"BBB\" ] }", StringFilter.class); + assertNotNull(filter2); + assertEquals(2, filter2.sw.size()); + assertThat(Arrays.asList("AAA", "BBB"), containsInAnyOrder(filter2.sw.toArray())); + } +}