117 lines
4.9 KiB
Java
117 lines
4.9 KiB
Java
package io.gitlab.jfronny.gson.compile.processor.adapter.impl;
|
|
|
|
import com.squareup.javapoet.*;
|
|
import io.gitlab.jfronny.commons.data.MutCollection;
|
|
import io.gitlab.jfronny.gson.compile.processor.Cl;
|
|
import io.gitlab.jfronny.gson.compile.processor.core.TypeHelper;
|
|
import io.gitlab.jfronny.gson.compile.processor.adapter.Adapter;
|
|
|
|
import javax.lang.model.element.Modifier;
|
|
import javax.lang.model.type.DeclaredType;
|
|
import javax.lang.model.type.TypeMirror;
|
|
import java.io.IOException;
|
|
import java.util.*;
|
|
|
|
public class CollectionAdapter extends Adapter<CollectionAdapter.Hydrated> {
|
|
@Override
|
|
public Hydrated instantiate() {
|
|
return new Hydrated();
|
|
}
|
|
|
|
public class Hydrated extends Adapter<CollectionAdapter.Hydrated>.Hydrated {
|
|
private static final Map<Class<?>, List<Class<?>>> SUPPORTED = MutCollection.mapOf(
|
|
Set.class, List.of(LinkedHashSet.class, HashSet.class, TreeSet.class),
|
|
List.class, List.of(ArrayList.class, LinkedList.class),
|
|
Queue.class, List.of(ArrayDeque.class, LinkedList.class),
|
|
Deque.class, List.of(ArrayDeque.class)
|
|
);
|
|
|
|
private DeclaredType type;
|
|
private TypeName implType;
|
|
private TypeMirror componentType;
|
|
|
|
@Override
|
|
public boolean applies() {
|
|
return type != null;
|
|
}
|
|
|
|
@Override
|
|
protected void afterHydrate() {
|
|
type = TypeHelper.asDeclaredType(super.type);
|
|
componentType = null;
|
|
if (type == null) return;
|
|
List<? extends TypeMirror> typeArguments = type.getTypeArguments();
|
|
if (typeArguments.size() == 0) {
|
|
type = null;
|
|
} else {
|
|
componentType = typeArguments.get(0);
|
|
String ts = TypeHelper.asDeclaredType(typeUtils.erasure(type)).asElement().toString();
|
|
for (Map.Entry<Class<?>, List<Class<?>>> entry : SUPPORTED.entrySet()) {
|
|
if (entry.getKey().getCanonicalName().equals(ts)) {
|
|
implType = TypeName.get(entry.getValue().get(0));
|
|
return;
|
|
}
|
|
for (Class<?> klazz : entry.getValue()) {
|
|
if (klazz.getCanonicalName().equals(ts)) {
|
|
implType = TypeName.get(klazz);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
type = null;
|
|
componentType = null;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void generateWrite(Runnable writeGet) {
|
|
code.addStatement("writer.beginArray()");
|
|
code.add("for ($T $N : ", componentType, argName);
|
|
writeGet.run();
|
|
code.beginControlFlow(")")
|
|
.beginControlFlow("if ($N == null)", argName)
|
|
.addStatement("if (writer.getSerializeNulls()) writer.nullValue()")
|
|
.nextControlFlow("else");
|
|
generateWrite(code, componentType, argName, componentType.getAnnotationMirrors(), () -> code.add(argName));
|
|
code.endControlFlow().endControlFlow().addStatement("writer.endArray()");
|
|
}
|
|
|
|
@Override
|
|
public void generateRead() {
|
|
CodeBlock.Builder kode = CodeBlock.builder();
|
|
kode.addStatement("$T list = new $T<>()", typeName, implType);
|
|
// Coerce
|
|
kode.beginControlFlow("if (reader.isLenient() && reader.peek() != $T.BEGIN_ARRAY)", Cl.GSON_TOKEN)
|
|
.add("list.add(");
|
|
generateRead(kode, componentType, argName, componentType.getAnnotationMirrors());
|
|
kode.add(");\n").addStatement("return list").endControlFlow();
|
|
|
|
kode.addStatement("reader.beginArray()")
|
|
.beginControlFlow("while (reader.hasNext())")
|
|
.beginControlFlow("if (reader.peek() == $T.NULL)", Cl.GSON_TOKEN)
|
|
.addStatement("reader.nextNull()")
|
|
.addStatement("list.add(null)")
|
|
.nextControlFlow("else")
|
|
.add("list.add(");
|
|
generateRead(kode, componentType, argName, componentType.getAnnotationMirrors());
|
|
kode.add(");\n")
|
|
.endControlFlow()
|
|
.endControlFlow()
|
|
.addStatement("reader.endArray()")
|
|
.addStatement("return list");
|
|
|
|
String methodName = "read$" + name;
|
|
klazz.addMethod(
|
|
MethodSpec.methodBuilder(methodName)
|
|
.addModifiers(Modifier.PRIVATE, Modifier.STATIC)
|
|
.returns(typeName)
|
|
.addParameter(Cl.GSON_READER, "reader")
|
|
.addException(IOException.class)
|
|
.addCode(kode.build())
|
|
.build()
|
|
);
|
|
code.add("$N(reader)", methodName);
|
|
}
|
|
}
|
|
}
|