Skip to main content
The Intent.Modules.Common.Java module provides comprehensive support for generating Java code, including template base classes, code builders, and Maven/Gradle dependency management.

Template Base Class

All Java templates inherit from JavaTemplateBase<TModel>, which provides:
  • Automatic import management: Automatically adds and organizes import statements
  • Package resolution: Resolves fully qualified type names based on package structure
  • Dependency management: Register Maven/Gradle dependencies
  • Type resolution: Converts metadata types to Java types

Basic Template Structure

public class MyJavaTemplate : JavaTemplateBase<ClassModel>
{
    public const string TemplateId = "MyCompany.MyJavaTemplate";

    public MyJavaTemplate(IOutputTarget outputTarget, ClassModel model) 
        : base(TemplateId, outputTarget, model)
    {
        // Configure type sources
        AddTypeSource("OtherJavaTemplate.TemplateId");
    }

    public override ITemplateFileConfig GetTemplateFileConfig()
    {
        return new JavaFileConfig(
            className: Model.Name,
            package: $"{OutputTarget.Name}.domain",
            relativeLocation: "domain");
    }

    public override string TransformText()
    {
        return $@"
package {Package};

import java.util.List;

public class {ClassName} {{
    // Generated code
}}";
    }
}

Key Properties and Methods

// Access the configured package and class name
public string Package { get; }
public string ClassName { get; }

Java Code Builder (JavaFile)

The JavaFile builder provides a fluent API for constructing Java code:
public class MyJavaBuilderTemplate : JavaTemplateBase<ClassModel>, IJavaFileBuilderTemplate
{
    public JavaFile JavaFile { get; }

    public MyJavaBuilderTemplate(IOutputTarget outputTarget, ClassModel model)
        : base(TemplateId, outputTarget, model)
    {
        JavaFile = new JavaFile(this.GetPackage(), this.GetFolderPath())
            .AddClass(model.Name, @class =>
            {
                @class
                    .ExtendsClass("BaseEntity")
                    .ImplementsInterface("Serializable")
                    .AddField("String", "id", field => 
                    {
                        field.Private().Final();
                    })
                    .AddConstructor(ctor =>
                    {
                        ctor
                            .AddParameter("String", "id")
                            .AddStatement("this.id = id;");
                    })
                    .AddMethod("String", "getId", method =>
                    {
                        method
                            .Public()
                            .AddStatement("return id;");
                    });
            });
    }

    public override ITemplateFileConfig GetTemplateFileConfig() => JavaFile.GetConfig();

    public override string TransformText() => JavaFile.ToString();
}

Building Classes

JavaFile.AddClass("User", @class =>
{
    @class
        .Public() // or Private(), Protected()
        .Final() // or Abstract()
        .ExtendsClass("BaseEntity")
        .ImplementsInterface("Serializable")
        .ImplementsInterfaces(new[] { "Comparable<User>", "Cloneable" })
        .AddGenericParameter("T")
        .AddGenericParameter("R", out var rParam);
});

Interfaces

JavaFile.AddInterface("UserRepository", @interface =>
{
    @interface
        .Public()
        .ExtendsInterface("Repository<User, Long>")
        .AddMethod("List<User>", "findByName", method =>
        {
            method.AddParameter("String", "name");
        })
        .AddMethod("Optional<User>", "findByEmail", method =>
        {
            method.AddParameter("String", "email");
        });
});

Annotations

Java annotations are first-class citizens in the builder API:
@class.AddAnnotation("Entity", annotation =>
{
    annotation.AddArgument("name", "\"users\"");
});

@class.AddAnnotation("Table", annotation =>
{
    annotation.AddArgument("name", "\"user_table\"");
    annotation.AddArgument("schema", "\"public\"");
});

Advanced Features

Generic Types

@class
    .AddGenericParameter("T")
    .AddGenericParameter("R")
    .ExtendsClass("BaseService<T>")
    .ImplementsInterface("Function<T, R>");

method
    .AddGenericParameter("E")
    .WithReturnType("List<E>")
    .AddParameter("Class<E>", "type");

Try-Catch Blocks

method.AddTryBlock(tryBlock =>
{
    tryBlock.AddStatement("var result = riskyOperation();");
    tryBlock.AddStatement("return result;");
}, catchBlocks =>
{
    catchBlocks.AddCatchBlock("IOException", "e", catchBlock =>
    {
        catchBlock.AddStatement("logger.error(\"IO Error\", e);");
        catchBlock.AddStatement("throw new RuntimeException(e);");
    });
}, finallyBlock =>
{
    finallyBlock.AddStatement("cleanup();");
});

Javadoc Comments

@class.WithComments(@"
/**
 * Represents a user in the system.
 * 
 * @author Intent Architect
 * @version 1.0
 */
");

method.WithComments(@"
/**
 * Finds a user by their ID.
 * 
 * @param id the user ID
 * @return the user, or null if not found
 * @throws IllegalArgumentException if id is null
 */
");

Maven/Gradle Dependencies

Intent can automatically register dependencies in your Maven or Gradle build files:
// In your template constructor
AddDependency(new JavaDependency(
    groupId: "org.springframework.boot",
    artifactId: "spring-boot-starter-data-jpa",
    version: "3.1.0",
    scope: "compile"));

AddDependency(new JavaDependency(
    groupId: "org.junit.jupiter",
    artifactId: "junit-jupiter",
    version: "5.9.3",
    scope: "test"));

Package Structure

Java templates follow standard package conventions:
return new JavaFileConfig(
    className: "UserService",
    package: "com.company.myapp.services",
    relativeLocation: "services");

// Results in: src/main/java/com/company/myapp/services/UserService.java

Import Resolution

The Java template base automatically handles imports:
// Types from java.lang are never imported
var stringType = UseType("String"); // No import needed

// Standard library imports
var listType = UseType("List", "java.util.List"); // Adds import

// Cross-template references
var userType = GetTypeName(userTemplate); // Resolves package automatically

Best Practices

  • Packages: lowercase (com.company.domain)
  • Classes: PascalCase (UserService)
  • Methods: camelCase (findById)
  • Constants: UPPER_SNAKE_CASE (MAX_RETRY_COUNT)
The JavaFile builder handles proper indentation, braces, and syntax. Use it instead of string concatenation for anything beyond trivial templates.
Java’s annotation system is powerful. Use the builder’s annotation support to generate Spring, JPA, and custom annotations correctly.
Call AddDependency() in your template constructor to ensure Maven/Gradle dependencies are available during the build process.

Comparing with C#

FeatureC# (CSharpTemplateBase)Java (JavaTemplateBase)
Namespace/PackageNamespace propertyPackage property
DependenciesAddNugetDependency()AddDependency(JavaDependency)
Imports/UsingsAddUsing()AddImport()
Code MergingRoslyn-basedText-based with markers

See Also

C# Support

Generate C# code with similar capabilities

Kotlin Support

Generate Kotlin code for JVM projects

Template Basics

Learn about Intent templates

Type Resolution

Understanding cross-template type references

Build docs developers (and LLMs) love