package pocketknife.internal.codegen.builder; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.MethodSpec; import org.apache.commons.lang3.StringUtils; import pocketknife.internal.codegen.BundleFieldBinding; import pocketknife.internal.codegen.KeySpec; import pocketknife.internal.codegen.MethodBinding; import pocketknife.internal.codegen.TypeUtil; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import static javax.lang.model.element.Modifier.PUBLIC; public class BundleMethodBinding extends MethodBinding { private static final String RETURN_VAR_NAME_ROOT = "bundle"; private final String name; private final List<BundleFieldBinding> fields = new ArrayList<BundleFieldBinding>(); public BundleMethodBinding(String name) { this.name = name; } public void addField(BundleFieldBinding fieldBinding) { if (fields.contains(fieldBinding)) { throw new IllegalStateException("Cannot have multiple arguments named: " + fieldBinding.getName()); } fields.add(fieldBinding); } @Override public Set<KeySpec> getKeys() { Set<KeySpec> keys = new LinkedHashSet<KeySpec>(); for (BundleFieldBinding field : fields) { keys.add(field.getKey()); } return keys; } @Override public MethodSpec generateMethodSpec(TypeUtil typeUtil) { String returnVarName = getReturnVarName(RETURN_VAR_NAME_ROOT); MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(name) .addAnnotation(Override.class) .addModifiers(PUBLIC) .returns(ClassName.get(typeUtil.bundleType)) .addStatement("$T $N = new $T()", ClassName.get(typeUtil.bundleType), returnVarName, ClassName.get(typeUtil.bundleType)); for (BundleFieldBinding field : fields) { methodBuilder.addParameter(ClassName.get(field.getType()), field.getName()); KeySpec key = field.getKey(); if (field.getBundleSerializer() == null) { String keyValue; String stmt = "$N.put$L("; if (StringUtils.isBlank(key.getName())) { keyValue = key.getValue(); stmt = stmt.concat("$S"); } else { keyValue = key.getName(); stmt = stmt.concat("$N"); } stmt = stmt.concat(", $N)"); methodBuilder.addStatement(stmt, returnVarName, field.getBundleType(), keyValue, field.getName()); } else { if (StringUtils.isBlank(key.getName())) { methodBuilder.addStatement("new $T().put($N, $N, $S)", field.getBundleSerializer(), returnVarName, field.getName(), key.getValue()); } else { methodBuilder.addStatement("new $T().put($N, $N, $N)", field.getBundleSerializer(), returnVarName, field.getName(), key.getName()); } } } methodBuilder.addStatement("return $N", returnVarName); return methodBuilder.build(); } @Override public List<BundleFieldBinding> getFields() { return fields; } }