Search code examples
javamavenjooqmaven-mojo

JOOQ custom code generator with maven mojos


I have a custom code generator extending JavaGenerator and it would be very useful if the user using this generator could specify additional information like a list of column names to which the custom generator applies to. My first though would be to add configuration options to the dependency with mojos. However this does not seem to work properly because during the build cycle two separate instance are created, once from maven and once from JOOQ.

This is my custom generator:

@Mojo(name="generation")
public class CustomGenerator extends JavaGenerator implements org.apache.maven.plugin.Mojo, ContextEnabled {

    @Parameter(property="tableNames")
    private List tableNames;

    private static final Logger log = LoggerFactory.getLogger(CustomGenerator.class);
    @Override
    protected void generateSchema(SchemaDefinition schema) {
        //custom code generation based on the variable "tableNames"
    }

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        //called when maven instantiates this class
    }

    //bunch of empty methods I do not care about but have to be there because
    //I cannot let this class also extend from AbstractMojo

    @Override
    public void setPluginContext(Map map) {

    }

    @Override
    public Map getPluginContext() {
        return null;
    }

    @Override
    public void setLog(Log log) {

    }

    @Override
    public Log getLog() {
        return null;
    }
}

And this is my pom of the project where I use the generator and want to supply additional information:

<plugin>
    <groupId>org.jooq</groupId>
    <artifactId>jooq-codegen-maven</artifactId>
    <version>3.15.4</version>
    <configuration>
        <generator>
            <name>org.example.CustomGenerator</name>
        </generator>
    </configuration>
</plugin>
<plugin>
    <groupId>org.example</groupId>
    <artifactId>customgenerator</artifactId>
    <version>1.0</version>
    <configuration>
        <tableNames>
            <tableName>test_table</tableName>
        </tableNames>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>generation</goal>
            </goals>
        </execution>
    </executions>
</plugin>
...
<dependency>
    <groupId>org.example</groupId>
    <artifactId>customgenerator</artifactId>
    <version>1.0</version>
</dependency>

If there are any other methods to supply custom information to the generator, please let me know.


Solution

  • Using database properties

    Maybe, much simpler, use the properties available in database as follows:

    <configuration>
      <generator>
        <database>
          <properties>
            <property>
              <key>some_key</key>
              <value>some_value</value>
            </property>
          </properties>
        </database>
      </generator>
    </configuration>
    

    There's no specification what you place as key/value in those properties. They've been added for purposes like yours, e.g. to add custom configuration to advanced <database> implementations like:

    See also those sections to see how the properties are used by those databases.

    Your custom JavaGenerator logic can then access the properties via:

    Properties properties = definition.getDatabase().getProperties();
    

    Where definition is any object that is being generated, e.g. SchemaDefinition in your code.

    Simplest solution

    Of course, setting system properties is always a pragmatic option.