Skip to content

Commit

Permalink
Support OpenAPI x-field-extra-annotation property (#245)
Browse files Browse the repository at this point in the history
Added support for the OpenAPI property `x-field-extra-annotation`. This property is *optional*, and will annotate the generated field with the provided annotations. **NOTE**: there is a formatting issue inherited from `openapi-generator-maven-plugin` which does not correctly indent the annotations. This change is fully backwards-compatible.
  • Loading branch information
Chrimle authored Dec 13, 2024
1 parent a302133 commit 2d1ea8c
Show file tree
Hide file tree
Showing 112 changed files with 362 additions and 143 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ The mustache templates can be acquired through multiple ways.
<dependency>
<groupId>io.github.chrimle</groupId>
<artifactId>openapi-to-java-records-mustache-templates</artifactId>
<version>2.3.0</version>
<version>2.4.0</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The mustache templates can be acquired through multiple ways.
<dependency>
<groupId>io.github.chrimle</groupId>
<artifactId>openapi-to-java-records-mustache-templates</artifactId>
<version>2.3.0</version>
<version>2.4.0</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>io.github.chrimle</groupId>
<artifactId>openapi-to-java-records-mustache-templates</artifactId>
<version>2.3.0</version>
<version>2.4.0</version>

<!-- Project Information -->
<name>OpenAPI to Java records :: Mustache Templates</name>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
Copyright 2024 Chrimle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package io.github.chrimle.example.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface TestFieldExtraAnnotationOne {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
Copyright 2024 Chrimle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package io.github.chrimle.example.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface TestFieldExtraAnnotationTwo {}
9 changes: 8 additions & 1 deletion src/main/resources/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,14 @@ components:
properties:
field1:
type: boolean
description: a boolean field
description: a boolean field with an extra field annotation
x-field-extra-annotation: '@io.github.chrimle.example.annotations.TestFieldExtraAnnotationOne'
field2:
type: boolean
description: a boolean field with two extra field annotations
x-field-extra-annotation: |-
@io.github.chrimle.example.annotations.TestFieldExtraAnnotationOne
@io.github.chrimle.example.annotations.TestFieldExtraAnnotationTwo
ExampleRecordWithTwoExtraAnnotations:
type: object
description: Example of a Record with two extra annotations
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/generateBuilders.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}}{{!
Source: openapi-to-java-records-mustache-templates
Version: 2.3.0
Version: 2.4.0
This template is a custom template, and is used by `pojo.mustache`.
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/javadoc.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}}{{!
Source: openapi-to-java-records-mustache-templates
Version: 2.3.0
Version: 2.4.0
This template is a custom template, and is used by `pojo.mustache` and `modelEnum.mustache`.
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/templates/licenseInfo.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}}{{!
Source: openapi-to-java-records-mustache-templates
Version: 2.3.0
Version: 2.4.0
This template is overriding an official 'openapi-generator-maven-plugin' template.
Expand All @@ -33,6 +33,6 @@
* openapi-to-java-records-mustache-templates. For further information,
* questions, requesting features or reporting issues, please visit:
* https://github.com/Chrimle/openapi-to-java-records-mustache-templates.
* Generated with Version: 2.3.0
* Generated with Version: 2.4.0
*
*/
2 changes: 1 addition & 1 deletion src/main/resources/templates/modelEnum.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}}{{!
Source: openapi-to-java-records-mustache-templates
Version: 2.3.0
Version: 2.4.0
This template is overriding an official 'openapi-generator-maven-plugin' template.
Expand Down
8 changes: 6 additions & 2 deletions src/main/resources/templates/pojo.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}}{{!
Source: openapi-to-java-records-mustache-templates
Version: 2.3.0
Version: 2.4.0
This template is overriding an official 'openapi-generator-maven-plugin' template.
Expand All @@ -34,7 +34,11 @@
}}{{{vendorExtensions.x-class-extra-annotation}}}
{{/vendorExtensions.x-class-extra-annotation}}{{!
}}public record {{classname}}(
{{#vars}}@{{javaxPackage}}.annotation.{{#isNullable}}Nullable{{/isNullable}}{{^isNullable}}Nonnull{{/isNullable}}{{>useBeanValidation}} {{{datatypeWithEnum}}} {{name}}{{^-last}},
{{#vars}}{{!
}}{{#vendorExtensions.x-field-extra-annotation}}{{!
}}{{vendorExtensions.x-field-extra-annotation}}
{{/vendorExtensions.x-field-extra-annotation}}{{!
}}@{{javaxPackage}}.annotation.{{#isNullable}}Nullable{{/isNullable}}{{^isNullable}}Nonnull{{/isNullable}}{{>useBeanValidation}} {{{datatypeWithEnum}}} {{name}}{{^-last}},
{{/-last}}{{/vars}}{{^serializableModel}}){{/serializableModel}}{{#serializableModel}}
) implements Serializable{{/serializableModel}} {
{{>serializableModel}}
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/serializableModel.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}}{{!
Source: openapi-to-java-records-mustache-templates
Version: 2.3.0
Version: 2.4.0
This template is a custom template, and is used by `pojo.mustache`.
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/useBeanValidation.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}}{{!
Source: openapi-to-java-records-mustache-templates
Version: 2.3.0
Version: 2.4.0
This template is a custom template, and is used by `pojo.mustache`.
Expand Down
19 changes: 17 additions & 2 deletions src/test/java/io/github/chrimle/example/models/GeneratedField.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
*/
package io.github.chrimle.example.models;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
Expand All @@ -32,6 +35,7 @@
* @param isCustomClass whether the field should be annotated with {@link jakarta.validation.Valid}
* @param isEmail whether the field should be annotated with {@link
* jakarta.validation.constraints.Email}
* @param enumValue of the enum constant. Meant for enum classes only.
* @param defaultValue of the field. May be inherited from openapi-generator, or be set explicitly
* in the OpenAPI spec.
* @param pattern of the field. Set in the OpenAPI spec.
Expand All @@ -43,6 +47,7 @@
* @param maximum of the field. Set in the OpenAPI spec.
* @param decimalMin of the field. Set in the OpenAPI spec.
* @param decimalMax of the field. Set in the OpenAPI spec.
* @param extraFieldAnnotations of the field. Set in the OpenAPI spec.
* @see Builder for constructing this class with default values
*/
public record GeneratedField<T>(
Expand All @@ -62,7 +67,8 @@ public record GeneratedField<T>(
Optional<Long> minimum,
Optional<Long> maximum,
Optional<String> decimalMin,
Optional<String> decimalMax) {
Optional<String> decimalMax,
List<Class<? extends Annotation>> extraFieldAnnotations) {

public static <T> Builder<T> of(final String name, final Class<T> type) {
return new Builder<>(name, type, null);
Expand Down Expand Up @@ -90,6 +96,7 @@ public static class Builder<T> {
private Optional<Long> maximum = Optional.empty();
private Optional<String> decimalMin = Optional.empty();
private Optional<String> decimalMax = Optional.empty();
private final List<Class<? extends Annotation>> extraFieldAnnotations = new ArrayList<>();

public Builder(final String name, final Class<T> type, final T enumValue) {
this.name = name;
Expand Down Expand Up @@ -172,6 +179,13 @@ public Builder<T> decimalMax(final String decimalMax) {
return this;
}

@SafeVarargs
public final Builder<T> withExtraFieldAnnotations(
final Class<? extends Annotation>... annotations) {
this.extraFieldAnnotations.addAll(List.of(annotations));
return this;
}

public GeneratedField<T> build() {
return new GeneratedField<>(
name,
Expand All @@ -190,7 +204,8 @@ public GeneratedField<T> build() {
minimum,
maximum,
decimalMin,
decimalMax);
decimalMax,
extraFieldAnnotations);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import io.github.chrimle.example.PluginExecution;
import io.github.chrimle.example.annotations.TestExtraAnnotation;
import io.github.chrimle.example.annotations.TestExtraAnnotationTwo;
import io.github.chrimle.example.annotations.TestFieldExtraAnnotationOne;
import io.github.chrimle.example.annotations.TestFieldExtraAnnotationTwo;
import java.lang.annotation.Annotation;
import java.math.BigDecimal;
import java.util.List;
Expand All @@ -43,7 +45,13 @@ public enum GeneratedRecord implements GeneratedClass {
"ExampleRecordWithOneExtraAnnotation",
false,
List.of(TestExtraAnnotation.class),
GeneratedField.of("field1", Boolean.class).build()),
GeneratedField.of("field1", Boolean.class)
.withExtraFieldAnnotations(TestFieldExtraAnnotationOne.class)
.build(),
GeneratedField.of("field2", Boolean.class)
.withExtraFieldAnnotations(
TestFieldExtraAnnotationOne.class, TestFieldExtraAnnotationTwo.class)
.build()),
EXAMPLE_RECORD_WITH_TWO_EXTRA_ANNOTATIONS(
"ExampleRecordWithTwoExtraAnnotations",
false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,7 @@
package io.github.chrimle.example.tests;

import io.github.chrimle.example.GeneratedSource;
import io.github.chrimle.example.annotations.TestAnnotationOne;
import io.github.chrimle.example.annotations.TestAnnotationThree;
import io.github.chrimle.example.annotations.TestAnnotationTwo;
import io.github.chrimle.example.annotations.TestExtraAnnotation;
import io.github.chrimle.example.annotations.TestExtraAnnotationTwo;
import io.github.chrimle.example.annotations.*;
import io.github.chrimle.example.models.GeneratedField;
import io.github.chrimle.example.tests.GeneratedRecordTests.GeneratorConfigurationTests.ConfigOptionsTests;
import io.github.chrimle.example.tests.GeneratedRecordTests.GeneratorConfigurationTests.ConfigOptionsTests.AdditionalModelTypeAnnotationsTests;
Expand All @@ -34,6 +30,7 @@
import io.github.chrimle.example.tests.GeneratedRecordTests.OpenAPITests.SchemaTests.PropertiesTests.PropertyTests;
import io.github.chrimle.example.tests.GeneratedRecordTests.OpenAPITests.SchemaTests.PropertiesTests.PropertyTests.DefaultTests;
import io.github.chrimle.example.tests.GeneratedRecordTests.OpenAPITests.SchemaTests.PropertiesTests.PropertyTests.NullableTests;
import io.github.chrimle.example.tests.GeneratedRecordTests.OpenAPITests.SchemaTests.PropertiesTests.PropertyTests.XFieldExtraAnnotationTests;
import io.github.chrimle.example.tests.GeneratedRecordTests.OpenAPITests.SchemaTests.TypeTests;
import io.github.chrimle.example.tests.GeneratedRecordTests.OpenAPITests.SchemaTests.XClassExtraAnnotationTests;
import io.github.chrimle.example.utils.AssertionUtils;
Expand Down Expand Up @@ -72,6 +69,8 @@
* <li>{@link PropertyTests `components.schemas.{schema}.properties.{property}`}
* <li>{@link NullableTests `components.schemas.{schema}.properties.{property}.nullable`}
* <li>{@link DefaultTests `components.schemas.{schema}.properties.{property}.default`}
* <li>{@link XFieldExtraAnnotationTests
* `components.schemas.{schema}.properties.{property}.x-field-extra-annotation`}
* </ul>
*
* <p><b>`openapi-generator` Configurations</b>
Expand Down Expand Up @@ -283,6 +282,70 @@ public void whenPropertyHasNullableSetThenFieldIsAnnotatedWithNullableOrNonnull(
}
}
}

@Nested
@DisplayName("Testing `{schema}.properties.{property}.x-field-extra-annotation`")
class XFieldExtraAnnotationTests {

@Nested
@DisplayName(
"Testing `{schema}.properties.{property}.x-field-extra-annotation: <null>`")
class XFieldExtraAnnotationUnsetTests {

@ParameterizedTest
@MethodSource(GENERATED_RECORD_TESTS_METHOD_SOURCE)
@DisplayName("Generated `field` is NOT annotated with extra field annotations`")
public void
whenXFieldExtraAnnotationIsUnsetThenFieldIsNotAnnotatedWithExtraFieldAnnotation(
final GeneratedSource generatedSource) {
for (final GeneratedField<?> generatedField : generatedSource.generatedFields()) {
final Field field =
AssertionUtils.assertRecordHasField(
generatedSource.getClassUnderTest(),
generatedField.name(),
generatedField.type());
if (generatedField.extraFieldAnnotations().isEmpty()) {
AssertionUtils.assertDoesNotHaveAnnotation(
generatedSource.getClassUnderTest(),
field,
TestFieldExtraAnnotationOne.class);
AssertionUtils.assertDoesNotHaveAnnotation(
generatedSource.getClassUnderTest(),
field,
TestFieldExtraAnnotationTwo.class);
}
}
}
}

@Nested
@DisplayName(
"Testing `{schema}.properties.{property}.x-field-extra-annotation: @TestFieldExtraAnnotationOne, @TestFieldExtraAnnotationTwo`")
class XFieldExtraAnnotationSetTests {

@ParameterizedTest
@MethodSource(GENERATED_RECORD_TESTS_METHOD_SOURCE)
@DisplayName("Generated `field` is annotated with extra field annotations`")
public void
whenXFieldExtraAnnotationIsSetThenFieldIsAnnotatedWithExtraFieldAnnotation(
final GeneratedSource generatedSource) {
for (final GeneratedField<?> generatedField : generatedSource.generatedFields()) {
final Field field =
AssertionUtils.assertRecordHasField(
generatedSource.getClassUnderTest(),
generatedField.name(),
generatedField.type());
if (!generatedField.extraFieldAnnotations().isEmpty()) {
for (final Class<? extends Annotation> expectedAnnotation :
generatedField.extraFieldAnnotations()) {
AssertionUtils.assertHasAnnotation(
generatedSource.getClassUnderTest(), field, expectedAnnotation);
}
}
}
}
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* openapi-to-java-records-mustache-templates. For further information,
* questions, requesting features or reporting issues, please visit:
* https://github.com/Chrimle/openapi-to-java-records-mustache-templates.
* Generated with Version: 2.3.0
* Generated with Version: 2.4.0
*
*/

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* openapi-to-java-records-mustache-templates. For further information,
* questions, requesting features or reporting issues, please visit:
* https://github.com/Chrimle/openapi-to-java-records-mustache-templates.
* Generated with Version: 2.3.0
* Generated with Version: 2.4.0
*
*/

Expand Down
Loading

0 comments on commit 2d1ea8c

Please sign in to comment.