bluelinelabs / LoganSquare

Screaming fast JSON parsing and serialization library for Android.
Apache License 2.0
3.21k stars 306 forks source link

not able to create converter for generic list #225

Open ntimesc opened 6 years ago

ntimesc commented 6 years ago

i have following class that i am using it to send request to the server. I have used list as generic so that any list can be mapped using single method.

@JsonObject
public class TRequest<T> {

    @JsonField(name= "request" , typeConverter = TRequestConverter.class)
    private RealmList<T> requestList;

    public RealmList<T> getRequestList() {
        return requestList;
    }

    public void setRequestList(RealmList<T> requestList) {
        this.requestList = requestList;
    }
}

following is the code to create request list

 TRequest<Fitness> request = new TRequest<Fitness>();
        Fitness fitness = new Fitness();
        fitness.setActivity_id("123");
        fitness.set_id("1");
        RealmList<Fitness> fitnesses = new RealmList<Fitness>();
        fitnesses.add(fitness);
        request.setRequestList(fitnesses);

        try {
            String data = LoganSquare.serialize(request);
            Log.e("LoginActivity",data);
        } catch (IOException e) {
            e.printStackTrace();
        }

here is my converter code

@JsonObject
public class TRequest<T> implements RealmModel {

    @JsonField(name= "request" , typeConverter = TRequestConverter.class)
    private RealmList<T> requestList;

    public RealmList<T> getRequestList() {
        return requestList;
    }

    public void setRequestList(RealmList<T> requestList) {
        this.requestList = requestList;
    }
}

and the realm list converter is

public class RealmListConverter<T extends RealmModel> implements TypeConverter<RealmList<T>> {

    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();
    }
}

but i am getting error

error: incompatible types: RealmList cannot be converted to RealmList where T is a type-variable: T extends Object declared in class TRequest$$JsonObjectMapper  
error: incompatible types: RealmList cannot be converted to RealmList where T is a type-variable: T extends Object declared in class TRequest$$JsonObjectMapper  
Alexander-- commented 6 years ago

@ntimesc this is due to the lack of proper typecasting support in LoganSquare-generated code.

Just give up on it and use a fixed element type.