Skip to content

Commit

Permalink
Merge pull request #178 from chisui/issue-177
Browse files Browse the repository at this point in the history
fix for #177
  • Loading branch information
ruslansennov authored Jan 12, 2021
2 parents cc37f24 + e07487e commit 27c4007
Show file tree
Hide file tree
Showing 6 changed files with 1,745 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ class MapDeserializer extends MaplikeDeserializer<Map<?, ?>> {
@Override
public Map<?, ?> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
final java.util.List<Tuple2<Object, Object>> result = new java.util.ArrayList<>();
while (p.nextToken() != JsonToken.END_OBJECT) {
if (p.getCurrentToken() != JsonToken.FIELD_NAME) {
p.nextToken();
}
while (p.getCurrentToken() != JsonToken.END_OBJECT) {
String name = p.getCurrentName();
Object key = keyDeserializer.deserializeKey(name, ctxt);
JsonToken t = p.nextToken();
Expand All @@ -70,6 +73,7 @@ class MapDeserializer extends MaplikeDeserializer<Map<?, ?>> {
value = elementDeserializer.deserializeWithType(p, ctxt, elementTypeDeserializer);
}
result.add(Tuple.of(key, value));
p.nextToken();
}
if (SortedMap.class.isAssignableFrom(handledType())) {
return TreeMap.ofEntries(keyComparator, result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,18 @@ public void resolve(DeserializationContext ctxt) throws JsonMappingException {
@Override
public Multimap<?, ?> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
final java.util.List<Tuple2<Object, Object>> result = new java.util.ArrayList<>();
while (p.nextToken() != JsonToken.END_OBJECT) {
if (p.getCurrentToken() != JsonToken.FIELD_NAME) {
p.nextToken();
}
while (p.getCurrentToken() != JsonToken.END_OBJECT) {
String name = p.getCurrentName();
Object key = keyDeserializer.deserializeKey(name, ctxt);
p.nextToken();
ArrayList<?> list = (ArrayList<?>) containerDeserializer.deserialize(p, ctxt);
for (Object elem : list) {
result.add(Tuple.of(key, elem));
}
p.nextToken();
}
if (TreeMultimap.class.isAssignableFrom(handledType())) {
return TreeMultimap.withSeq().ofEntries(keyComparator, result);
Expand Down
1 change: 1 addition & 0 deletions src/test/java/generator/Generator.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public static void main(String[] args) throws IOException {
cases.put("RightEitherOfTuple", Either.right(Tuple.of("A", "B")));

SimplePojo.generate(cases);
JsonCreatorPojo.generate(cases);
ParameterizedPojo.generate(cases);
PolymorphicPojo.generate();
ExtFieldsPojo.generate();
Expand Down
68 changes: 68 additions & 0 deletions src/test/java/generator/JsonCreatorPojo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package generator;

import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import io.vavr.collection.PriorityQueue;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import javax.lang.model.element.Modifier;
import java.io.File;
import java.io.IOException;

import static generator.utils.Initializer.initMapper;
import static generator.utils.Initializer.initValue;
import static generator.utils.PoetHelpers.jsonCreatorPojo;
import static generator.utils.Serializer.expectedJson;

/**
* @author <a href="mailto:[email protected]">Philipp Dargel</a>
*/
public class JsonCreatorPojo {

public static void main(String[] args) throws IOException {
java.util.Map<String, Object> cases = new java.util.HashMap<>();
cases.put("PriorityQueueOfString", PriorityQueue.of("A", "B"));
generate(cases);
}

static void generate(java.util.Map<String, Object> cases) throws IOException {

TypeSpec.Builder pojoTest = TypeSpec.classBuilder("JsonCreatorPojoTest")
.addJavadoc("generated\n")
.addModifiers(Modifier.PUBLIC);
initMapper(pojoTest, "MAPPER");

cases.forEach((k, v) -> addCase(pojoTest, k, v));

JavaFile javaFile = JavaFile.builder("io.vavr.jackson.generated", pojoTest.build())
.indent(" ")
.skipJavaLangImports(true)
.build();

javaFile.writeTo(new File("src/test/java"));
}

private static void addCase(TypeSpec.Builder builder, String pojoName, Object value) {
addCase(builder, pojoName, value, 0);
}

private static void addCase(TypeSpec.Builder builder, String pojoName, Object value, int opts) {

MethodSpec.Builder testBuilder = MethodSpec.methodBuilder("testJsonCreator" + pojoName)
.addAnnotation(Test.class)
.addException(ClassName.get(Exception.class));
TypeName valueTypeName = initValue(testBuilder, "src", value);
MethodSpec testSpec = testBuilder
.addStatement("$T json = MAPPER.writeValueAsString($L.create(src))", ClassName.get(String.class), pojoName)
.addStatement("$T.assertEquals(json, $S)", ClassName.get(Assertions.class), expectedJson(value, opts))
.addStatement("$L restored = MAPPER.readValue(json, $L.class)", pojoName, pojoName)
.addStatement("$T.assertEquals(src, restored.getValue())", ClassName.get(Assertions.class))
.build();
builder.addMethod(testSpec);
builder.addType(jsonCreatorPojo(pojoName, valueTypeName));
}
}
60 changes: 47 additions & 13 deletions src/test/java/generator/utils/PoetHelpers.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package generator.utils;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import com.squareup.javapoet.*;

import javax.lang.model.element.Modifier;
Expand All @@ -10,21 +12,53 @@
public class PoetHelpers {

public static TypeSpec simplePojo(String pojoName, TypeName valueTypeName) {
return pojoClass(pojoName, valueTypeName)
.addMethod(getter(valueTypeName).build())
.addMethod(setter(pojoName, valueTypeName))
.build();
}

public static TypeSpec jsonCreatorPojo(String pojoName, TypeName valueTypeName) {
return pojoClass(pojoName, valueTypeName)
.addMethod(getter(valueTypeName)
.addAnnotation(JsonValue.class)
.build())
.addMethod(creator(pojoName, valueTypeName))
.build();
}

private static MethodSpec creator(String pojoName, TypeName valueTypeName) {
return MethodSpec.methodBuilder("create")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addAnnotation(JsonCreator.class)
.returns(ClassName.get("", pojoName))
.addParameter(ParameterSpec.builder(valueTypeName, "v").build())
.addStatement(pojoName + " i = new " + pojoName + "()")
.addStatement("i.v = v")
.addStatement("return i")
.build();
}

private static TypeSpec.Builder pojoClass(String pojoName, TypeName valueTypeName) {
return TypeSpec.classBuilder(pojoName)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addField(FieldSpec.builder(valueTypeName, "v", Modifier.PRIVATE).build())
.addMethod(MethodSpec.methodBuilder("getValue")
.addModifiers(Modifier.PUBLIC)
.returns(valueTypeName)
.addStatement("return v")
.build())
.addMethod(MethodSpec.methodBuilder("setValue")
.addModifiers(Modifier.PUBLIC)
.returns(ClassName.get("", pojoName))
.addParameter(ParameterSpec.builder(valueTypeName, "v").build())
.addStatement("this.v = v")
.addStatement("return this")
.build())
.addField(FieldSpec.builder(valueTypeName, "v", Modifier.PRIVATE).build());
}

private static MethodSpec.Builder getter(TypeName valueTypeName) {
return MethodSpec.methodBuilder("getValue")
.addModifiers(Modifier.PUBLIC)
.returns(valueTypeName)
.addStatement("return v");
}

private static MethodSpec setter(String pojoName, TypeName valueTypeName) {
return MethodSpec.methodBuilder("setValue")
.addModifiers(Modifier.PUBLIC)
.returns(ClassName.get("", pojoName))
.addParameter(ParameterSpec.builder(valueTypeName, "v").build())
.addStatement("this.v = v")
.addStatement("return this")
.build();
}
}
Loading

0 comments on commit 27c4007

Please sign in to comment.