package io.gitlab.jfronny.gson.compile.processor.adapter; import com.squareup.javapoet.*; import io.gitlab.jfronny.gson.compile.processor.*; import io.gitlab.jfronny.gson.compile.processor.util.valueprocessor.Property; import javax.lang.model.element.*; import javax.lang.model.type.DeclaredType; import javax.tools.Diagnostic; import java.util.*; public class DeclaredAdapter extends AdapterAdapter { private DeclaredType typeAdapterClass; @Override public boolean applies() { return typeAdapterClass != null; } @Override public void hydrate(Property property, TypeSpec.Builder klazz, CodeBlock.Builder code, List typeVariables, Set other) { super.hydrate(property, klazz, code, typeVariables, other); this.typeAdapterClass = findTypeAdapterClass(property.getAnnotations()); } @Override public void dehydrate() { super.dehydrate(); typeAdapterClass = null; } @Override protected String createAdapter(String typeAdapterName) { if (TypeHelper.isInstance(typeAdapterClass, Const.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, Const.TYPE_ADAPTER_FACTORY.toString(), typeUtils)) { TypeName typeAdapterType = ParameterizedTypeName.get(Const.TYPE_ADAPTER, TypeName.get(type).box()); CodeBlock.Builder block = CodeBlock.builder(); block.add("new $T().create($T.HOLDER.getGson(), ", typeAdapterClass, Const.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.", property.getElement()); return typeAdapterName; } private DeclaredType findTypeAdapterClass(List annotations) { for (AnnotationMirror annotation : annotations) { String typeName = annotation.getAnnotationType().toString(); if (typeName.equals(Const.JSON_ADAPTER.toString())) { Map elements = annotation.getElementValues(); if (!elements.isEmpty()) { AnnotationValue value = elements.values().iterator().next(); return (DeclaredType) value.getValue(); } } } return null; } }