Skip to content

Instantly share code, notes, and snippets.

@krzysztof-miemiec
Last active March 5, 2019 11:34
Show Gist options
  • Save krzysztof-miemiec/d6b6449b0e0e56e4a57e4ed7bc367aab to your computer and use it in GitHub Desktop.
Save krzysztof-miemiec/d6b6449b0e0e56e4a57e4ed7bc367aab to your computer and use it in GitHub Desktop.
List parsing done with LoganSquare and Realm database.
/**
* Sample class showing how to use type converter in this gist.
*
* @author Krzysztof Miemiec
*/
@JsonObject
public class Album extends RealmObject {
@PrimaryKey
@JsonField
private String id;
@JsonField(typeConverter = StringRealmListConverter.class)
private RealmList<RealmString> imageUrls;
public RealmList<RealmString> getImageUrls() {
return imageUrls;
}
public void setImageUrls(RealmList<RealmString> imageUrls) {
this.imageUrls = imageUrls;
}
}
/**
* The universal converter for RealmList.
* You can use this with RealmObjects:
* 1. Annotated with @JsonObject
* 2. With custom converters, such as RealmString below.
* @author Krzysztof Miemiec
*/
public class RealmListConverter<T extends RealmObject> implements TypeConverter<RealmList<T>> {
/**
* This is useful if you want to use this converter for sending just a simple part of object back to server.
* For example:
* Server gives you this:
* [{"id": 1, "description": "Doxie!", "image": "http://imgur.com/r/Dachshund/OGKuGTR"},
* {"id": 33, "description": "Second doxie!", "image": "http://imgur.com/r/Dachshund/nU3PlyO"}]
* You send back:
* [1, 33]
*/
public interface SingleFieldSerialization<T> {
Object getValue(T object);
}
private Class<T> clazz;
private TypeConverter<T> typeConverter;
private JsonMapper<T> mapper;
private SingleFieldSerialization<T> serializer;
public RealmListConverter(Class<T> clazz) {
this.clazz = clazz;
}
public RealmListConverter(Class<T> clazz, SingleFieldSerialization<T> serializer){
this.clazz = clazz;
this.serializer = serializer;
}
private void init() {
if (typeConverter == null && mapper == null) {
try {
typeConverter = LoganSquare.typeConverterFor(clazz);
} catch (NoSuchTypeConverterException e) {
mapper = LoganSquare.mapperFor(clazz);
}
}
}
@Override
public RealmList<T> parse(JsonParser jsonParser) throws IOException {
init();
RealmList<T> list = new RealmList<>();
if (jsonParser.getCurrentToken() == JsonToken.START_ARRAY) {
while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
T object = typeConverter != null ? typeConverter.parse(jsonParser) : mapper.parse(jsonParser);
if (object != null) {
list.add(object);
}
}
}
return list;
}
@Override
public void serialize(RealmList<T> list, String fieldName, boolean writeFieldNameForObject, JsonGenerator jsonGenerator) throws IOException {
if (writeFieldNameForObject) {
if (list == null) {
return;
}
jsonGenerator.writeFieldName(fieldName);
}
if (list == null) {
jsonGenerator.writeNull();
return;
}
jsonGenerator.writeStartArray();
if (serializer != null) {
JsonMapper<Object> objectMapper = LoganSquare.mapperFor(Object.class);
for (T object : list) {
if (object != null) {
objectMapper.serialize(serializer.getValue(object), jsonGenerator, true);
} else {
jsonGenerator.writeNull();
}
}
} else {
init();
for (T object : list) {
if (object != null) {
if (typeConverter != null) {
typeConverter.serialize(object, fieldName, false, jsonGenerator);
} else {
mapper.serialize(object, jsonGenerator, true);
}
} else {
jsonGenerator.writeNull();
}
}
}
jsonGenerator.writeEndArray();
}
}
/**
* A wrapper for holding Strings in RealmList. Shame.
*
* @author Krzysztof Miemiec
*/
public class RealmString extends RealmObject {
public RealmString(String string) {
this.string = string;
}
public RealmString() {
}
private String string;
public String getString() {
return string;
}
public void setString(String string) {
this.string = string;
}
}
/**
* A simple converter for RealmString wrapper.
*
* @author Krzysztof Miemiec
*/
public class RealmStringConverter extends StringBasedTypeConverter<RealmString> {
@Override
public RealmString getFromString(String string) {
return new RealmString(string);
}
@Override
public String convertToString(RealmString realmString) {
return realmString.getString();
}
}
/**
* All you need to serialize/deserialize RealmList of RealmStrings.
* It can be used thanks to that line:
* LoganSquare.registerTypeConverter(RealmString.class, new RealmStringConverter());
* Put it in place where you initialize LoganSquare.
*
* @author Krzysztof Miemiec
*/
public class StringRealmListConverter extends RealmListConverter<RealmString> {
public StringRealmListConverter() {
super(RealmString.class);
}
}
@peterbetos
Copy link

peterbetos commented Oct 10, 2016

Whoops, sorry forgot about this. I solved mine using the ParameterizedType implementation. You can refer to my implementation below:
https://gist.github.com/peterbetos/fb42ac87c31accd2efc43e33ddaaecc3

But yeah, @krzysztof-miemiec, no solution so far regarding the extensions.
Unless.... someone will do annotation processing for it? :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment