Skip to content

[java][spring] Process fields of POJOs recursively #19630

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 64 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
4cc2ae3
1) Implement recursive processing
DatApplePy Sep 17, 2024
bbff5e9
Rework generation of variables and methods
DatApplePy Sep 17, 2024
6b81f06
Exclude date and dateTime
DatApplePy Sep 17, 2024
91e02c8
Loosen the generation of NotNull
DatApplePy Sep 17, 2024
2d183e8
Merge branch 'refs/heads/master' into fix_issue_19601
DatApplePy Sep 17, 2024
942aced
1) Change restriction of NotNull 2) add @Valid if the schema is a model
DatApplePy Sep 20, 2024
e7966f2
Collapse it into one line to generate readable code
DatApplePy Sep 20, 2024
003b5ed
Generate annotations for fields
DatApplePy Sep 20, 2024
6d682e7
Introduce vendorTags to define custom validation error messages
DatApplePy Sep 20, 2024
132352f
Fix issues caused by the changes
DatApplePy Sep 20, 2024
b913813
1) Add newly introduced vendor tags to the documentation
DatApplePy Sep 20, 2024
e2d64ea
Merge branch 'refs/heads/master' into fix_issue_19601
DatApplePy Sep 20, 2024
1a6572f
Update samples
DatApplePy Sep 24, 2024
bd5f4cf
Add new tags to VendorExtension
DatApplePy Sep 24, 2024
81631ed
Revert spring.md and add new vendor tags
DatApplePy Sep 24, 2024
e632b94
Add new vendor tags to supported extensions
DatApplePy Sep 24, 2024
b9b0de0
Update docs
DatApplePy Sep 24, 2024
3e496c0
Update java camel samples
DatApplePy Sep 24, 2024
b5ae78b
Fix git diff
DatApplePy Sep 24, 2024
aaaa906
Update pojo.mustache based on Spring pojo.mustache
DatApplePy Sep 24, 2024
6971193
Update Java Camel samples
DatApplePy Sep 24, 2024
66b7e24
Changes in javaBuilder to use nullableDataType template
DatApplePy Sep 25, 2024
e194ab3
Update Spring samples
DatApplePy Sep 25, 2024
32de2e1
Revert "Update Spring samples"
DatApplePy Sep 28, 2024
a941255
Revert "Update Java Camel samples"
DatApplePy Sep 28, 2024
0a653fc
Revert "Fix git diff"
DatApplePy Sep 28, 2024
86ffc1e
Revert "Update java camel samples"
DatApplePy Sep 28, 2024
12296dc
Revert "Update docs"
DatApplePy Sep 28, 2024
19e87ab
Revert "Revert spring.md and add new vendor tags"
DatApplePy Sep 28, 2024
6015911
Revert "Update samples"
DatApplePy Sep 28, 2024
a8d0d8a
Revert "1) Add newly introduced vendor tags to the documentation"
DatApplePy Sep 28, 2024
50b9d14
Add extension for `@NotNull` and remove extension for `@DecimalMin` a…
DatApplePy Sep 28, 2024
de3f970
Rework abstraction for getTypeDeclaration (explanation in PR comment)
DatApplePy Sep 28, 2024
4290634
Rework generation of request parameters and response
DatApplePy Sep 28, 2024
21b79df
Fix minor issues caused by changes and refactor som of the cases
DatApplePy Sep 28, 2024
40414fd
Regenerate samples
DatApplePy Sep 28, 2024
36abb34
Regenerate samples
DatApplePy Sep 28, 2024
248fb3a
Regenerate docs
DatApplePy Sep 28, 2024
bd4cd66
Revert "Regenerate samples"
DatApplePy Oct 3, 2024
c520cfe
Revert "Regenerate samples"
DatApplePy Oct 3, 2024
3d8fdb8
Regenerate samples
DatApplePy Oct 3, 2024
e209bfe
Use responseType template
DatApplePy Oct 3, 2024
82a5edd
Remove use of datatypeWithEnum
DatApplePy Oct 3, 2024
c180170
Add `isResolvedEnum` as condition
DatApplePy Oct 6, 2024
6fd9c98
Add new attribute (isResolvedEnum)
DatApplePy Oct 6, 2024
7990f3a
Implement `clone` method
DatApplePy Oct 6, 2024
83a797b
Rework `clone` method to create real deep copy
DatApplePy Oct 6, 2024
ea43ca3
Wiring the use of `isResolvedEnum`
DatApplePy Oct 6, 2024
1aa9ccd
Revert "Regenerate samples"
DatApplePy Oct 6, 2024
4de6a82
Regenerate Spring samples
DatApplePy Oct 6, 2024
58a9c20
Regenerate Java samples
DatApplePy Oct 6, 2024
27ff736
Merge branch 'refs/heads/master' into fix_issue_19601
DatApplePy Oct 6, 2024
e292493
Regenerate Spring samples
DatApplePy Oct 7, 2024
c52e148
Refactor the implementation of OptionalFeatures
DatApplePy Oct 8, 2024
5ffee39
Handling the generation of Optional for default values
DatApplePy Oct 8, 2024
2a8a1fc
Fix: due to deep copying the `CodegenProperty` classes, `items` and `…
DatApplePy Oct 8, 2024
2437a1a
Revert "Fix: due to deep copying the `CodegenProperty` classes, `item…
DatApplePy Oct 10, 2024
b6809ae
Fix deep copying of Map fields using ObjectMapper
DatApplePy Oct 10, 2024
05328a2
Merge branch 'refs/heads/master' into fix_issue_19601
DatApplePy Oct 10, 2024
32a607e
Reapply "Fix: due to deep copying the `CodegenProperty` classes, `ite…
DatApplePy Oct 10, 2024
880f4ad
Add missing `vendorExtensions` prefix
DatApplePy Oct 11, 2024
74e6bd5
Tiny refactor
DatApplePy Oct 11, 2024
ad8ff51
Rename `x-min-message` and `x-max-message` to match OpenAPI Spec prop…
DatApplePy Oct 11, 2024
4dd6e51
Update docs
DatApplePy Oct 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 5 additions & 1 deletion docs/generators/java-camel.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,11 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|x-operation-extra-annotation|List of custom annotations to be added to operation|OPERATION|null
|x-spring-paginated|Add org.springframework.data.domain.Pageable to controller method. Can be used to handle page & size query parameters|OPERATION|false
|x-version-param|Marker property that tells that this parameter would be used for endpoint versioning. Applicable for headers & query params. true/false|OPERATION_PARAMETER|null
|x-pattern-message|Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null
|x-not-null-message|Add this property whenever you need to customize the validation error message for required field|FIELD, OPERATION_PARAMETER|null
|x-pattern-message|Add this property whenever you need to customize the validation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null
|x-size-message|Add this property whenever you need to customize the validation error message for the size of a variable (can be applied along with `minLength`, `maxLength`, `minItems`, `maxItems`)|FIELD, OPERATION_PARAMETER|null
|x-minimum-message|Add this property whenever you need to customize the validation error message for the minimum of a number|FIELD, OPERATION_PARAMETER|null
|x-maximum-message|Add this property whenever you need to customize the validation error message for the maximum of a number|FIELD, OPERATION_PARAMETER|null


## IMPORT MAPPING
Expand Down
6 changes: 5 additions & 1 deletion docs/generators/kotlin-spring.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,11 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|x-content-type|Specify custom value for 'Content-Type' header for operation|OPERATION|null
|x-discriminator-value|Used with model inheritance to specify value for discriminator that identifies current model|MODEL|
|x-field-extra-annotation|List of custom annotations to be added to property|FIELD, OPERATION_PARAMETER|null
|x-pattern-message|Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null
|x-not-null-message|Add this property whenever you need to customize the validation error message for required field|FIELD, OPERATION_PARAMETER|null
|x-pattern-message|Add this property whenever you need to customize the validation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null
|x-size-message|Add this property whenever you need to customize the validation error message for the size of a variable (can be applied along with `minLength`, `maxLength`, `minItems`, `maxItems`)|FIELD, OPERATION_PARAMETER|null
|x-minimum-message|Add this property whenever you need to customize the validation error message for the minimum of a number|FIELD, OPERATION_PARAMETER|null
|x-maximum-message|Add this property whenever you need to customize the validation error message for the maximum of a number|FIELD, OPERATION_PARAMETER|null


## IMPORT MAPPING
Expand Down
6 changes: 5 additions & 1 deletion docs/generators/spring.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,11 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|x-operation-extra-annotation|List of custom annotations to be added to operation|OPERATION|null
|x-spring-paginated|Add org.springframework.data.domain.Pageable to controller method. Can be used to handle page & size query parameters|OPERATION|false
|x-version-param|Marker property that tells that this parameter would be used for endpoint versioning. Applicable for headers & query params. true/false|OPERATION_PARAMETER|null
|x-pattern-message|Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null
|x-not-null-message|Add this property whenever you need to customize the validation error message for required field|FIELD, OPERATION_PARAMETER|null
|x-pattern-message|Add this property whenever you need to customize the validation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null
|x-size-message|Add this property whenever you need to customize the validation error message for the size of a variable (can be applied along with `minLength`, `maxLength`, `minItems`, `maxItems`)|FIELD, OPERATION_PARAMETER|null
|x-minimum-message|Add this property whenever you need to customize the validation error message for the minimum of a number|FIELD, OPERATION_PARAMETER|null
|x-maximum-message|Add this property whenever you need to customize the validation error message for the maximum of a number|FIELD, OPERATION_PARAMETER|null


## IMPORT MAPPING
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import java.util.*;

@Getter @Setter
public class CodegenComposedSchemas {
public class CodegenComposedSchemas implements Cloneable {
private List<CodegenProperty> allOf;
private List<CodegenProperty> oneOf;
private List<CodegenProperty> anyOf;
Expand Down Expand Up @@ -59,4 +59,35 @@ public boolean equals(Object o) {
public int hashCode() {
return Objects.hash(oneOf, anyOf, allOf, not);
}

@Override
public CodegenComposedSchemas clone() {
try {
CodegenComposedSchemas ccs = (CodegenComposedSchemas) super.clone();
if (allOf != null) {
ccs.allOf = new ArrayList<>();
for (CodegenProperty prop : this.allOf) {
ccs.allOf.add(prop.clone());
}
}
if (oneOf != null) {
ccs.oneOf = new ArrayList<>();
for (CodegenProperty prop : this.oneOf) {
ccs.oneOf.add(prop.clone());
}
}
if (anyOf != null) {
ccs.anyOf = new ArrayList<>();
for (CodegenProperty prop : this.anyOf) {
ccs.anyOf.add(prop.clone());
}
}
if (not != null) {
ccs.not = this.not.clone();
}
return ccs;
} catch (CloneNotSupportedException e) {
throw new IllegalStateException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@

package org.openapitools.codegen;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Getter;
import lombok.Setter;

Expand Down Expand Up @@ -183,6 +187,12 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti
public boolean isEnum; // true if the enum is defined inline
public boolean isInnerEnum; // Enums declared inline will be located inside the generic model, changing how the enum is referenced in some cases.
public boolean isEnumRef; // true if it's a reference to an enum
/**
* This indicates that the enum whether it is inline or referenced can be used as a data type.
* If <code>RESOLVE_INLINE_ENUMS</code> is set to <code>true</code> in `<code>inlineSchemaOptions</code>, in those cases this field is irrelevant.
*
*/
public boolean isResolvedEnum;
public boolean isReadOnly;
public boolean isWriteOnly;
public boolean isNullable;
Expand Down Expand Up @@ -253,6 +263,7 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti
private String format;
private LinkedHashMap<String, List<String>> dependentRequired;
private CodegenProperty contains;
private final ObjectMapper mapper = new ObjectMapper();

@Override
public CodegenProperty getContains() {
Expand Down Expand Up @@ -602,52 +613,170 @@ public String getRef() {
public CodegenProperty clone() {
try {
CodegenProperty cp = (CodegenProperty) super.clone();

// Deep copy in case of mutable objects
if (this._enum != null) {
cp._enum = new ArrayList<String>(this._enum);
cp._enum = new ArrayList<>(this._enum);
}
if (this.allowableValues != null) {
cp.allowableValues = new HashMap<String, Object>(this.allowableValues);
}
if (this.items != null) {
cp.items = this.items;
}
if (this.additionalProperties != null) {
cp.additionalProperties = this.additionalProperties;
cp.allowableValues = mapper.readValue(
mapper.writeValueAsString(this.allowableValues),
new TypeReference<>() {});
}
if (this.vars != null) {
cp.vars = this.vars;
cp.vars = new ArrayList<>();
for (CodegenProperty var : this.vars) {
cp.vars.add(var.clone());
}
}
if (this.requiredVars != null) {
cp.requiredVars = this.requiredVars;
}
if (this.mostInnerItems != null) {
cp.mostInnerItems = this.mostInnerItems;
cp.requiredVars = new ArrayList<>();
for (CodegenProperty var : this.requiredVars) {
cp.requiredVars.add(var.clone());
}
}
if (this.vendorExtensions != null) {
cp.vendorExtensions = new HashMap<String, Object>(this.vendorExtensions);
cp.vendorExtensions = mapper.readValue(
mapper.writeValueAsString(this.vendorExtensions),
new TypeReference<>() {});
}
if (this.composedSchemas != null) {
cp.composedSchemas = this.composedSchemas;
if (this.items != null) {
cp.items = this.items.clone();
}
if (this.requiredVarsMap != null) {
cp.setRequiredVarsMap(this.requiredVarsMap);
if (this.additionalProperties != null) {
cp.additionalProperties = this.additionalProperties.clone();
}
if (this.ref != null) {
cp.setRef(this.ref);
if (this.mostInnerItems != null) {
cp.mostInnerItems = this.mostInnerItems.clone();
}
if (this.format != null) {
cp.setFormat(this.format);
if (this.requiredVarsMap != null) {
cp.requiredVarsMap = new HashMap<>();
for (Map.Entry<String, CodegenProperty> entry : this.requiredVarsMap.entrySet()) {
cp.requiredVarsMap.put(entry.getKey(), entry.getValue().clone());
}
}
if (this.dependentRequired != null) {
cp.setDependentRequired(this.dependentRequired);
cp.dependentRequired = mapper.readValue(
mapper.writeValueAsString(this.dependentRequired),
new TypeReference<>() {});
}
if (this.contains != null) {
cp.setContains(this.contains);
if (this.composedSchemas != null) {
cp.composedSchemas = this.composedSchemas.clone();
}

// Immutable objects
cp.openApiType = this.openApiType;
cp.baseName = this.baseName;
cp.complexType = this.complexType;
cp.getter = this.getter;
cp.setter = this.setter;
cp.description = this.description;
cp.dataType = this.dataType;
cp.datatypeWithEnum = this.datatypeWithEnum;
cp.dataFormat = this.dataFormat;
cp.name = this.name;
cp.min = this.min;
cp.max = this.max;
cp.defaultValue = this.defaultValue;
cp.defaultValueWithParam = this.defaultValueWithParam;
cp.baseType = this.baseType;
cp.containerType = this.containerType;
cp.containerTypeMapped = this.containerTypeMapped;
cp.title = this.title;
cp.unescapedDescription = this.unescapedDescription;
cp.maxLength = this.maxLength;
cp.minLength = this.minLength;
cp.pattern = this.pattern;
cp.example = this.example;
cp.jsonSchema = this.jsonSchema;
cp.minimum = this.minimum;
cp.maximum = this.maximum;
cp.multipleOf = this.multipleOf;
cp.exclusiveMinimum = this.exclusiveMinimum;
cp.exclusiveMaximum = this.exclusiveMaximum;
cp.required = this.required;
cp.deprecated = this.deprecated;
cp.hasMoreNonReadOnly = this.hasMoreNonReadOnly;
cp.isPrimitiveType = this.isPrimitiveType;
cp.isModel = this.isModel;
cp.isContainer = this.isContainer;
cp.isString = this.isString;
cp.isNumeric = this.isNumeric;
cp.isInteger = this.isInteger;
cp.isShort = this.isShort;
cp.isLong = this.isLong;
cp.isUnboundedInteger = this.isUnboundedInteger;
cp.isNumber = this.isNumber;
cp.isFloat = this.isFloat;
cp.isDouble = this.isDouble;
cp.isDecimal = this.isDecimal;
cp.isByteArray = this.isByteArray;
cp.isBinary = this.isBinary;
cp.isFile = this.isFile;
cp.isBoolean = this.isBoolean;
cp.isDate = this.isDate;
cp.isDateTime = this.isDateTime;
cp.isUuid = this.isUuid;
cp.isUri = this.isUri;
cp.isEmail = this.isEmail;
cp.isPassword = this.isPassword;
cp.isNull = this.isNull;
cp.isVoid = this.isVoid;
cp.isFreeFormObject = this.isFreeFormObject;
cp.isAnyType = this.isAnyType;
cp.isArray = this.isArray;
cp.isMap = this.isMap;
cp.isOptional = this.isOptional;
cp.isEnum = this.isEnum;
cp.isInnerEnum = this.isInnerEnum;
cp.isEnumRef = this.isEnumRef;
cp.isResolvedEnum = this.isResolvedEnum;
cp.isReadOnly = this.isReadOnly;
cp.isWriteOnly = this.isWriteOnly;
cp.isNullable = this.isNullable;
cp.isSelfReference = this.isSelfReference;
cp.isCircularReference = this.isCircularReference;
cp.isDiscriminator = this.isDiscriminator;
cp.isNew = this.isNew;
cp.isOverridden = this.isOverridden;
cp.hasValidation = this.hasValidation;
cp.isInherited = this.isInherited;
cp.discriminatorValue = this.discriminatorValue;
cp.nameInLowerCase = this.nameInLowerCase;
cp.nameInCamelCase = this.nameInCamelCase;
cp.nameInPascalCase = this.nameInPascalCase;
cp.nameInSnakeCase = this.nameInSnakeCase;
cp.enumName = this.enumName;
cp.maxItems = this.maxItems;
cp.minItems = this.minItems;
cp.maxProperties = this.maxProperties;
cp.minProperties = this.minProperties;
cp.uniqueItems = this.uniqueItems;
cp.uniqueItemsBoolean = this.uniqueItemsBoolean;
cp.isXmlAttribute = this.isXmlAttribute;
cp.xmlPrefix = this.xmlPrefix;
cp.xmlName = this.xmlName;
cp.xmlNamespace = this.xmlNamespace;
cp.isXmlWrapped = this.isXmlWrapped;
cp.additionalPropertiesIsAnyType = this.additionalPropertiesIsAnyType;
cp.hasVars = this.hasVars;
cp.hasRequired = this.hasRequired;
cp.hasDiscriminatorWithNonEmptyMapping = this.hasDiscriminatorWithNonEmptyMapping;
cp.hasMultipleTypes = this.hasMultipleTypes;
cp.hasSanitizedName = this.hasSanitizedName;
cp.ref = this.ref;
cp.schemaIsFromAdditionalProperties = this.schemaIsFromAdditionalProperties;
cp.isBooleanSchemaTrue = this.isBooleanSchemaTrue;
cp.isBooleanSchemaFalse = this.isBooleanSchemaFalse;
cp.format = this.format;
cp.dependentRequired = this.dependentRequired;
cp.contains = this.contains;

return cp;
} catch (CloneNotSupportedException e) {
throw new IllegalStateException(e);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}

Expand Down Expand Up @@ -1025,6 +1154,7 @@ public String toString() {
sb.append(", isEnum=").append(isEnum);
sb.append(", isInnerEnum=").append(isInnerEnum);
sb.append(", isEnumRef=").append(isEnumRef);
sb.append(", isResolvedEnum=").append(isResolvedEnum);
sb.append(", isAnyType=").append(isAnyType);
sb.append(", isReadOnly=").append(isReadOnly);
sb.append(", isWriteOnly=").append(isWriteOnly);
Expand Down Expand Up @@ -1122,6 +1252,7 @@ public boolean equals(Object o) {
isEnum == that.isEnum &&
isInnerEnum == that.isInnerEnum &&
isEnumRef == that.isEnumRef &&
isResolvedEnum == that.isResolvedEnum &&
isAnyType == that.isAnyType &&
isReadOnly == that.isReadOnly &&
isWriteOnly == that.isWriteOnly &&
Expand Down Expand Up @@ -1211,7 +1342,7 @@ public int hashCode() {
hasMoreNonReadOnly, isPrimitiveType, isModel, isContainer, isString, isNumeric,
isInteger, isLong, isNumber, isFloat, isDouble, isDecimal, isByteArray, isBinary, isFile,
isBoolean, isDate, isDateTime, isUuid, isUri, isEmail, isPassword, isFreeFormObject,
isArray, isMap, isOptional, isEnum, isInnerEnum, isEnumRef, isAnyType, isReadOnly, isWriteOnly, isNullable, isShort,
isArray, isMap, isOptional, isEnum, isInnerEnum, isEnumRef, isResolvedEnum, isAnyType, isReadOnly, isWriteOnly, isNullable, isShort,
isUnboundedInteger, isSelfReference, isCircularReference, isDiscriminator, isNew, isOverridden, _enum,
allowableValues, items, mostInnerItems, additionalProperties, vars, requiredVars,
vendorExtensions, hasValidation, isInherited, discriminatorValue, nameInPascalCase, nameInCamelCase,
Expand Down
Loading
Loading