All Downloads are FREE. Search and download functionalities are using the official Maven repository.

butterknife.plugin.FinalRClassBuilder Maven / Gradle / Ivy

There is a newer version: 10.2.3
Show newest version
package butterknife.plugin;

import com.github.javaparser.JavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.BodyDeclaration;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.TypeDeclaration;
import com.github.javaparser.ast.body.VariableDeclarator;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.TypeSpec;
import java.io.File;
import java.util.Arrays;
import java.util.List;

import static javax.lang.model.element.Modifier.FINAL;
import static javax.lang.model.element.Modifier.PUBLIC;
import static javax.lang.model.element.Modifier.STATIC;

/**
 * Generates a class that contains all supported field names in an R file as final values.
 * Also enables adding support annotations to indicate the type of resource for every field.
 */
public final class FinalRClassBuilder {
  private static final String SUPPORT_ANNOTATION_PACKAGE = "android.support.annotation";
  private static final String[] SUPPORTED_TYPES = {
      "array", "attr", "bool", "color", "dimen", "drawable", "id", "integer", "string"
  };

  private FinalRClassBuilder() { }

  public static void brewJava(File rFile, File outputDir, String packageName, String className)
      throws Exception {
    CompilationUnit compilationUnit = JavaParser.parse(rFile);
    TypeDeclaration resourceClass = compilationUnit.getTypes().get(0);

    TypeSpec.Builder result =
        TypeSpec.classBuilder(className).addModifiers(PUBLIC).addModifiers(FINAL);

    for (Node node : resourceClass.getChildrenNodes()) {
      if (node instanceof TypeDeclaration) {
        addResourceType(Arrays.asList(SUPPORTED_TYPES), result, (TypeDeclaration) node);
      }
    }

    JavaFile finalR = JavaFile.builder(packageName, result.build())
        .addFileComment("Generated code from Butter Knife gradle plugin. Do not modify!")
        .build();

    finalR.writeTo(outputDir);
  }

  private static void addResourceType(List supportedTypes, TypeSpec.Builder result,
      TypeDeclaration node) {
    if (!supportedTypes.contains(node.getName())) {
      return;
    }

    String type = node.getName();
    TypeSpec.Builder resourceType = TypeSpec.classBuilder(type).addModifiers(PUBLIC, STATIC, FINAL);

    for (BodyDeclaration field : node.getMembers()) {
      if (field instanceof FieldDeclaration) {
        addResourceField(resourceType, ((FieldDeclaration) field).getVariables().get(0),
            getSupportAnnotationClass(type));
      }
    }

    result.addType(resourceType.build());
  }

  private static void addResourceField(TypeSpec.Builder resourceType, VariableDeclarator variable,
      ClassName annotation) {
    String fieldName = variable.getId().getName();
    String fieldValue = variable.getInit().toString();
    FieldSpec.Builder fieldSpecBuilder = FieldSpec.builder(int.class, fieldName)
        .addModifiers(PUBLIC, STATIC, FINAL)
        .initializer(fieldValue);

    if (annotation != null) {
      fieldSpecBuilder.addAnnotation(annotation);
    }

    resourceType.addField(fieldSpecBuilder.build());
  }

  private static ClassName getSupportAnnotationClass(String type) {
    return ClassName.get(SUPPORT_ANNOTATION_PACKAGE, capitalize(type) + "Res");
  }

  private static String capitalize(String word) {
    return Character.toUpperCase(word.charAt(0)) + word.substring(1);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy