The Java output currently has external dependencies.
To support JSON deserialization, we will be utilizing the @SerializedName
annotation in Gson to facilitate the conversion between Plank types and JSON objects.
For properties that are not required (i.e. nullable), we will annotate them with @Nullable
.
Properties that are required, we will annotate them with @NonNull
.
A builder class is generated as a subclass. Use builders to create brand new instances of the model, or to make copies of existing instances.
Construct a new instance: Pin pin = Pin.builder().build();
Generate a builder from an existing model: Pin anotherPin = pin.toBuilder().build();
It is sometimes necessary to determine whether a field has been explicitly set. For example, in order to distinguish between a boolean field being explicitly set to false as opposed to just having a default value of false.
pin.getInStockIsSet() // Returns true only if pin.setInStock(true/false) has been called before
If the model has been deserialized from Json, pin.getInStockIsSet()
will return true only if the field was present in the Json.
A Gson TypeAdapterFactory is generated as a sublcass. You should register this TypeAdapterFactory in order in order to guarantee proper behavior for merging and field “is set” checking, as well as for performance benefits.
gsonBuilder.registerTypeAdapterFactory(new Pin.PinTypeAdapterFactory());
An enum class is created to represent enums defined in the schema.
Schema Property Type | Java Type |
---|---|
String | String |
Boolean | Boolean |
Integer | Integer |
Number | Double |
Date-time Property (String variant) | java.util.Date |
URI Property (String variant) | String |
JSON Pointer Property ($ref ) |
ModelType |
Array Property | List<Object> |
Array Property with Item types | List<ModelType> |
Set Property (unique array) | Set<Object> |
Set Property (unique array) with items | Set<ModelType> |
Object Property | Map<String, Object> |
Object Property with item types | Map<String, ModelType> |
Object Property with primitive item type | Map<String, Integer> , Map<String, Float> , Map<String, Boolean> , Map<String, String> |
Algebraic Data Type (ADT)(oneOf) | ADT Class (ModelType + Property name) |
Nullable Property | @Nullable T |
Integer Enum | @IntDef |
String Enum | @StringDef |
{
"id": "pin.json",
"title": "pin",
"description" : "Schema definition of Pinterest Pin",
"$schema": "http://json-schema.org/schema#",
"type": "object",
"properties": {
"id" : { "type": "string" },
"link" : {
"type": "string",
"format": "uri"
},
"url" : {
"type": "string",
"format": "uri"
},
"creator": {
"type": "object",
"additionalProperties": { "$ref": "user.json" }
},
"board": { "$ref": "board.json" },
"created_at" : {
"type": "string",
"format": "date-time"
},
"note" : { "type": "string" },
"color" : { "type": "string" },
"counts": {
"type": "object",
"additionalProperties": { "type": "integer" }
},
"media": {
"type": "object",
"additionalProperties": { "type": "string" }
},
"attribution": {
"type": "object",
"additionalProperties": { "type": "string" }
},
"description" : { "type": "string" },
"image": { "$ref": "image.json" },
"tags": {
"type": "array",
"items": { "type": "object" }
},
"visual_search_attrs": {
"type": "object"
},
"attribution_objects": {
"type": "array",
"items": {
"oneOf": [{
"$ref": "board.json"
}, {
"$ref": "user.json"
}]
}
},
"in_stock" : {
"type": "integer",
"enum": [
{ "default" : -1, "description" : "unknown" },
{ "default" : 0, "description" : "out_of_stock" },
{ "default" : 1, "description" : "in_stock" }
]
}
},
"required": ["id", "created_at", "creator"]
}
public class Pin {
public enum PinInStock {
@SerializedName("-1") UNKNOWN(-1),
@SerializedName("0") OUT_OF_STOCK(0),
@SerializedName("1") IN_STOCK(1);
private final int value;
PinInStock(int value) {
this.value = value;
}
public int getValue() {
return this.value;
}
}
public static final String TYPE = "pin";
@SerializedName("attribution") private @Nullable Map<String, String> attribution;
@SerializedName("attribution_objects") private @Nullable List<PinAttributionObjects> attributionObjects;
@SerializedName("board") private @Nullable Board board;
@SerializedName("color") private @Nullable String color;
@SerializedName("counts") private @Nullable Map<String, Integer> counts;
@SerializedName("created_at") private @NonNull Date createdAt;
@SerializedName("creator") private @NonNull Map<String, User> creator;
@SerializedName("description") private @Nullable String description;
@SerializedName("id") private @NonNull String uid;
@SerializedName("image") private @Nullable Image image;
@SerializedName("in_stock") private @Nullable PinInStock inStock;
@SerializedName("link") private @Nullable String link;
@SerializedName("media") private @Nullable Map<String, String> media;
@SerializedName("note") private @Nullable String note;
@SerializedName("tags") private @Nullable List<Map<String, Object>> tags;
@SerializedName("url") private @Nullable String url;
@SerializedName("visual_search_attrs") private @Nullable Map<String, Object> visualSearchAttrs;
private static final int ATTRIBUTION_INDEX = 0;
private static final int ATTRIBUTION_OBJECTS_INDEX = 1;
private static final int BOARD_INDEX = 2;
// ... omitted for brevity
private static final int VISUAL_SEARCH_ATTRS_INDEX = 16;
private boolean[] _bits;
private Pin(
@Nullable Map<String, String> attribution,
@Nullable List<PinAttributionObjects> attributionObjects,
// ... omitted for brevity
boolean[] _bits
) {
this.attribution = attribution;
this.attributionObjects = attributionObjects;
// ... omitted for brevity
this._bits = _bits;
}
@NonNull
public static Pin.Builder builder() {
return new Pin.Builder();
}
@NonNull
public Pin.Builder toBuilder() {
return new Pin.Builder(this);
}
@NonNull
public Pin mergeFrom(@NonNull Pin model) {
Pin.Builder builder = this.toBuilder();
builder.mergeFrom(model);
return builder.build();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Pin that = (Pin) o;
return Objects.equals(this.inStock, that.inStock) &&
Objects.equals(this.attribution, that.attribution) &&
// ... omitted for brevity
Objects.equals(this.visualSearchAttrs, that.visualSearchAttrs);
}
@Override
public int hashCode() {
return Objects.hash(attribution,
attributionObjects,
// ... omitted for brevity
visualSearchAttrs);
}
/**
* GETTERS
*/
public @Nullable Map<String, String> getAttribution() {
return this.attribution;
}
public @Nullable List<PinAttributionObjects> getAttributionObjects() {
return this.attributionObjects;
}
// ...omitted for brevity
public @Nullable String getUrl() {
return this.url;
}
public @Nullable Map<String, Object> getVisualSearchAttrs() {
return this.visualSearchAttrs;
}
/**
* IsSet CHECKERS
*/
public boolean getAttributionIsSet() {
return this._bits.length > ATTRIBUTION_INDEX && this._bits[ATTRIBUTION_INDEX];
}
public boolean getAttributionObjectsIsSet() {
return this._bits.length > ATTRIBUTION_OBJECTS_INDEX && this._bits[ATTRIBUTION_OBJECTS_INDEX];
}
// ... omitted for brevity
/**
* BUILDER
*/
public static class Builder {
private @Nullable Map<String, String> attribution;
private @Nullable List<PinAttributionObjects> attributionObjects;
// ... omitted for brevity
private @Nullable Map<String, Object> visualSearchAttrs;
private boolean[] _bits;
private Builder() {
this._bits = new boolean[17];
}
private Builder(@NonNull Pin model) {
this.attribution = model.attribution;
this.attributionObjects = model.attributionObjects;
// ... omitted for brevity
this._bits = model._bits;
}
@NonNull
public Builder setAttribution(@Nullable Map<String, String> value) {
this.attribution = value;
if (this._bits.length > ATTRIBUTION_INDEX) {
this._bits[ATTRIBUTION_INDEX] = true;
}
return this;
}
// ... the rest of the fields are omitted for brevity
public @Nullable Map<String, String> getAttribution() {
return this.attribution;
}
// ... the rest of the fields are omitted for brevity
@NonNull
public Pin build() {
return new Pin(
this.attribution,
this.attributionObjects,
// ... omitted for brevity
this._bits
);
}
public void mergeFrom(@NonNull Pin model) {
if (model._bits.length > ATTRIBUTION_INDEX && model._bits[ATTRIBUTION_INDEX]) {
this.attribution = model.attribution;
this._bits[ATTRIBUTION_INDEX] = true;
}
if (model._bits.length > ATTRIBUTION_OBJECTS_INDEX && model._bits[ATTRIBUTION_OBJECTS_INDEX]) {
this.attributionObjects = model.attributionObjects;
this._bits[ATTRIBUTION_OBJECTS_INDEX] = true;
}
// ... omitted for brevity
}
}
/**
* TypeAdapterFactory
*/
public static class PinTypeAdapterFactory implements TypeAdapterFactory {
@Nullable
@Override
public <T> TypeAdapter<T> create(@NonNull Gson gson, @NonNull TypeToken<T> typeToken) {
if (!Pin.class.isAssignableFrom(typeToken.getRawType())) {
return null;
}
return (TypeAdapter<T>) new PinTypeAdapter(gson);
}
}
/**
* TypeAdapterFactory
*/
private static class PinTypeAdapter extends TypeAdapter<Pin> {
// ... omitted for brevity
}
/**
* Algabraeic Data Type
*/
public static final class PinAttributionObjects {
private @Nullable Board value0;
private @Nullable User value1;
private PinAttributionObjects() {
}
public PinAttributionObjects(@NonNull Board value) {
this.value0 = value;
}
public PinAttributionObjects(@NonNull User value) {
this.value1 = value;
}
@Nullable
public <R> R matchPinAttributionObjects(PinAttributionObjectsMatcher<R> matcher) {
if (value0 != null) {
return matcher.match(value0);
}
if (value1 != null) {
return matcher.match(value1);
}
return null;
}
public static class PinAttributionObjectsTypeAdapterFactory implements TypeAdapterFactory {
@Nullable
@Override
public <T> TypeAdapter<T> create(@NonNull Gson gson, @NonNull TypeToken<T> typeToken) {
if (!PinAttributionObjects.class.isAssignableFrom(typeToken.getRawType())) {
return null;
}
return (TypeAdapter<T>) new PinAttributionObjectsTypeAdapter(gson);
}
}
private static class PinAttributionObjectsTypeAdapter extends TypeAdapter<PinAttributionObjects> {
private final Gson gson;
private TypeAdapter<Board> boardTypeAdapter;
private TypeAdapter<User> userTypeAdapter;
public PinAttributionObjectsTypeAdapter(Gson gson) {
this.gson = gson;
}
@Override
public void write(@NonNull JsonWriter writer, PinAttributionObjects value) throws IOException {
writer.nullValue();
}
@Nullable
@Override
public PinAttributionObjects read(@NonNull JsonReader reader) throws IOException {
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
return null;
}
if (reader.peek() == JsonToken.BEGIN_OBJECT) {
JsonObject jsonObject = this.gson.fromJson(reader, JsonObject.class);
String type;
try {
type = jsonObject.get("type").getAsString();
} catch (Exception e) {
return new PinAttributionObjects();
}
if (type == null) {
return new PinAttributionObjects();
}
switch (type) {
case ("board"):
if (this.boardTypeAdapter == null) {
this.boardTypeAdapter = this.gson.getAdapter(Board.class).nullSafe();
}
return new PinAttributionObjects(boardTypeAdapter.fromJsonTree(jsonObject));
case ("user"):
if (this.userTypeAdapter == null) {
this.userTypeAdapter = this.gson.getAdapter(User.class).nullSafe();
}
return new PinAttributionObjects(userTypeAdapter.fromJsonTree(jsonObject));
default:
return new PinAttributionObjects();
}
}
reader.skipValue();
return new PinAttributionObjects();
}
}
public interface PinAttributionObjectsMatcher<R> {
R match(@NonNull Board value0);
R match(@NonNull User value1);
}
}
}