package io.gitlab.jfronny.commons.serialize.generator.adapter; import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeVariableName; import io.gitlab.jfronny.commons.serialize.generator.Cl; import io.gitlab.jfronny.commons.serialize.generator.core.TypeHelper; import javax.lang.model.type.TypeMirror; import java.lang.reflect.ParameterizedType; import java.util.Iterator; import java.util.List; public abstract class AdapterAdapter.Hydrated> extends Adapter { public abstract class Hydrated extends Adapter.Hydrated { @Override public void generateWrite(Runnable writeGet) { Object adapter = getAdapter(); code.add("$" + (adapter instanceof String ? "L" : "T") + ".serialize(", adapter); writeGet.run(); code.add(", writer);\n"); } @Override public void generateRead() { Object adapter = getAdapter(); code.add("$" + (adapter instanceof String ? "L" : "T") + ".deserialize(reader)", adapter); } private Object getAdapter() { for (FieldSpec spec : klazz.fieldSpecs) { if (spec.name.equals(adapterName)) return adapterName; } return createAdapter(adapterName); } protected abstract Object createAdapter(String name); protected void appendFieldTypeToken(boolean allowClassType) { TypeName typeName = TypeName.get(type); if (TypeHelper.isComplexType(type, typeUtils)) { TypeName typeTokenType = ParameterizedTypeName.get(Cl.TYPE_TOKEN, typeName); List typeParams = TypeHelper.getGenericTypes(type); if (typeParams.isEmpty()) { code.add("new $T() {}", typeTokenType); } else { code.add("($T) $T.getParameterized($T.class, ", typeTokenType, Cl.TYPE_TOKEN, typeUtils.erasure(type)); for (Iterator iterator = typeParams.iterator(); iterator.hasNext(); ) { TypeMirror typeParam = iterator.next(); int typeIndex = typeVariables.indexOf(TypeVariableName.get(typeParam.toString())); code.add("(($T)typeToken.getType()).getActualTypeArguments()[$L]", ParameterizedType.class, typeIndex); if (iterator.hasNext()) { code.add(", "); } } code.add(")"); } } else if (TypeHelper.isGenericType(type)) { TypeName typeTokenType = ParameterizedTypeName.get(Cl.TYPE_TOKEN, typeName); int typeIndex = typeVariables.indexOf(TypeVariableName.get(type.toString())); code.add("($T) $T.get((($T)typeToken.getType()).getActualTypeArguments()[$L])", typeTokenType, Cl.TYPE_TOKEN, ParameterizedType.class, typeIndex); } else { if (allowClassType) { code.add("$T.class", typeName); } else { code.add("$T.get($T.class)", Cl.TYPE_TOKEN, typeName); } } } } }