Search code examples
javainterfacecode-generationjooq

Implement interface in POJO if contains field


I generate java classes with jOOQ. And I want to make POJOs implement an interface which contains only getters for fields. Obviously, I need this interface only in POJOs with such fields. I need check class or table for field and, if field extists, implement interface in pojo.

Overriding getJavaClassImplements in DefaultGeneratorStrategy does not help because it adds the interface for all classes.


Solution

  • Configurative generator strategy

    You seem to be implementing a programmatic generator strategy, just to let you know that there's also an option of a configurative strategy, which could look like this:

    <configuration>
      <generator>
        <strategy>
          <matchers>
            <tables>
              <table>
                <expression>MY_TABLE</expression>
                <pojoImplements>com.example.MyOptionalCustomInterface</pojoImplements>
              </table>
            </tables>
            ...
    

    Please refer to the manual for more details. In order to apply this only to tables containing certain fields, just update the regular expression in <expression> to match those tables.

    <expression>MY_TABLE1|MY_TABLE2</expression>
    

    This expression has to be updated to be in sync with the schema, of course.

    Programmatic genenerator strategy

    Just like with the configurative strategy, you'll have to limit yourself to applying your logic only to generated POJOs. For this, notice the remark in the manual:

    /**
     * ...
     * Beware that most methods also receive a "Mode" object, to tell you whether a
     * TableDefinition is being rendered as a Table, Record, POJO, etc. Depending on
     * that information, you can add a suffix only for TableRecords, not for Tables
     * ...
     */
    

    So, you'll have to do something like this:

    @Override
    public List<String> getJavaClassImplements(Definition definition, Mode mode) {
        if (mode == Mode.POJO)
            return Arrays.asList("com.example.MyOptionalCustomInterface");
        else
            return Collections.emptyList();
    }
    

    If you want to make sure that this inteface is only added to tables that match certain conditions, do this, instead:

    @Override
    public List<String> getJavaClassImplements(Definition definition, Mode mode) {
        if (mode == Mode.POJO
                && definition instanceof TableDefinition t
                && t.getColumns().stream().anyMatch(c -> conditionHere(c)))
            return Arrays.asList("com.example.MyOptionalCustomInterface");
        else
            return Collections.emptyList();
    }