Last active
August 29, 2015 13:56
-
-
Save s-j/8864592 to your computer and use it in GitHub Desktop.
Deserializing multi-level polymorphic types with Jackson.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import com.fasterxml.jackson.core.JsonParser; | |
import com.fasterxml.jackson.core.ObjectCodec; | |
import com.fasterxml.jackson.databind.DeserializationContext; | |
import com.fasterxml.jackson.databind.JsonDeserializer; | |
import com.fasterxml.jackson.databind.JsonNode; | |
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; | |
import com.google.common.base.Strings; | |
public final class Example { | |
private Example() { } | |
@JsonDeserialize(using = FilterDeserializer.class) | |
public abstract static class Filter { | |
public String type; | |
public String operator; | |
} | |
public abstract static class StringFilter extends Filter { | |
public String variable; | |
} | |
public static final class Equality extends StringFilter { | |
public String value; | |
public Equality(String type, String operator, String variable, String value) { | |
this.type = type; | |
this.operator = operator; | |
this.variable = variable; | |
this.value = value; | |
} | |
} | |
public static final class Match extends StringFilter { | |
public String pattern; | |
public Match(String type, String operator, String variable, String pattern) { | |
this.type = type; | |
this.operator = operator; | |
this.variable = variable; | |
this.pattern = pattern; | |
} | |
} | |
public static final class FilterDeserializer extends JsonDeserializer<Filter> { | |
@Override | |
public Filter deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { | |
ObjectCodec oc = jsonParser.getCodec(); | |
JsonNode node = oc.readTree(jsonParser); | |
String type = node.path("type").asText(); | |
String operator = node.path("operator").asText(); | |
switch (type) { | |
case "string" : | |
if (Strings.isNullOrEmpty(operator)) { | |
operator = "equals"; | |
} | |
switch (operator) { | |
case "equals" : | |
return new Equality(type, operator, node.path("variable").asText(), node.path("value").asText()); | |
case "matches" : | |
return new Match(type, operator, node.path("variable").asText(), node.path("pattern").asText()); | |
default: | |
throw new IllegalArgumentException("Unknown operator"); | |
} | |
default: | |
throw new IllegalArgumentException("Unknown filter type"); | |
} | |
} | |
} | |
public static void main(String[] args) { | |
Filter f = JSONUtil.fromString("{\"type\":\"string\",\"variable\":\"foo\",\"value\":\"bar\"}", Filter.class); | |
System.out.println(JSONUtil.toString(f)); | |
f = JSONUtil.fromString("{\"type\":\"string\",\"variable\":\"foo\",\"operator\":\"matches\",\"pattern\":\"bar*\"}", Filter.class); | |
System.out.println(JSONUtil.toString(f)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment