Skip to content

Commit

Permalink
Add Bean Validation @Email annotation to fields with format: email (
Browse files Browse the repository at this point in the history
#224)

Added Bean Validation for `String` fields with the `format` property set to `email`. This property value will annotate the generated field with `@Email`. Requires the `useBeanValidation` configOption to be set to `true`. The `format` property remains optional.
  • Loading branch information
Chrimle authored Nov 18, 2024
1 parent 252ab37 commit 46724a4
Show file tree
Hide file tree
Showing 86 changed files with 184 additions and 98 deletions.
24 changes: 16 additions & 8 deletions 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.1.1</version>
<version>2.2.0</version>
</dependency>
```

Expand Down Expand Up @@ -56,10 +56,9 @@ Place the file(s) in desired directory. Then, in the Maven build configuration,
## Additional Configurations
The generated classes are customizable by using `<configuration>`-properties.

In this example, each generated class will be named with the suffix "DTO", and fields of generated records will be annotated with [Jakarta Bean Validation annotations](https://jakarta.ee/specifications/bean-validation/3.0/jakarta-bean-validation-spec-3.0.html#builtinconstraints).
In this example, each generated class field will be annotated with [Jakarta Bean Validation annotations](https://jakarta.ee/specifications/bean-validation/3.0/jakarta-bean-validation-spec-3.0.html#builtinconstraints).
```xml
<configuration>
<modelNameSuffix>DTO</modelNameSuffix>
<!-- ... more configurations ... -->
<configOptions>
<useBeanValidation>true</useBeanValidation>
Expand Down Expand Up @@ -106,6 +105,7 @@ components:
- height
- ssn
- aliases
- email
- trackingCode
properties:
name:
Expand Down Expand Up @@ -148,6 +148,10 @@ components:
description: Telephone Number
type: string
nullable: true
email:
description: Email Address
type: string
format: email
trackingCode:
description: Tracking code for Web analytics
type: string
Expand Down Expand Up @@ -183,33 +187,36 @@ import ...;
* @param age Age (years)
* @param gender Gender
* @param height Height (m)
* @param legalGuardian PersonDTO
* @param legalGuardian Person
* @param ssn Social Security Number
* @param aliases Known Aliases
* @param telephoneNumber Telephone Number
* @param email Email Address
* @param trackingCode Tracking code for Web analytics
*/
@Deprecated
public record PersonDTO(
public record Person(
@javax.annotation.Nonnull @Valid @NotNull Name name,
@javax.annotation.Nonnull @NotNull @Min(0) @Max(100) Integer age,
@javax.annotation.Nonnull @NotNull GenderEnum gender,
@javax.annotation.Nonnull @NotNull @DecimalMin("0") BigDecimal height,
@javax.annotation.Nonnull @Valid PersonDTO legalGuardian,
@javax.annotation.Nonnull @Valid Person legalGuardian,
@javax.annotation.Nonnull @NotNull @Pattern(regexp = "^\\d{3}-\\d{2}-\\d{4}$") String ssn,
@javax.annotation.Nonnull @NotNull @Size(min = 1, max = 3) Set<String> aliases,
@javax.annotation.Nullable String telephoneNumber,
@javax.annotation.Nonnull @NotNull @Email String email,
@javax.annotation.Nonnull @NotNull @Size(min = 5, max = 50) String trackingCode) {

public PersonDTO(
public Person(
@javax.annotation.Nonnull final Name name,
@javax.annotation.Nonnull final Integer age,
@javax.annotation.Nonnull final GenderEnum gender,
@javax.annotation.Nonnull final BigDecimal height,
@javax.annotation.Nonnull final PersonDTO legalGuardian,
@javax.annotation.Nonnull final Person legalGuardian,
@javax.annotation.Nonnull final String ssn,
@javax.annotation.Nullable final Set<String> aliases,
@javax.annotation.Nullable final String telephoneNumber,
@javax.annotation.Nonnull final String email,
@javax.annotation.Nullable final String trackingCode) {
this.name = name;
this.age = age;
Expand All @@ -219,6 +226,7 @@ public record PersonDTO(
this.ssn = ssn;
this.aliases = Objects.requireNonNullElse(aliases, new LinkedHashSet<>());
this.telephoneNumber = telephoneNumber;
this.email = email;
this.trackingCode = Objects.requireNonNullElse(trackingCode, "utm_source=default");
}

Expand Down
24 changes: 16 additions & 8 deletions 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.1.1</version>
<version>2.2.0</version>
</dependency>
```

Expand Down Expand Up @@ -55,10 +55,9 @@ Place the file(s) in desired directory. Then, in the Maven build configuration,
## Additional Configurations
The generated classes are customizable by using `<configuration>`-properties.

In this example, each generated class will be named with the suffix "DTO", and fields of generated records will be annotated with [Jakarta Bean Validation annotations](https://jakarta.ee/specifications/bean-validation/3.0/jakarta-bean-validation-spec-3.0.html#builtinconstraints).
In this example, each generated class field will be annotated with [Jakarta Bean Validation annotations](https://jakarta.ee/specifications/bean-validation/3.0/jakarta-bean-validation-spec-3.0.html#builtinconstraints).
```xml
<configuration>
<modelNameSuffix>DTO</modelNameSuffix>
<!-- ... more configurations ... -->
<configOptions>
<useBeanValidation>true</useBeanValidation>
Expand Down Expand Up @@ -104,6 +103,7 @@ components:
- height
- ssn
- aliases
- email
- trackingCode
properties:
name:
Expand Down Expand Up @@ -146,6 +146,10 @@ components:
description: Telephone Number
type: string
nullable: true
email:
description: Email Address
type: string
format: email
trackingCode:
description: Tracking code for Web analytics
type: string
Expand Down Expand Up @@ -180,33 +184,36 @@ import ...;
* @param age Age (years)
* @param gender Gender
* @param height Height (m)
* @param legalGuardian PersonDTO
* @param legalGuardian Person
* @param ssn Social Security Number
* @param aliases Known Aliases
* @param telephoneNumber Telephone Number
* @param email Email Address
* @param trackingCode Tracking code for Web analytics
*/
@Deprecated
public record PersonDTO(
public record Person(
@javax.annotation.Nonnull @Valid @NotNull Name name,
@javax.annotation.Nonnull @NotNull @Min(0) @Max(100) Integer age,
@javax.annotation.Nonnull @NotNull GenderEnum gender,
@javax.annotation.Nonnull @NotNull @DecimalMin("0") BigDecimal height,
@javax.annotation.Nonnull @Valid PersonDTO legalGuardian,
@javax.annotation.Nonnull @Valid Person legalGuardian,
@javax.annotation.Nonnull @NotNull @Pattern(regexp = "^\\d{3}-\\d{2}-\\d{4}$") String ssn,
@javax.annotation.Nonnull @NotNull @Size(min = 1, max = 3) Set<String> aliases,
@javax.annotation.Nullable String telephoneNumber,
@javax.annotation.Nonnull @NotNull @Email String email,
@javax.annotation.Nonnull @NotNull @Size(min = 5, max = 50) String trackingCode) {

public PersonDTO(
public Person(
@javax.annotation.Nonnull final Name name,
@javax.annotation.Nonnull final Integer age,
@javax.annotation.Nonnull final GenderEnum gender,
@javax.annotation.Nonnull final BigDecimal height,
@javax.annotation.Nonnull final PersonDTO legalGuardian,
@javax.annotation.Nonnull final Person legalGuardian,
@javax.annotation.Nonnull final String ssn,
@javax.annotation.Nullable final Set<String> aliases,
@javax.annotation.Nullable final String telephoneNumber,
@javax.annotation.Nonnull final String email,
@javax.annotation.Nullable final String trackingCode) {
this.name = name;
this.age = age;
Expand All @@ -216,6 +223,7 @@ public record PersonDTO(
this.ssn = ssn;
this.aliases = Objects.requireNonNullElse(aliases, new LinkedHashSet<>());
this.telephoneNumber = telephoneNumber;
this.email = email;
this.trackingCode = Objects.requireNonNullElse(trackingCode, "utm_source=default");
}

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.1.1</version>
<version>2.2.0</version>

<!-- Project Information -->
<name>OpenAPI to Java records :: Mustache Templates</name>
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ components:
stringRequiredPattern:
type: string
pattern: '^\d{3}-\d{2}-\d{4}$'
stringEmailFormat:
type: string
format: email
stringMinLength:
type: string
minLength: 3
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.1.1
Version: 2.2.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.1.1
Version: 2.2.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.1.1
Version: 2.2.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.1.1
* Generated with Version: 2.2.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.1.1
Version: 2.2.0
This template is overriding an official 'openapi-generator-maven-plugin' template.
Expand Down
2 changes: 1 addition & 1 deletion 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.1.1
Version: 2.2.0
This template is overriding an official 'openapi-generator-maven-plugin' template.
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.1.1
Version: 2.2.0
This template is a custom template, and is used by `pojo.mustache`.
Expand Down
5 changes: 4 additions & 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.1.1
Version: 2.2.0
This template is a custom template, and is used by `pojo.mustache`.
Expand Down Expand Up @@ -102,4 +102,7 @@
}}{{/maximum}}{{!
}}{{/isLong}}{{!
}}{{/isInteger}}{{!
}}{{#isEmail}}{{!
}} @Email{{!
}}{{/isEmail}}{{!
}}{{/useBeanValidation}}
12 changes: 11 additions & 1 deletion src/test/java/com/chrimle/example/GeneratedField.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@
* Represents a generated field, along with additional properties which are expected to be true for
* the field generated by openapi-generator.
*
* @param <T> type of the field. Used for type-safe casting.
* @param name of the field
* @param type of the field
* @param isNullable whether the field should be annotated with {@link jakarta.annotation.Nullable}
* or {@link jakarta.annotation.Nonnull}
* @param isBeanValidationNullable whether the field should be annotated with {@link
* jakarta.validation.constraints.NotNull}
* @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 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 @@ -40,7 +43,6 @@
* @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 <T> type of the field. Used for type-safe casting.
* @see Builder for constructing this class with default values
*/
public record GeneratedField<T>(
Expand All @@ -49,6 +51,7 @@ public record GeneratedField<T>(
boolean isNullable,
boolean isBeanValidationNullable,
boolean isCustomClass,
boolean isEmail,
Optional<T> defaultValue,
Optional<String> pattern,
Optional<Integer> minLength,
Expand All @@ -70,6 +73,7 @@ public static class Builder<T> {
private boolean isNullable = false;
private boolean isBeanValidationNullable = true;
private boolean isCustomClass = false;
private boolean isEmail = false;
private Optional<T> defaultValue = Optional.empty();
private Optional<String> pattern = Optional.empty();
private Optional<Integer> minLength = Optional.empty();
Expand Down Expand Up @@ -101,6 +105,11 @@ public Builder<T> isCustomClass(final boolean isCustomClass) {
return this;
}

public Builder<T> isEmail(final boolean isEmail) {
this.isEmail = isEmail;
return this;
}

public Builder<T> defaultValue(final T defaultValue) {
this.defaultValue = Optional.ofNullable(defaultValue);
return this;
Expand Down Expand Up @@ -158,6 +167,7 @@ public GeneratedField<T> build() {
isNullable,
isBeanValidationNullable,
isCustomClass,
isEmail,
defaultValue,
pattern,
minLength,
Expand Down
1 change: 1 addition & 0 deletions src/test/java/com/chrimle/example/TestSuite.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ private static GeneratedSource getGeneratedSourceForGeneratedClass(
.isBeanValidationNullable(false)
.pattern("^\\d{3}-\\d{2}-\\d{4}$")
.build(),
GeneratedField.of("stringEmailFormat", String.class).isEmail(true).build(),
GeneratedField.of("stringMinLength", String.class).minLength(3).build(),
GeneratedField.of("stringMaxLength", String.class).maxLength(7).build(),
GeneratedField.of("stringMinAndMaxLength", String.class)
Expand Down
7 changes: 7 additions & 0 deletions src/test/java/com/chrimle/example/utils/AssertionUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import jakarta.validation.Valid;
import jakarta.validation.constraints.DecimalMax;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
Expand Down Expand Up @@ -207,6 +208,12 @@ public static void assertRecordHasFieldsOfTypeWithNullableAnnotations(
} else {
assertDoesNotHaveAnnotation(classUnderTest, field, decimalMaxAnnotation);
}
final Class<Email> emailAnnotation = Email.class;
if (generatedField.isEmail()) {
assertHasAnnotation(classUnderTest, field, emailAnnotation);
} else {
assertDoesNotHaveAnnotation(classUnderTest, field, emailAnnotation);
}
}
}
}
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.1.1
* Generated with Version: 2.2.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.1.1
* Generated with Version: 2.2.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.1.1
* Generated with Version: 2.2.0
*
*/

Expand Down
Loading

0 comments on commit 46724a4

Please sign in to comment.