Extending SpringBootCodeGenerator with Custom Parsers and Freemarker Templates

Introduction to Extension Architecture

SpringBootCodeGenerator is a robust utility built on Spring Boot 2 and Freemarker, designed to automate Java code creation from database schemas or structured data. While it supports standard inputs like MySQL, Oracle, and PostgreSQL DDL, complex projects often require custom data ingestion methods or specific framework outputs. This guide details the architectural steps required to integrate custom parsing logic and new template definitions into the generation pipeline.

Implementing Custom Data Parsers

The core responsibility of a parser within this system is to transform raw enput sources into a standardized metadata object used by the templating engine. The system currently supports SQL and JSON inputs via dedicated service interfaces. To introduce support for additional formats, developers must adhere to the defined service contract.

Defining the Parser Interface

New parsing strategies should be defined within the com.softdev.system.generator.service.parser package. Instead of directly coupling to specific file types, consider defining a generic ingestion contract. For example, a YAML-based parser interface might look like this:

public interface DataIngestionStrategy {
    EntityDefinition ingest(SourcePayload payload);
}

The EntityDefinition object serves as the canonical model containing table structuers, field types, and relationships, ensuring compatibility with existing templates.

Developing the Implementation Logic

Implementation classes reside in com.softdev.system.generator.service.impl.parser. When building the logic, focus on the following requirements:

  • Input Handling: Accept the SourcePayload which encapsulates raw text or file streams.
  • Type Mapping: Utilize existing utility classes, such as mysqlJavaTypeUtil.java, to ensure database types are correctly converted to Java types.
  • Error Management: Throw specific runtime exceptions, such as GenerationFailureException, when input data is malformed.

Below is a simplified example of how the ingestion logic might be structured:

@Service
public class YamlStructureParser implements DataIngestionStrategy {

    @Override
    public EntityDefinition ingest(SourcePayload payload) {
        // Parse YAML content
        YamlNode root = parseYaml(payload.getContent());
        
        // Map to internal entity model
        EntityDefinition model = new EntityDefinition();
        model.setNamespace(extractPackage(root));
        model.setFields(mapFields(root.getChildren()));
        
        return model;
    }
}

Registering the Parser

To make the new parser available to the generation engine, it must be wired into the main orchestration service. Modify the GenerationOrchestrator.java (formerly CodeGenServiceImpl) to include the new strategy. Use dependency injection to load the service and implement a routing mechanism based on the input source type.

@Autowired
private DataIngestionStrategy yamlParser;

public void executeGeneration(GenerationRequest request) {
    EntityDefinition metadata;
    if (request.getType() == InputType.YAML) {
        metadata = yamlParser.ingest(request.getPayload());
    } else {
        // Default handling
    }
    // Proceed to template rendering
}

Customizing Freemarker Templates

The output generation relies on Freemarker templates stored in the resources directory. The template service, defined by TemplateService, manages the loading and processing of these files.

Creating Template Files

New templates should follow the naming convention {framework}-{component}.ftl. For instance, to generate OpenAPI specifications, you might create openapi-spec.ftl. Place this file in the designated templates folder within the classpath.

Configuring Template Metadata

Each template must be registered in the configuration JSON so it apears in the user interface. Add an entry describing the template's purpose and identifier:

{
  "id": "22",
  "key": "openapi-spec",
  "label": "OpenAPI Specification Definition",
  "category": "documentation"
}

Utilizing Template Variables

Templates access the metadata generated by the parsers. Key variables available during rendering include:

  • ${metadata}: Contains namespace, entity name, and imports.
  • ${columns}: A list of field objects with types and comments.
  • ${tableName}: The source database table identifier.

A basic entity class template might utilize these variables as follows:

package ${metadata.namespace};

public class ${metadata.entityName} {
<#list columns as col>
    private ${col.javaType} ${col.fieldName};
#list>
}

Development Best Practices

Project Structure

Maintain separation of concerns by adhering to the standard package layout:

  • Interfaces: com.softdev.system.generator.service.parser
  • Implementations: com.softdev.system.generator.service.impl.parser
  • Utilities: com.softdev.system.generator.util
  • DTOs: com.softdev.system.generator.entity.dto

Testing and Validation

Every new parser or template should be covered by unit tests. Mimic the structure of existing test suites like SqlParserServiceTest.java. Ensure that edge cases, such as null values or unexpected data types, are handled gracefully during parsing.

Performance Considerations

For high-volume generation tasks, consider the following optimizations:

  • Implement caching for frequently used parsing results using tools like MapUtil.
  • Pre-compile Freemarker configurations to reduce rendering overhead.
  • Process large datasets in batches to prevent memory overflow.

Integration Workflow

To fully integrate a new capability, such as an XML parser paired with a Swagger documentation template, follow this sequence:

  1. Define the XmlParserStrategy interface.
  2. Implement the parsing logic in XmlStructureParser.
  3. Create the swagger-doc.ftl template file.
  4. Update the template configuration JSON with the new entry.
  5. Wire the parser into the GenerationOrchestrator.
  6. Validate functionality via XmlParserStrategyTest.

Once completed, the new options will appear in the generation configuration interface, allowing users to select the custom template and input format for their projects.

Tags: SpringBoot FreeMarker code-generation java Metaprogramming

Posted on Tue, 22 Sep 2026 16:06:18 +0000 by sheraz