// Path: objectmapper-processor/src/main/java/com/hannesdorfmann/sqlbrite/objectmapper/processor/generator/CodeGenerator.java
// public interface CodeGenerator {
// 
//   /**
//    * Generate the code for reading cursor into the object
//    *
//    * @param builder the {@link CodeBlock.Builder}
//    * @param objectVarName The variable name of the object that gets instantiated and filled with
//    * data from cursor
//    * @param cursorVarName The variable name of the cursor from which you should read
//    * @param indexVarName The variable name of the index of the column
//    */
//   void generateAssignStatement(CodeBlock.Builder builder, String objectVarName,
//       String cursorVarName, String indexVarName);
// 
//   void generateContentValuesBuilderMethod(TypeSpec.Builder builder, TypeName type,
//       String contentValuesVarName);
// }
// 
// Path: objectmapper-processor/src/main/java/com/hannesdorfmann/sqlbrite/objectmapper/processor/generator/method/MethodCodeFactory.java
// public class MethodCodeFactory {
// 
//   public static CodeGenerator get(ColumnAnnotatedMethod method) throws ProcessingException {
// 
//     ExecutableElement element = method.getMethod();
//     TypeMirror parameter =element.getParameters().get(0).asType();
// 
//     switch (parameter.getKind()) {
// 
//       case INT:
//         return new MethodCodeGenerator(method, "getInt");
// 
//       case FLOAT:
//         return new MethodCodeGenerator(method, "getFloat");
// 
//       case DOUBLE:
//         return new MethodCodeGenerator(method, "getDouble");
// 
//       case LONG:
//         return new MethodCodeGenerator(method, "getLong");
// 
//       case SHORT:
//         return new MethodCodeGenerator(method, "getShort");
// 
//       case BOOLEAN:
//         return new BooleanMethodCodeGenerator(method);
//       case ARRAY:
//         ArrayType parameterArrayType = (ArrayType) parameter;
//         if (parameterArrayType.getComponentType().getKind() == TypeKind.BYTE) {
//           return new MethodCodeGenerator(method, "getBlob");
//         }
//         break;
// 
//       case DECLARED:
//         String parameterType = parameter.toString();
//         if (parameterType.equals(String.class.getCanonicalName())) {
//           return new MethodCodeGenerator(method, "getString");
//         }
// 
//         if (parameterType.equals(Date.class.getCanonicalName())) {
//           return new DateMethodCodeGenerator(method);
//         }
//         break;
//     }
// 
//     throw new ProcessingException(element,
//         "Unsupported type %s as parameter in method %s() in class %s annotated with @%s.",
//         parameter, method.getMethod(),
//         method.getQualifiedSurroundingClassName(), Column.class.getSimpleName());
//   }
// }


import com.hannesdorfmann.sqlbrite.objectmapper.annotation.Column;
import com.hannesdorfmann.sqlbrite.objectmapper.processor.generator.CodeGenerator;
import com.hannesdorfmann.sqlbrite.objectmapper.processor.generator.method.MethodCodeFactory;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
package com.hannesdorfmann.sqlbrite.objectmapper.processor;


/**
 * @author Hannes Dorfmann
 */
public class ColumnAnnotatedMethod implements ColumnAnnotateable {

  private ExecutableElement method;
  private String columnName;
  private CodeGenerator codeGenerator;
  private boolean throwOnColumnIndexNotFound;

  public ColumnAnnotatedMethod(ExecutableElement method, Column annotation)
      throws ProcessingException {

    if (!method.getModifiers().contains(Modifier.PUBLIC)) {
      throw new ProcessingException(method,
          "Setter method %s in %s annotated with @%s is not public. Only PUBLIC setter methods are supported",
          method.getSimpleName().toString(), method.getEnclosingElement().toString(),
          Column.class.getSimpleName());
    }

    if (method.getParameters().size() != 1) {
      throw new ProcessingException(method,
          "Setter method %s in %s annotated with @%s MUST have exactly one parameter!",
          method.toString(), method.getEnclosingElement().toString(), Column.class.getSimpleName());
    }

    columnName = annotation.value();
    if (columnName == null || columnName.length() == 0) {
      throw new ProcessingException(method, "The column name is unspecified for method %s in %s",
          method.getSimpleName().toString(), method.getEnclosingElement().toString());
    }

    throwOnColumnIndexNotFound = annotation.throwOnColumnIndexNotFound();
    this.method = method;

    codeGenerator = MethodCodeFactory.get(this);
  }

// Path: objectmapper-processor/src/main/java/com/hannesdorfmann/sqlbrite/objectmapper/processor/generator/CodeGenerator.java
// public interface CodeGenerator {
// 
//   /**
//    * Generate the code for reading cursor into the object
//    *
//    * @param builder the {@link CodeBlock.Builder}
//    * @param objectVarName The variable name of the object that gets instantiated and filled with
//    * data from cursor
//    * @param cursorVarName The variable name of the cursor from which you should read
//    * @param indexVarName The variable name of the index of the column
//    */
//   void generateAssignStatement(CodeBlock.Builder builder, String objectVarName,
//       String cursorVarName, String indexVarName);
// 
//   void generateContentValuesBuilderMethod(TypeSpec.Builder builder, TypeName type,
//       String contentValuesVarName);
// }
// 
// Path: objectmapper-processor/src/main/java/com/hannesdorfmann/sqlbrite/objectmapper/processor/generator/method/MethodCodeFactory.java
// public class MethodCodeFactory {
// 
//   public static CodeGenerator get(ColumnAnnotatedMethod method) throws ProcessingException {
// 
//     ExecutableElement element = method.getMethod();
//     TypeMirror parameter =element.getParameters().get(0).asType();
// 
//     switch (parameter.getKind()) {
// 
//       case INT:
//         return new MethodCodeGenerator(method, "getInt");
// 
//       case FLOAT:
//         return new MethodCodeGenerator(method, "getFloat");
// 
//       case DOUBLE:
//         return new MethodCodeGenerator(method, "getDouble");
// 
//       case LONG:
//         return new MethodCodeGenerator(method, "getLong");
// 
//       case SHORT:
//         return new MethodCodeGenerator(method, "getShort");
// 
//       case BOOLEAN:
//         return new BooleanMethodCodeGenerator(method);
//       case ARRAY:
//         ArrayType parameterArrayType = (ArrayType) parameter;
//         if (parameterArrayType.getComponentType().getKind() == TypeKind.BYTE) {
//           return new MethodCodeGenerator(method, "getBlob");
//         }
//         break;
// 
//       case DECLARED:
//         String parameterType = parameter.toString();
//         if (parameterType.equals(String.class.getCanonicalName())) {
//           return new MethodCodeGenerator(method, "getString");
//         }
// 
//         if (parameterType.equals(Date.class.getCanonicalName())) {
//           return new DateMethodCodeGenerator(method);
//         }
//         break;
//     }
// 
//     throw new ProcessingException(element,
//         "Unsupported type %s as parameter in method %s() in class %s annotated with @%s.",
//         parameter, method.getMethod(),
//         method.getQualifiedSurroundingClassName(), Column.class.getSimpleName());
//   }
// }


// Path: objectmapper-processor/src/main/java/com/hannesdorfmann/sqlbrite/objectmapper/processor/ColumnAnnotatedMethod.java
import com.hannesdorfmann.sqlbrite.objectmapper.annotation.Column;
import com.hannesdorfmann.sqlbrite.objectmapper.processor.generator.CodeGenerator;
import com.hannesdorfmann.sqlbrite.objectmapper.processor.generator.method.MethodCodeFactory;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;

package com.hannesdorfmann.sqlbrite.objectmapper.processor;


/**
 * @author Hannes Dorfmann
 */
public class ColumnAnnotatedMethod implements ColumnAnnotateable {

  private ExecutableElement method;
  private String columnName;
  private CodeGenerator codeGenerator;
  private boolean throwOnColumnIndexNotFound;

  public ColumnAnnotatedMethod(ExecutableElement method, Column annotation)
      throws ProcessingException {

    if (!method.getModifiers().contains(Modifier.PUBLIC)) {
      throw new ProcessingException(method,
          "Setter method %s in %s annotated with @%s is not public. Only PUBLIC setter methods are supported",
          method.getSimpleName().toString(), method.getEnclosingElement().toString(),
          Column.class.getSimpleName());
    }

    if (method.getParameters().size() != 1) {
      throw new ProcessingException(method,
          "Setter method %s in %s annotated with @%s MUST have exactly one parameter!",
          method.toString(), method.getEnclosingElement().toString(), Column.class.getSimpleName());
    }

    columnName = annotation.value();
    if (columnName == null || columnName.length() == 0) {
      throw new ProcessingException(method, "The column name is unspecified for method %s in %s",
          method.getSimpleName().toString(), method.getEnclosingElement().toString());
    }

    throwOnColumnIndexNotFound = annotation.throwOnColumnIndexNotFound();
    this.method = method;

    codeGenerator = MethodCodeFactory.get(this);
  }

  @Override public void generateAssignStatement(CodeBlock.Builder builder, String objectVarName,