square/javapoet

Generate Builder Code

38leinaD opened this issue · 2 comments

Hi,
This is more a question than an issue. I am trying to understand JavaPoet. I am able to understand how to generate simple code fragements, but what i would like to do is generated nested code structures based on builder objects. So, i would like to generate code like this:

new MyTransactionBuilder()
  .amount(MyAmountBuilder()
    .value(100)
    .currency("EUR")
    .build())
  .build()

I am having a hard time to understand how i can generate code that includes methods-calls which again need to have a code fragment as the methods parameter. I.e. amount method call needs a code fragment again.
If someone could give me a push in the right direction, that would be great. Feels, like I am missing some basic understanding somewhere.

Thanks,
Daniel

In Javapoet, these type of codes called "CodeBlock" also a class named CodeBlock is used to generate this type of calls.

First, you need to define your custom classes like MyTransactionBuilder and MyAmountBuilder by their package name.

Then, other calls can be added by a simple addStatement method. In this method, you can reference custom types that you defined before. For example, $T is a placeholder for typename.

For more detailed information, you should look at CodeBlock docs

The short answer to your question, the below code does the job 👍

        ClassName myTransactionBuilderClazz = ClassName.get("com.yourpackage", "MyTransactionBuilder");
        ClassName myAmountBuilderClazz = ClassName.get("com.yourpackage", "MyAmountBuilder");
        
        CodeBlock block = CodeBlock.builder()
            .addStatement("return new $T()", myTransactionBuilderClazz)
            .indent()
            .addStatement(".amount(new $T().value(100).currency(\"EUR\").build())", myAmountBuilderClazz)
            .addStatement(".build()")
            .unindent()
            .build();

Sorry, it's not working because addStatement appends ; on each line. For builder pattern-based code it's a problem.