From 367bf5b740f42362b4e08ee2c3de6b2014ccfe72 Mon Sep 17 00:00:00 2001 From: Matija Obreza Date: Thu, 28 Aug 2014 16:07:14 +0200 Subject: [PATCH] Deserialize JSON filters to internal objects --- .../model/filters/NoSuchFilterException.java | 9 + .../filters/NoSuchFilterValueException.java | 19 + .../filters/UnsupportedFilterOperation.java | 9 + .../server/service/impl/FilterHandler.java | 564 +++++++++++++++++- .../server/model/filters/FiltersTest.java | 218 +++++++ 5 files changed, 814 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/genesys2/server/model/filters/NoSuchFilterException.java create mode 100644 src/main/java/org/genesys2/server/model/filters/NoSuchFilterValueException.java create mode 100644 src/main/java/org/genesys2/server/model/filters/UnsupportedFilterOperation.java create mode 100644 src/test/java/org/genesys2/server/model/filters/FiltersTest.java diff --git a/src/main/java/org/genesys2/server/model/filters/NoSuchFilterException.java b/src/main/java/org/genesys2/server/model/filters/NoSuchFilterException.java new file mode 100644 index 000000000..dd264d89e --- /dev/null +++ b/src/main/java/org/genesys2/server/model/filters/NoSuchFilterException.java @@ -0,0 +1,9 @@ +package org.genesys2.server.model.filters; + +public class NoSuchFilterException extends Exception { + + public NoSuchFilterException(String message) { + super(message); + } + +} diff --git a/src/main/java/org/genesys2/server/model/filters/NoSuchFilterValueException.java b/src/main/java/org/genesys2/server/model/filters/NoSuchFilterValueException.java new file mode 100644 index 000000000..44048804d --- /dev/null +++ b/src/main/java/org/genesys2/server/model/filters/NoSuchFilterValueException.java @@ -0,0 +1,19 @@ +package org.genesys2.server.model.filters; + +public class NoSuchFilterValueException extends Exception { + + private Object filterValue; + + public NoSuchFilterValueException(Object filterValue) { + this.filterValue = filterValue; + } + + public Object getFilterValue() { + return filterValue; + } + + @Override + public String toString() { + return super.toString() + " Invalid value: " + filterValue; + } +} diff --git a/src/main/java/org/genesys2/server/model/filters/UnsupportedFilterOperation.java b/src/main/java/org/genesys2/server/model/filters/UnsupportedFilterOperation.java new file mode 100644 index 000000000..935acfeea --- /dev/null +++ b/src/main/java/org/genesys2/server/model/filters/UnsupportedFilterOperation.java @@ -0,0 +1,9 @@ +package org.genesys2.server.model.filters; + +public class UnsupportedFilterOperation extends Exception { + + public UnsupportedFilterOperation(String message) { + super(message); + } + +} diff --git a/src/main/java/org/genesys2/server/service/impl/FilterHandler.java b/src/main/java/org/genesys2/server/service/impl/FilterHandler.java index ced0de0dc..29b981c50 100644 --- a/src/main/java/org/genesys2/server/service/impl/FilterHandler.java +++ b/src/main/java/org/genesys2/server/service/impl/FilterHandler.java @@ -19,8 +19,10 @@ package org.genesys2.server.service.impl; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.Predicate; @@ -35,6 +37,9 @@ import org.genesys2.server.model.filters.GenesysFilter.DataType; import org.genesys2.server.model.filters.GenesysFilter.FilterType; import org.genesys2.server.model.filters.I18nListFilter; import org.genesys2.server.model.filters.MethodFilter; +import org.genesys2.server.model.filters.NoSuchFilterException; +import org.genesys2.server.model.filters.NoSuchFilterValueException; +import org.genesys2.server.model.filters.UnsupportedFilterOperation; import org.genesys2.server.model.filters.ValueName; import org.genesys2.server.model.genesys.Method; import org.genesys2.server.model.genesys.TraitCode; @@ -43,7 +48,18 @@ import org.genesys2.server.service.TraitService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; /** * Converts filter requests (usually JSON) to internal data structures @@ -155,24 +171,562 @@ public class FilterHandler { return filter; } - public List fromJSON(String jsonFilter) throws IOException { - Map> filters = objectMapper.readValue(jsonFilter, Map.class); - List appliedFilters = new ArrayList(); + public List fromJSON(String jsonFilter) throws IOException, NoSuchFilterException, UnsupportedFilterOperation, NoSuchFilterValueException { + @SuppressWarnings("unchecked") + Map> filters = objectMapper.readValue(jsonFilter, Map.class); + AppliedFilters appliedFilters = new AppliedFilters(); for (String key : filters.keySet()) { - List filterValues = filters.get(key); + List filterValues = filters.get(key); if (filterValues == null || filterValues.isEmpty()) continue; LOG.info("key=" + key); + AppliedFilter appliedFilter = new AppliedFilter(); + appliedFilter.setFilter(getFilterByName(key)); + for (Object filterValue : filterValues) { + appliedFilter.addFilterValue(toFilterValue(filterValue)); + } } return appliedFilters; } - private static class AppliedFilter { + private FilterValue toFilterValue(Object filterValue) throws UnsupportedFilterOperation, NoSuchFilterValueException { + if (filterValue == null) + return null; + + if (filterValue instanceof Map) { + return toFilterOperation((Map) filterValue); + } else if (filterValue instanceof Number || filterValue instanceof String) { + return new LiteralValueFilter(filterValue); + } else { + throw new NoSuchFilterValueException(filterValue); + } + } + + private FilterValue toFilterOperation(Map filterValue) throws UnsupportedFilterOperation { + @SuppressWarnings("unchecked") + List range = (List) filterValue.get("range"); + + if (range != null) { + return new ValueRangeFilter(range.get(0), range.get(1)); + } + Number max = (Number) filterValue.get("max"); + if (max != null) { + return new MaxValueFilter(max); + } + Number min = (Number) filterValue.get("min"); + if (min != null) { + return new MinValueFilter(min); + } + + String like = (String) filterValue.get("like"); + if (like != null) { + return new StartsWithFilter(like); + } + + throw new UnsupportedFilterOperation(filterValue.toString()); + } + + private GenesysFilter getFilterByName(String key) throws NoSuchFilterException { + for (GenesysFilter filter : this.availableFilters) { + if (filter.getKey().equals(key)) { + return filter; + } + } + throw new NoSuchFilterException(key); + } + + public static interface FilterValue { + + } + + @JsonSerialize(using = AppliedFilters.Serializer.class) + @JsonDeserialize(using = AppliedFilters.Deserializer.class) + public static class AppliedFilters extends ArrayList { + public static class Serializer extends JsonSerializer { + @Override + public void serialize(AppliedFilters filters, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeStartObject(); + for (AppliedFilter filter : filters) { + jgen.writeArrayFieldStart(filter.getFilterName()); + for (FilterValue fv : filter.getValues()) + jgen.writeObject(fv); + if (filter.withNull) + jgen.writeNull(); + jgen.writeEndArray(); + } + jgen.writeEndObject(); + } + } + + public static class Deserializer extends StdDeserializer { + public Deserializer() { + super(AppliedFilters.class); + } + + protected Deserializer(Class vc) { + super(vc); + } + + @Override + public AppliedFilters deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + if (jp.getCurrentToken() != JsonToken.START_OBJECT) { + throw new IOException("invalid start marker"); + } + final AppliedFilters appliedFilters = new AppliedFilters(); + + jp.nextToken(); + while (jp.getCurrentToken() == JsonToken.FIELD_NAME) { + AppliedFilter af = new AppliedFilter(); + appliedFilters.add(af); + af.setFilterName(jp.getCurrentName()); + + jp.nextToken(); + if (jp.getCurrentToken() == JsonToken.START_ARRAY) { + jp.nextToken(); + + do { + if (jp.getCurrentToken() == JsonToken.VALUE_STRING) { + af.addFilterValue(new LiteralValueFilter(jp.getText())); + } else if (jp.getCurrentToken() == JsonToken.VALUE_TRUE || jp.getCurrentToken() == JsonToken.VALUE_FALSE) { + af.addFilterValue(new LiteralValueFilter(jp.getBooleanValue())); + } else if (jp.getCurrentToken() == JsonToken.VALUE_NUMBER_FLOAT) { + af.addFilterValue(new LiteralValueFilter(jp.getDoubleValue())); + } else if (jp.getCurrentToken() == JsonToken.VALUE_NUMBER_INT) { + af.addFilterValue(new LiteralValueFilter(jp.getLongValue())); + } else if (jp.getCurrentToken() == JsonToken.VALUE_NULL) { + af.addFilterValue(null); + } else if (jp.getCurrentToken() == JsonToken.START_OBJECT) { + jp.nextToken(); + String op = jp.getCurrentName(); + if ("like".equals(op)) { + af.addFilterValue(new StartsWithFilter(jp.nextTextValue())); + } else if ("min".equals(op)) { + Number number1 = null; + jp.nextToken(); + if (jp.getCurrentToken() == JsonToken.VALUE_NUMBER_FLOAT) { + number1 = jp.getDoubleValue(); + } else if (jp.getCurrentToken() == JsonToken.VALUE_NUMBER_INT) { + number1 = jp.getLongValue(); + } + + if (number1 == null) + throw new JsonParseException("MinValueFilter expects a single numeric value", jp.getCurrentLocation()); + + af.addFilterValue(new MinValueFilter(number1)); + } else if ("max".equals(op)) { + Number number1 = null; + jp.nextToken(); + if (jp.getCurrentToken() == JsonToken.VALUE_NUMBER_FLOAT) { + number1 = jp.getDoubleValue(); + } else if (jp.getCurrentToken() == JsonToken.VALUE_NUMBER_INT) { + number1 = jp.getLongValue(); + } + + if (number1 == null) + throw new JsonParseException("MaxValueFilter expects a single numeric value", jp.getCurrentLocation()); + + af.addFilterValue(new MaxValueFilter(number1)); + } else if ("range".equals(op)) { + if (jp.nextToken() == JsonToken.START_ARRAY) { + Number number1 = null, number2 = null; + jp.nextToken(); + if (jp.getCurrentToken() == JsonToken.VALUE_NUMBER_FLOAT) { + number1 = jp.getDoubleValue(); + } else if (jp.getCurrentToken() == JsonToken.VALUE_NUMBER_INT) { + number1 = jp.getLongValue(); + } + jp.nextToken(); + if (jp.getCurrentToken() == JsonToken.VALUE_NUMBER_FLOAT) { + number2 = jp.getDoubleValue(); + } else if (jp.getCurrentToken() == JsonToken.VALUE_NUMBER_INT) { + number2 = jp.getLongValue(); + } + if (number1 == null || number2 == null || jp.nextToken() != JsonToken.END_ARRAY) + throw new JsonParseException("ValueRangeFilter expects two numeric values in an array", jp.getCurrentLocation()); + + af.addFilterValue(new ValueRangeFilter(number1, number2)); + } else { + throw new JsonParseException("ValueRangeFilter expects an array of values", jp.getCurrentLocation()); + } + } + + if (jp.nextToken() != JsonToken.END_OBJECT) + throw new JsonParseException("Expecting }, got " + jp.getCurrentToken(), jp.getCurrentLocation()); + } else { + throw new JsonParseException("I don't know where I am.", jp.getCurrentLocation()); + } + + jp.nextToken(); + + } while (jp.getCurrentToken() != JsonToken.END_ARRAY); + } else { + System.err.println(jp.getCurrentToken()); + throw new JsonParseException("Filter values must be provided in an array", jp.getCurrentLocation()); + } + + if (jp.nextToken() == JsonToken.END_OBJECT) + break; + + // System.err.println(jp.getCurrentToken()); + } + return appliedFilters; + } + } + } + + public static class AppliedFilter { + + private GenesysFilter filter; + private Set values = new HashSet(); + private boolean withNull = false; + private String filterName; + + public void setFilter(GenesysFilter filter) { + this.filter = filter; + } + + public String getFilterName() { + return this.filterName; + } + + public AppliedFilter setFilterName(String filterName) { + this.filterName = filterName; + return this; + } + + public AppliedFilter addFilterValue(FilterValue filterValue) { + if (filterValue == null) { + this.withNull = true; + } else { + values.add(filterValue); + } + + return this; + } + + public GenesysFilter getFilter() { + return filter; + } + + public boolean getWithNull() { + return this.withNull; + } + + public Set getValues() { + return values; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((filterName == null) ? 0 : filterName.hashCode()); + result = prime * result + ((values == null) ? 0 : values.hashCode()); + result = prime * result + (withNull ? 1231 : 1237); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AppliedFilter other = (AppliedFilter) obj; + if (filterName == null) { + if (other.filterName != null) + return false; + } else if (!filterName.equals(other.filterName)) + return false; + if (values == null) { + if (other.values != null) + return false; + } else if (!values.equals(other.values)) + return false; + if (withNull != other.withNull) + return false; + return true; + } + } + @JsonSerialize(using = LiteralValueFilter.Serializer.class) + public static class LiteralValueFilter implements FilterValue { + + public static class Serializer extends JsonSerializer { + @Override + public void serialize(LiteralValueFilter value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeObject(value.getValue()); + } + } + + private Object value; + + public LiteralValueFilter(Object value) { + this.value = value; + } + + public Object getValue() { + return value; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((value == null) ? 0 : value.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + LiteralValueFilter other = (LiteralValueFilter) obj; + if (value == null) { + if (other.value != null) + return false; + } else if (!value.equals(other.value)) + return false; + return true; + } + } + + @JsonSerialize(using = ValueRangeFilter.Serializer.class) + public static class ValueRangeFilter implements FilterValue { + + public static class Serializer extends JsonSerializer { + @Override + public void serialize(ValueRangeFilter value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeStartObject(); + jgen.writeArrayFieldStart("range"); + jgen.writeObject(value.getFrom()); + jgen.writeObject(value.getTo()); + jgen.writeEndArray(); + jgen.writeEndObject(); + } + } + + private Number from; + private Number to; + + public ValueRangeFilter(Number number1, Number number2) { + if (number1 == null || number2 == null) + throw new NullPointerException("ValueRangeFilter requires non-null values for range"); + + if (number1 instanceof Integer) + number1 = number1.longValue(); + if (number1 instanceof Float) + number1 = number1.doubleValue(); + + if (number2 instanceof Integer) + number2 = number2.longValue(); + if (number2 instanceof Float) + number2 = number2.doubleValue(); + + this.from = number1.doubleValue() < number2.doubleValue() ? number1 : number2; + this.to = number1.doubleValue() < number2.doubleValue() ? number2 : number1; + } + + public Number getFrom() { + return from; + } + + public Number getTo() { + return to; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((from == null) ? 0 : from.hashCode()); + result = prime * result + ((to == null) ? 0 : to.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ValueRangeFilter other = (ValueRangeFilter) obj; + if (from == null) { + if (other.from != null) + return false; + } else if (!from.equals(other.from)) + return false; + if (to == null) { + if (other.to != null) + return false; + } else if (!to.equals(other.to)) + return false; + return true; + } + } + + @JsonSerialize(using = MaxValueFilter.Serializer.class) + public static class MaxValueFilter implements FilterValue { + public static class Serializer extends JsonSerializer { + @Override + public void serialize(MaxValueFilter value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeStartObject(); + jgen.writeObjectField("max", value.getTo()); + jgen.writeEndObject(); + } + } + + private Number to; + + public MaxValueFilter(Number max) { + if (max instanceof Integer) + max = max.longValue(); + else if (max instanceof Float) + max = max.doubleValue(); + + this.to = max; + } + + public Number getTo() { + return to; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((to == null) ? 0 : to.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + MaxValueFilter other = (MaxValueFilter) obj; + if (to == null) { + if (other.to != null) + return false; + } else if (!to.equals(other.to)) + return false; + return true; + } + } + + @JsonSerialize(using = MinValueFilter.Serializer.class) + public static class MinValueFilter implements FilterValue { + public static class Serializer extends JsonSerializer { + @Override + public void serialize(MinValueFilter value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeStartObject(); + jgen.writeObjectField("min", value.getFrom()); + jgen.writeEndObject(); + } + } + + private Number from; + + public MinValueFilter(Number min) { + if (min instanceof Integer) + this.from = min.longValue(); + else if (min instanceof Float) + this.from = min.doubleValue(); + else + this.from = min; + } + + public Number getFrom() { + return from; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((from == null) ? 0 : from.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + MinValueFilter other = (MinValueFilter) obj; + if (from == null) { + if (other.from != null) + return false; + } else if (!from.equals(other.from)) + return false; + return true; + } + + } + + @JsonSerialize(using = StartsWithFilter.Serializer.class) + public static class StartsWithFilter implements FilterValue { + public static class Serializer extends JsonSerializer { + @Override + public void serialize(StartsWithFilter value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeStartObject(); + jgen.writeObjectField("like", value.getStartsWith()); + jgen.writeEndObject(); + } + } + + private String startsWith; + + public StartsWithFilter(String startsWith) { + this.startsWith = startsWith; + } + + public String getStartsWith() { + return startsWith; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((startsWith == null) ? 0 : startsWith.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + StartsWithFilter other = (StartsWithFilter) obj; + if (startsWith == null) { + if (other.startsWith != null) + return false; + } else if (!startsWith.equals(other.startsWith)) + return false; + return true; + } } } diff --git a/src/test/java/org/genesys2/server/model/filters/FiltersTest.java b/src/test/java/org/genesys2/server/model/filters/FiltersTest.java new file mode 100644 index 000000000..3db5f240e --- /dev/null +++ b/src/test/java/org/genesys2/server/model/filters/FiltersTest.java @@ -0,0 +1,218 @@ +package org.genesys2.server.model.filters; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.genesys2.server.aspect.AsAdminAspect; +import org.genesys2.server.service.AclService; +import org.genesys2.server.service.HtmlSanitizer; +import org.genesys2.server.service.TraitService; +import org.genesys2.server.service.UserService; +import org.genesys2.server.service.impl.AclServiceImpl; +import org.genesys2.server.service.impl.FilterHandler; +import org.genesys2.server.service.impl.FilterHandler.AppliedFilter; +import org.genesys2.server.service.impl.FilterHandler.AppliedFilters; +import org.genesys2.server.service.impl.OWASPSanitizer; +import org.genesys2.server.service.impl.TraitServiceImpl; +import org.genesys2.server.service.impl.UserServiceImpl; +import org.genesys2.server.test.JpaDataConfig; +import org.genesys2.server.test.PropertyPlacholderInitializer; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.CacheManager; +import org.springframework.cache.support.NoOpCacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = FiltersTest.Config.class, initializers = PropertyPlacholderInitializer.class) +@ActiveProfiles("dev") +public class FiltersTest { + public static final Log LOG = LogFactory.getLog(FiltersTest.class); + + @Import({ JpaDataConfig.class }) + @ComponentScan(basePackages = { "org.genesys2.server.persistence.domain" }) + public static class Config { + @Bean + public FilterHandler filterHandler() { + return new FilterHandler(); + } + + @Bean + public ObjectMapper objectMapper() { + return new ObjectMapper(); + } + + @Bean + public TraitService traitService() { + return new TraitServiceImpl(); + } + + @Bean + public AclService aclService() { + return new AclServiceImpl(); + } + + @Bean + public HtmlSanitizer htmlSanitizer() { + return new OWASPSanitizer(); + } + + @Bean + public UserService userService() { + return new UserServiceImpl(); + } + + @Bean + public AsAdminAspect asAdminAspect() { + return new AsAdminAspect(); + } + + @Bean + public CacheManager cacheManager() { + return new NoOpCacheManager(); + } + } + + @Autowired + private FilterHandler filterHandler; + + @Autowired + private ObjectMapper objectMapper; + + @Test + public void test1() throws JsonGenerationException, JsonMappingException, IOException { + AppliedFilters afs = new AppliedFilters(); + + for (int i = 0; i < 5; i++) { + FilterHandler.AppliedFilter af = new FilterHandler.AppliedFilter(); + af.setFilterName("key1"); + af.addFilterValue(new FilterHandler.LiteralValueFilter(1)); + af.addFilterValue(new FilterHandler.MinValueFilter(2)); + af.addFilterValue(new FilterHandler.LiteralValueFilter("Test")); + af.addFilterValue(new FilterHandler.StartsWithFilter("Te")); + af.addFilterValue(new FilterHandler.MaxValueFilter(2.1f)); + af.addFilterValue(new FilterHandler.ValueRangeFilter(3.0f, -1)); + af.addFilterValue(null); + afs.add(af); + } + + LOG.info(objectMapper.writeValueAsString(afs)); + } + + @Test + public void testDeserialize() throws JsonParseException, JsonMappingException, IOException { + String source = "{\"key\":[1,{\"min\":2},\"Test\"],\"key2\":[{\"max\":2.1},{\"range\":[-1,3.0]}],\"key3\":[{\"like\":\"Te\"},null]}"; + AppliedFilters afs = objectMapper.readValue(source, AppliedFilters.class); + + String result = objectMapper.writeValueAsString(afs); + LOG.info(result); + assertTrue(source.equals(result)); + } + + @Test + public void testLiterals() throws IOException { + AppliedFilters afs = new AppliedFilters(); + afs.add(new AppliedFilter().setFilterName("key1").addFilterValue(new FilterHandler.LiteralValueFilter(1)).addFilterValue(null)); + afs.add(new AppliedFilter().setFilterName("key2").addFilterValue(new FilterHandler.LiteralValueFilter("Test 1"))); + + String source = objectMapper.writeValueAsString(afs); + LOG.info(source); + + AppliedFilters afs2 = objectMapper.readValue(source, AppliedFilters.class); + String result = objectMapper.writeValueAsString(afs2); + LOG.info(result); + assertTrue(source.equals(result)); + } + + @Test + public void testRange() throws IOException { + AppliedFilters afs = new AppliedFilters(); + afs.add(new AppliedFilter().setFilterName("key1").addFilterValue(new FilterHandler.ValueRangeFilter(20, -10)).addFilterValue(null)); + afs.add(new AppliedFilter().setFilterName("key2.two").addFilterValue(new FilterHandler.ValueRangeFilter(-20, 10))); + + String source = objectMapper.writeValueAsString(afs); + LOG.info(source); + + AppliedFilters afs2 = objectMapper.readValue(source, AppliedFilters.class); + String result = objectMapper.writeValueAsString(afs2); + LOG.info(result); + assertTrue(source.equals(result)); + } + + @Test + public void testMax() throws IOException { + AppliedFilters afs = new AppliedFilters(); + afs.add(new AppliedFilter().setFilterName("key1").addFilterValue(new FilterHandler.MaxValueFilter(20.2)).addFilterValue(null)); + afs.add(new AppliedFilter().setFilterName("key2.two").addFilterValue(new FilterHandler.MaxValueFilter(-10.2f))); + + String source = objectMapper.writeValueAsString(afs); + LOG.info(source); + + AppliedFilters afs2 = objectMapper.readValue(source, AppliedFilters.class); + String result = objectMapper.writeValueAsString(afs2); + LOG.info(result); + assertTrue(source.equals(result)); + } + + @Test + public void testMin() throws IOException { + AppliedFilters afs = new AppliedFilters(); + afs.add(new AppliedFilter().setFilterName("key1").addFilterValue(new FilterHandler.MinValueFilter(20.2)).addFilterValue(null)); + afs.add(new AppliedFilter().setFilterName("key2.two").addFilterValue(new FilterHandler.MinValueFilter(-10.2f))); + + String source = objectMapper.writeValueAsString(afs); + LOG.info(source); + + AppliedFilters afs2 = objectMapper.readValue(source, AppliedFilters.class); + String result = objectMapper.writeValueAsString(afs2); + LOG.info(result); + assertTrue(source.equals(result)); + } + + @Test + public void testStartsWith() throws IOException { + AppliedFilters afs = new AppliedFilters(); + afs.add(new AppliedFilter().setFilterName("key1").addFilterValue(new FilterHandler.StartsWithFilter("Tes")).addFilterValue(null)); + afs.add(new AppliedFilter().setFilterName("key2.two").addFilterValue(new FilterHandler.StartsWithFilter("Haha"))); + + String source = objectMapper.writeValueAsString(afs); + LOG.info(source); + + AppliedFilters afs2 = objectMapper.readValue(source, AppliedFilters.class); + String result = objectMapper.writeValueAsString(afs2); + LOG.info(result); + assertTrue(source.equals(result)); + } + + @Test + public void testMix() throws IOException { + AppliedFilters afs = new AppliedFilters(); + afs.add(new AppliedFilter().setFilterName("key1").addFilterValue(new FilterHandler.MaxValueFilter(20.2)) + .addFilterValue(new FilterHandler.StartsWithFilter("Tes")).addFilterValue(null)); + afs.add(new AppliedFilter().setFilterName("key2.two").addFilterValue(new FilterHandler.StartsWithFilter("Haha")) + .addFilterValue(new FilterHandler.MinValueFilter(20.2)).addFilterValue(new FilterHandler.ValueRangeFilter(20, -10))); + + String source = objectMapper.writeValueAsString(afs); + LOG.info(source); + + AppliedFilters afs2 = objectMapper.readValue(source, AppliedFilters.class); + String result = objectMapper.writeValueAsString(afs2); + LOG.info(result); + + assertTrue(afs2.equals(afs)); + } +} -- GitLab