package io.gitlab.jfronny.gson.compile.processor.adapter.impl; import com.squareup.javapoet.*; 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.AdapterAdapter; import javax.lang.model.element.*; import javax.lang.model.type.DeclaredType; import javax.tools.Diagnostic; import java.util.List; import java.util.Map; public class DeclaredAdapter extends AdapterAdapter { @Override public Hydrated instantiate() { return new Hydrated(); } public class Hydrated extends AdapterAdapter.Hydrated { private DeclaredType typeAdapterClass; @Override public boolean applies() { return typeAdapterClass != null; } @Override protected void afterHydrate() { this.typeAdapterClass = findTypeAdapterClass(annotations); } @Override protected String createAdapter(String typeAdapterName) { if (TypeHelper.isInstance(typeAdapterClass, Cl.TYPE_ADAPTER.toString(), typeUtils)) { klazz.addField( FieldSpec.builder(TypeName.get(typeAdapterClass), typeAdapterName) .addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL) .initializer("new $T()", typeAdapterClass) .build() ); } else if (TypeHelper.isInstance(typeAdapterClass, Cl.TYPE_ADAPTER_FACTORY.toString(), typeUtils)) { TypeName typeAdapterType = ParameterizedTypeName.get(Cl.TYPE_ADAPTER, TypeName.get(type).box()); CodeBlock.Builder block = CodeBlock.builder(); block.add("new $T().create($T.HOLDER.getGson(), ", typeAdapterClass, Cl.CCORE); appendFieldTypeToken(false); block.add(")"); klazz.addField( FieldSpec.builder(typeAdapterType, typeAdapterName) .addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL) .initializer(block.build()) .build() ); } else message.printMessage(Diagnostic.Kind.ERROR, "@JsonAdapter value must by TypeAdapter or TypeAdapterFactory reference.", sourceElement); return typeAdapterName; } private static DeclaredType findTypeAdapterClass(List annotations) { for (AnnotationMirror annotation : annotations) { String typeName = annotation.getAnnotationType().toString(); if (typeName.equals(Cl.JSON_ADAPTER.toString())) { Map elements = annotation.getElementValues(); if (!elements.isEmpty()) { AnnotationValue value = elements.values().iterator().next(); return (DeclaredType) value.getValue(); } } } return null; } } }