Skip to content

How to generate sources at runtime

Burningwave edited this page Feb 3, 2021 · 6 revisions

With UnitSourceGenerator you can generate source code and store it on the drive. Assuming this class as example:

package source.generation.test;

import java.util.Arrays;
import java.util.List;

public class GeneratedClass {
    
    
    private List<String> words;
    
    public GeneratedClass(String... words) {
        this.words = Arrays.asList(words);
    }
    
    public void print() {
        System.out.print(String.join(" ", words));
    }
    
    public static void main(String[] args) {
        new GeneratedClass(args).print();
    }
}

... The relative code to generate and store it will be:

package source.generation.test;

import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;

import org.burningwave.core.classes.ClassSourceGenerator;
import org.burningwave.core.classes.FunctionSourceGenerator;
import org.burningwave.core.classes.GenericSourceGenerator;
import org.burningwave.core.classes.TypeDeclarationSourceGenerator;
import org.burningwave.core.classes.UnitSourceGenerator;
import org.burningwave.core.classes.VariableSourceGenerator;

public class SourceGenerationTester {

    
    public static UnitSourceGenerator generate() {
        return UnitSourceGenerator.create(SourceGenerationTester.class.getPackage().getName())
        .addClass(
            ClassSourceGenerator.create(TypeDeclarationSourceGenerator.create("GeneratedClass"))
            .addField(
                VariableSourceGenerator.create(
                    TypeDeclarationSourceGenerator.create(List.class)
                    .addGeneric(GenericSourceGenerator.create(String.class)),
                    "words"
                )
            )
            .addConstructor(
                FunctionSourceGenerator.create().addParameter(
                    VariableSourceGenerator.create(
                        TypeDeclarationSourceGenerator.create(String.class)
                        .setAsVarArgs(true),
                        "words"
                    )
                ).addBodyCodeLine("this.words = Arrays.asList(words);").useType(Arrays.class)
            )
            .addMethod(
                FunctionSourceGenerator.create("print")
                .addModifier(Modifier.PUBLIC).setReturnType(void.class)
                .addBodyCodeLine(
                  "System.out.println(\"\\n\\t\" + String.join(\" \", words) + \"\\n\");"
                )
            )
            .addMethod(
                FunctionSourceGenerator.create("main")
                .addModifier(Modifier.PUBLIC | Modifier.STATIC)
                .setReturnType(void.class)
                .addParameter(VariableSourceGenerator.create(String[].class, "args"))
                .addBodyCodeLine("new GeneratedClass(args).print();")
            )
        );
    }
    
    
    public static void main(String[] args) {
        UnitSourceGenerator unitSG = SourceGenerationTester.generate();
        unitSG.storeToClassPath(System.getProperty("user.home") + "/Desktop/sources");
        System.out.println("\nGenerated code:\n" + unitSG);
        
    }
}

Once the sources have been generated you can also compile them at runtime: to do this follow this guide.

Examples of use of some components:

BackgroundExecutor
ClassFactory
ClassHunter
ClassPathHunter
CodeExecutor
Constructors
Fields
FileSystemItem
FunctionalInterfaceFactory
IterableObjectHelper
JavaMemoryCompiler
Methods
PathHelper
PropertyAccessor
UnitSourceGenerator

HitCount

Clone this wiki locally