bluelinelabs / bluelinelabs/LoganSquare

MapCollectionType parse and serialize assume type String.class as the key

Open
#153 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
3.2k
Forks
303
PR merge metrics
No merged PRs in 30d

Description

Given the following simple class

```
@JsonObject
public class JsonRpcRequests {
@JsonField
Map requests;
}
```

The following mapper code is generated

```
public final class JsonRpcRequests$$JsonObjectMapper extends JsonMapper {
private static final JsonMapper COM_TREVJONEZ_RETRORX_BUSY_API_APIREQUEST__JSONOBJECTMAPPER = LoganSquare.mapperFor(ApiRequest.class);

private static TypeConverter java_lang_Class_type_converter;

@Override
public JsonRpcRequests parse(JsonParser jsonParser) throws IOException {
JsonRpcRequests instance = new JsonRpcRequests();
if (jsonParser.getCurrentToken() == null) {
jsonParser.nextToken();
}
if (jsonParser.getCurrentToken() != JsonToken.START_OBJECT) {
jsonParser.skipChildren();
return null;
}
while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
String fieldName = jsonParser.getCurrentName();
jsonParser.nextToken();
parseField(instance, fieldName, jsonParser);
jsonParser.skipChildren();
}
return instance;
}

@Override
public void parseField(JsonRpcRequests instance, String fieldName, JsonParser jsonParser) throws IOException {
if ("requests".equals(fieldName)) {
if (jsonParser.getCurrentToken() == JsonToken.START_OBJECT) {
HashMap map1 = new HashMap();
while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
String key1 = jsonParser.getText();
jsonParser.nextToken();
if (jsonParser.getCurrentToken() == JsonToken.VALUE_NULL) {
map1.put(key1, null);
} else {
map1.put(key1, COM_TREVJONEZ_RETRORX_BUSY_API_APIREQUEST__JSONOBJECTMAPPER.parse(jsonParser));
}
}
instance.requests = map1;
} else {
instance.requests = null;
}
}
}

@Override
public void serialize(JsonRpcRequests object, JsonGenerator jsonGenerator, boolean writeStartAndEnd) throws IOException {
if (writeStartAndEnd) {
jsonGenerator.writeStartObject();
}
final Map lslocalrequests = object.requests;
if (lslocalrequests != null) {
jsonGenerator.writeFieldName("requests");
jsonGenerator.writeStartObject();
for (Map.Entry entry1 : lslocalrequests.entrySet()) {
jsonGenerator.writeFieldName(entry1.getKey().toString());
if (entry1.getValue() != null) {
COM_TREVJONEZ_RETRORX_BUSY_API_APIREQUEST__JSONOBJECTMAPPER.serialize(entry1.getValue(), jsonGenerator, true);
}
}
jsonGenerator.writeEndObject();
}
if (writeStartAndEnd) {
jsonGenerator.writeEndObject();
}
}

private static final TypeConverter getjava_lang_Class_type_converter() {
if (java_lang_Class_type_converter == null) {
java_lang_Class_type_converter = LoganSquare.typeConverterFor(Class.class);
}
return java_lang_Class_type_converter;
}
}
```

The processor generates the serializing and parsing code with the assumption that the type will be of `String.class` ( [Here](https://github.com/bluelinelabs/LoganSquare/blob/development/processor/src/main/java/com/bluelinelabs/logansquare/processor/type/collection/MapCollectionType.java#L42), [Here](https://github.com/bluelinelabs/LoganSquare/blob/development/processor/src/main/java/com/bluelinelabs/logansquare/processor/type/collection/MapCollectionType.java#L72) & [Here](https://github.com/bluelinelabs/LoganSquare/blob/development/processor/src/main/java/com/bluelinelabs/logansquare/processor/type/collection/MapCollectionType.java#L75) )

It seems as though any provided or default `TypeConverter` should be dispatched for the purpose of serialization [here](https://github.com/bluelinelabs/LoganSquare/blob/development/processor/src/main/java/com/bluelinelabs/logansquare/processor/type/collection/MapCollectionType.java#L88), as apposed to the current `.toString()` approach.

Based on the unused methods in the generated code and the logic [here](https://github.com/bluelinelabs/LoganSquare/blob/development/processor/src/main/java/com/bluelinelabs/logansquare/processor/ObjectMapperInjector.java#L347), it would seem like this was your eventual intent.

I plan to work on a pull request for this in the morning however if my understanding of the issue and speculation of your intent are wrong please let me know at your earliest convenience.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reading the referenced MapCollectionType locations and the ObjectMapperInjector logic around line 347, then compare them with the generated JsonRpcRequests mapper shown in the issue. Done means map parsing and serialization no longer assume String.class keys and the applicable TypeConverter is dispatched as intended.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.