public Optional generate()

in mapper-processor/src/main/java/com/datastax/oss/driver/internal/mapper/processor/dao/DaoInsertMethodGenerator.java [96:185]


  public Optional<MethodSpec> generate() {

    // Validate the parameters:
    // - the first one must be the entity.
    // - the others are completely free-form (they'll be used as additional bind variables)
    // A Function<BoundStatementBuilder, BoundStatementBuilder> can be added in last position.
    List<? extends VariableElement> parameters = methodElement.getParameters();
    VariableElement boundStatementFunction = findBoundStatementFunction(methodElement);
    if (boundStatementFunction != null) {
      parameters = parameters.subList(0, parameters.size() - 1);
    }
    TypeElement entityElement =
        parameters.isEmpty()
            ? null
            : EntityUtils.asEntityElement(parameters.get(0), typeParameters);
    if (entityElement == null) {
      context
          .getMessager()
          .error(
              methodElement,
              "%s methods must take the entity to insert as the first parameter",
              Insert.class.getSimpleName());
      return Optional.empty();
    }

    // Validate the return type:
    DaoReturnType returnType =
        parseAndValidateReturnType(getSupportedReturnTypes(), Insert.class.getSimpleName());
    if (returnType == null) {
      return Optional.empty();
    }
    if (returnType.getEntityElement() != null
        && !returnType.getEntityElement().equals(entityElement)) {
      context
          .getMessager()
          .error(
              methodElement,
              "Invalid return type: %s methods must return the same entity as their argument ",
              Insert.class.getSimpleName());
      return Optional.empty();
    }

    // Generate the method:
    String helperFieldName = enclosingClass.addEntityHelperField(ClassName.get(entityElement));
    String statementName =
        enclosingClass.addPreparedStatement(
            methodElement,
            (methodBuilder, requestName) ->
                generatePrepareRequest(methodBuilder, requestName, helperFieldName));

    CodeBlock.Builder createStatementBlock = CodeBlock.builder();

    createStatementBlock.addStatement(
        "$T boundStatementBuilder = $L.boundStatementBuilder()",
        BoundStatementBuilder.class,
        statementName);

    populateBuilderWithStatementAttributes(createStatementBlock, methodElement);
    populateBuilderWithFunction(createStatementBlock, boundStatementFunction);

    warnIfCqlNamePresent(parameters.subList(0, 1));
    String entityParameterName = parameters.get(0).getSimpleName().toString();

    NullSavingStrategy nullSavingStrategy =
        nullSavingStrategyValidation.getNullSavingStrategy(
            Insert.class, Insert::nullSavingStrategy, methodElement, enclosingClass);

    createStatementBlock.addStatement(
        "$1L.set($2L, boundStatementBuilder, $3T.$4L, false)",
        helperFieldName,
        entityParameterName,
        NullSavingStrategy.class,
        nullSavingStrategy);

    // Handle all remaining parameters as additional bound values
    if (parameters.size() > 1) {
      List<? extends VariableElement> bindMarkers = parameters.subList(1, parameters.size());
      if (validateCqlNamesPresent(bindMarkers)) {
        GeneratedCodePatterns.bindParameters(
            bindMarkers, createStatementBlock, enclosingClass, context, false);
      } else {
        return Optional.empty();
      }
    }

    createStatementBlock.addStatement(
        "$T boundStatement = boundStatementBuilder.build()", BoundStatement.class);

    return crudMethod(createStatementBlock, returnType, helperFieldName);
  }