package org.gsonformat.intellij.process;
import com.intellij.psi.*;
import org.apache.http.util.TextUtils;
import org.gsonformat.intellij.common.FieldHelper;
import org.gsonformat.intellij.common.PsiClassUtil;
import org.gsonformat.intellij.common.Try;
import org.gsonformat.intellij.config.Config;
import org.gsonformat.intellij.config.Constant;
import org.gsonformat.intellij.entity.FieldEntity;
import org.gsonformat.intellij.entity.ClassEntity;
import java.util.regex.Pattern;
/**
* Created by dim on 16/11/7.
*/
class AutoValueProcessor extends Processor {
@Override
public void onStarProcess(ClassEntity classEntity, PsiElementFactory factory, PsiClass cls, IProcessor visitor) {
super.onStarProcess(classEntity, factory, cls, visitor);
injectAutoAnnotation(factory, cls);
}
@Override
public void generateField(PsiElementFactory factory, FieldEntity fieldEntity, PsiClass cls, ClassEntity classEntity) {
if (fieldEntity.isGenerate()) {
Try.run(new Try.TryListener() {
@Override
public void run() {
cls.add(factory.createMethodFromText(generateFieldText(classEntity, fieldEntity, null), cls));
}
@Override
public void runAgain() {
fieldEntity.setFieldName(FieldHelper.generateLuckyFieldName(fieldEntity.getFieldName()));
cls.add(factory.createMethodFromText(generateFieldText(classEntity, fieldEntity, Constant.FIXME), cls));
}
@Override
public void error() {
cls.addBefore(factory.createCommentFromText("// FIXME generate failure field " + fieldEntity.getFieldName(), cls), cls.getChildren()[0]);
}
});
}
}
@Override
public void generateGetterAndSetter(PsiElementFactory factory, PsiClass cls, ClassEntity classEntity) {
}
@Override
public void generateConvertMethod(PsiElementFactory factory, PsiClass cls, ClassEntity classEntity) {
super.generateConvertMethod(factory, cls, classEntity);
// if (PsiClassUtil.isClassAvailableForProject(cls.getProject(), "com.ryanharter.auto.value.gson.AutoValueGsonAdapterFactoryProcessor")) {
// String qualifiedName = cls.getQualifiedName();
// String autoAdapter = qualifiedName.substring(mainPackage.length()+1, qualifiedName.length());
// createMethod(factory, Constant.autoValueMethodTemplate.replace("$className$", classEntity.getClassName()).replace("$AdapterClassName$", getAutoAdpaterClass(autoAdapter)).trim(), cls);
// }
}
public static String getAutoAdpaterClass(String className) {
return String.join("_", className.split("\\."));
}
@Override
protected void onEndGenerateClass(PsiElementFactory factory, ClassEntity classEntity, PsiClass parentClass, PsiClass generateClass, IProcessor visitor) {
super.onEndGenerateClass(factory, classEntity, parentClass, generateClass, visitor);
injectAutoAnnotation(factory, generateClass);
}
private void injectAutoAnnotation(PsiElementFactory factory, PsiClass cls) {
PsiModifierList modifierList = cls.getModifierList();
if (modifierList != null) {
PsiElement firstChild = modifierList.getFirstChild();
Pattern pattern = Pattern.compile("@.*?AutoValue");
if (firstChild != null && !pattern.matcher(firstChild.getText()).find()) {
PsiAnnotation annotationFromText = factory.createAnnotationFromText("@com.google.auto.value.AutoValue", cls);
modifierList.addBefore(annotationFromText, firstChild);
}
if (!modifierList.hasModifierProperty(PsiModifier.ABSTRACT)) {
modifierList.setModifierProperty(PsiModifier.ABSTRACT, true);
}
}
}
private String generateFieldText(ClassEntity classEntity, FieldEntity fieldEntity, String fixme) {
fixme = fixme == null ? "" : fixme;
StringBuilder fieldSb = new StringBuilder();
String fieldName = fieldEntity.getGenerateFieldName();
if (!TextUtils.isEmpty(classEntity.getExtra())) {
fieldSb.append(classEntity.getExtra()).append("\n");
classEntity.setExtra(null);
}
if (!fieldName.equals(fieldEntity.getKey()) || Config.getInstant().isUseSerializedName()) {
fieldSb.append(Constant.gsonFullNameAnnotation.replaceAll("\\{filed\\}", fieldEntity.getKey()));
}
if (fieldEntity.getTargetClass() != null) {
fieldEntity.getTargetClass().setGenerate(true);
}
return fieldSb.append(String.format("public abstract %s %s(); " + fixme, fieldEntity.getFullNameType(), fieldName)).toString();
}
}