java-commons/commons-serialize-generator/src/main/java/io/gitlab/jfronny/commons/serialize/generator/adapter/impl/ArrayAdapter.java

94 lines
4.2 KiB
Java

package io.gitlab.jfronny.commons.serialize.generator.adapter.impl;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeVariableName;
import io.gitlab.jfronny.commons.serialize.generator.Cl;
import io.gitlab.jfronny.commons.serialize.generator.adapter.Adapter;
import io.gitlab.jfronny.commons.serialize.generator.core.TypeHelper;
import javax.lang.model.element.Modifier;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.TypeMirror;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class ArrayAdapter extends Adapter<ArrayAdapter.Hydrated> {
@Override
public Hydrated instantiate() {
return new Hydrated();
}
public class Hydrated extends Adapter<Hydrated>.Hydrated {
private ArrayType type;
private TypeMirror componentType;
@Override
public boolean applies() {
return type != null;
}
@Override
protected void afterHydrate() {
type = TypeHelper.asArrayType(super.type);
componentType = type == null ? null : type.getComponentType();
}
@Override
public void generateWrite(Runnable writeGet) {
code.add("for ($T $N : ", componentType, argName);
writeGet.run();
code.beginControlFlow(")")
.beginControlFlow("if ($N == null)", argName)
.addStatement("if (writer.isSerializeNulls()) writer.nullValue()")
.nextControlFlow("else");
generateWrite(code, componentType, argName, componentType.getAnnotationMirrors(), () -> code.add(argName));
code.endControlFlow().endControlFlow();
}
@Override
public void generateRead() {
String methodName = "deserialize$" + name;
if (klazz.methodSpecs.stream().noneMatch(s -> s.name.equals(methodName))) {
CodeBlock.Builder kode = CodeBlock.builder();
// Coerce
kode.beginControlFlow("if (reader.isLenient() && reader.peek() != $T.BEGIN_ARRAY)", Cl.GSON_TOKEN)
.add("return new $T[] { ", componentType);
generateRead(kode, componentType, argName, componentType.getAnnotationMirrors());
kode.add(" };\n").endControlFlow();
kode.addStatement("$T<$T> list = new $T<>()", List.class, componentType, ArrayList.class)
.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.toArray($T[]::new)", componentType);
klazz.addMethod(
MethodSpec.methodBuilder(methodName)
.addModifiers(Modifier.PRIVATE, Modifier.STATIC)
.returns(typeName)
.addTypeVariable(TypeVariableName.get("TEx", Exception.class))
.addTypeVariable(TypeVariableName.get("Reader", ParameterizedTypeName.get(Cl.SERIALIZE_READER, TypeVariableName.get("TEx"), TypeVariableName.get("Reader"))))
.addParameter(TypeVariableName.get("Reader"), "reader")
.addException(TypeVariableName.get("TEx"))
.addException(Cl.MALFORMED_DATA_EXCEPTION)
.addCode(kode.build())
.build()
);
}
code.add("$N(reader)", methodName);
}
}
}