Skip to content

Instantly share code, notes, and snippets.

@libetl
Last active July 20, 2016 20:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save libetl/853029faf7999c98159f36d1c229c961 to your computer and use it in GitHub Desktop.
Save libetl/853029faf7999c98159f36d1c229c961 to your computer and use it in GitHub Desktop.
Jackson unmarshalling with Immutable objects (jackson-databind >= 2.7.6 or >= 2.8.1 or >= 2.9 or >=3)
@JsonDeserialize (builder = A.Builder.class)
public class A { private final String b; private final int c;
@JsonPOJOBuilder (withPrefix = "")
public static class Builder {
private String b;
private int c;
@Override
public A build () {
return new A (this.b, this.c);
}
public Builder b (final String b) {
this.b = b;
return this;
}
public Builder c (final int c) {
this.c = c;
return this;
}
}
private A (final String b, final int c) {
this.b = b;
this.c = c;
}
}
@JsonDeserialize (builder = TripSegment.Builder.class)
public class TripSegment { private final TripSegment.TransportMode mode; private final SegmentDetails segmentDetails;
@JsonPOJOBuilder (withPrefix = "")
public static class Builder {
private TripSegment.TransportMode mode;
private SegmentDetails segmentDetails;
@Override
public TripSegment build () {
return new TripSegment (this.mode, this.segmentDetails);
}
public Builder mode (final TripSegment.TransportMode mode) {
this.mode = mode;
return this;
}
@JsonTypeInfo (use = JsonTypeInfo.Id.CUSTOM, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "mode", visible = true)
@JsonTypeIdResolver (TripSegment.TransportMode.ModeTypeIdResolver.class)
public Builder segmentDetails (final SegmentDetails segmentDetails) {
this.segmentDetails = segmentDetails;
return this;
}
}
private A (final TripSegment.TransportMode mode, final SegmentDetails segmentDetails) {
this.mode = mode;
this.segmentDetails = segmentDetails;
}
public enum TransportMode {
FLIGHT(FlightSegmentDetails.class),
TRAIN(TrainSegmentDetails.class),
BOAT(BoatSegmentDetails.class),
CAR_SHARING(CarSharingSegmentDetails.class),
LOCAL_TRANSIT(LocalTransitSegmentDetails.class);
TransportMode(Class<? extends SegmentDetails> detailsClass);
<T> Class<T extends SegmentDetails> getDetailsClass () {
return (T) detailsClass;
}
public static TransportMode fromDetailsClass (Class<? extends SegmentDetails> detailsClass) {
for (TransportMode tm : TransportMode.values ()) {
if (tm.getDetailsClass () == detailsClass) {
return tm;
}
}
throw new IllegalArgumentException ("not found");
}
public static class ModeTypeIdResolver implements TypeIdResolver {
@Override
public void init (JavaType baseType) {
}
@SuppressWarnings ("unchecked")
@Override
public String idFromValue (Object value) {
if (! (value instanceof TripSegment)) {
return null;
}
return TransportMode.fromDetailsClass ((Class<SegmentDetails>) value.getClass ()).name ();
}
@Override
public String idFromValueAndType (Object value, Class<?> suggestedType) {
return this.idFromValue (value);
}
@Override
public String idFromBaseType () {
return null;
}
@Override
public JavaType typeFromId (DatabindContext context, String id) throws IOException {
return TypeFactory.defaultInstance ().constructType (TransportMode.valueOf (id).getDetailsClass ());
}
@Override
public String getDescForKnownTypeIds () {
return "TransportMode";
}
@Override
public Id getMechanism () {
return JsonTypeInfo.Id.CUSTOM;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment