Skip to content

Commit

Permalink
Fixed @Nullable / @NotNull annotations for primitive array (#1920)
Browse files Browse the repository at this point in the history
  • Loading branch information
altro3 authored Jan 2, 2025
1 parent d91827c commit d5457e9
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ public static Pair<CodegenParameter, Set<String>> processMultipartBody(CodegenOp

public static void processGenericAnnotations(CodegenParameter parameter, boolean useBeanValidation, boolean isGenerateHardNullable,
boolean isNullable, boolean isRequired, boolean isReadonly, boolean withNullablePostfix) {
var ext = parameter.vendorExtensions;
if (!ext.containsKey("isPrimitiveArray")) {
ext.put("isPrimitiveArray", isJavaPrimitiveArray(parameter.dataType) || isKotlinPrimitiveArray(parameter.dataType));
}
CodegenProperty items = parameter.isMap ? parameter.additionalProperties : parameter.items;
String datatypeWithEnum = parameter.datatypeWithEnum == null ? parameter.dataType : parameter.datatypeWithEnum;
processGenericAnnotations(parameter.dataType, datatypeWithEnum, parameter.isMap, parameter.containerTypeMapped,
Expand All @@ -113,28 +117,32 @@ public static void processGenericAnnotations(CodegenParameter parameter, boolean

public static void processGenericAnnotations(CodegenProperty property, boolean useBeanValidation, boolean isGenerateHardNullable,
boolean isNullable, boolean isRequired, boolean isReadonly, boolean withNullablePostfix) {
var ext = property.vendorExtensions;
if (!ext.containsKey("isPrimitiveArray")) {
ext.put("isPrimitiveArray", isJavaPrimitiveArray(property.dataType) || isKotlinPrimitiveArray(property.dataType));
}
CodegenProperty items = property.isMap ? property.additionalProperties : property.items;
String datatypeWithEnum = property.datatypeWithEnum == null ? property.dataType : property.datatypeWithEnum;
processGenericAnnotations(property.dataType, datatypeWithEnum, property.isMap, property.containerTypeMapped,
items, property.vendorExtensions, useBeanValidation, isGenerateHardNullable, isNullable, isRequired, isReadonly, withNullablePostfix);
items, ext, useBeanValidation, isGenerateHardNullable, isNullable, isRequired, isReadonly, withNullablePostfix);
}

public static void processGenericAnnotations(String dataType, String dataTypeWithEnum, boolean isMap, String containerType, CodegenProperty itemsProp, Map<String, Object> ext,
boolean useBeanValidation, boolean isGenerateHardNullable, boolean isNullable,
boolean isRequired, boolean isReadonly,
boolean withNullablePostfix) {
String genericAnnotations = null;
dataType = addAnnotationsToPrimitiveArray(dataType, isNullable, isRequired, isReadonly, isGenerateHardNullable);
dataTypeWithEnum = addAnnotationsToPrimitiveArray(dataTypeWithEnum, isNullable, isRequired, isReadonly, isGenerateHardNullable);
var typeWithGenericAnnotations = dataType;
var typeWithEnumWithGenericAnnotations = dataTypeWithEnum;
if (useBeanValidation && itemsProp != null && dataType.contains("<")) {
genericAnnotations = genericAnnotations(itemsProp, isGenerateHardNullable);
processGenericAnnotations(itemsProp, useBeanValidation, isGenerateHardNullable, itemsProp.isNullable, itemsProp.required, itemsProp.isReadOnly, withNullablePostfix);
if (isMap) {
genericAnnotations = genericAnnotations(itemsProp, isGenerateHardNullable);
processGenericAnnotations(itemsProp, useBeanValidation, isGenerateHardNullable, itemsProp.isNullable, itemsProp.required, itemsProp.isReadOnly, withNullablePostfix);
typeWithGenericAnnotations = "Map<String, " + genericAnnotations + itemsProp.vendorExtensions.get("typeWithGenericAnnotations") + ">";
typeWithEnumWithGenericAnnotations = "Map<String, " + genericAnnotations + itemsProp.vendorExtensions.get("typeWithEnumWithGenericAnnotations") + ">";
} else if (containerType != null) {
genericAnnotations = genericAnnotations(itemsProp, isGenerateHardNullable);
processGenericAnnotations(itemsProp, useBeanValidation, isGenerateHardNullable, itemsProp.isNullable, itemsProp.required, itemsProp.isReadOnly, withNullablePostfix);
typeWithGenericAnnotations = containerType + "<" + genericAnnotations + itemsProp.vendorExtensions.get("typeWithGenericAnnotations") + ">";
typeWithEnumWithGenericAnnotations = containerType + "<" + genericAnnotations + itemsProp.vendorExtensions.get("typeWithEnumWithGenericAnnotations") + ">";
}
Expand All @@ -146,10 +154,44 @@ public static void processGenericAnnotations(String dataType, String dataTypeWit
ext.put("typeWithEnumWithGenericAnnotations", typeWithEnumWithGenericAnnotations + (isNullableType ? "?" : ""));
}

private static String addAnnotationsToPrimitiveArray(String dataType, boolean isNullable, boolean isRequired, boolean isReadOnly, boolean isGenerateHardNullable) {
if (!isJavaPrimitiveArray(dataType)) {
return dataType;
}

var type = dataType.substring(0, dataType.indexOf('['));

if (isNullable || !isRequired || isReadOnly) {
if (isGenerateHardNullable) {
return type + " @Nullable(inherited = true) []";
} else {
return type + " @Nullable []";
}
} else {
return type + " @NotNull []";
}
}

private static boolean isJavaPrimitiveArray(String dataType) {
return switch (dataType) {
case "byte[]", "short[]", "int[]", "long[]", "boolean[]", "char[]", "float[]", "double[]" -> true;
default -> false;
};
}

private static boolean isKotlinPrimitiveArray(String dataType) {
return switch (dataType) {
case "ByteArray", "ShortArray", "IntArray", "LongArray", "BooleanArray", "CharArray", "FloatArray", "DoubleArray" -> true;
default -> false;
};
}

private static String genericAnnotations(CodegenProperty prop, boolean isGenerateHardNullable) {

var type = prop.openApiType == null ? null : prop.openApiType.toLowerCase();

var isPrimitiveArray = isJavaPrimitiveArray(prop.dataType) || isKotlinPrimitiveArray(prop.dataType);

var result = new StringBuilder();

if (prop.isModel) {
Expand Down Expand Up @@ -227,7 +269,7 @@ private static String genericAnnotations(CodegenProperty prop, boolean isGenerat
result.append(") ");
}
}
if (!(Boolean) prop.vendorExtensions.get("isPrimitive")) {
if (!isPrimitiveArray && !(Boolean) prop.vendorExtensions.get("isPrimitive")) {
if (prop.isNullable) {
if (isGenerateHardNullable) {
result.append("@Nullable(inherited = true) ");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

{{^vendorExtensions.isPrimitiveArray}}
{{#isNullable}}
{{#generateHardNullable}}
@Nullable(inherited = true)
Expand Down Expand Up @@ -32,15 +32,18 @@
{{/generateHardNullable}}
{{/required}}
{{/isNullable}}
{{/vendorExtensions.isPrimitiveArray}}
{{!All the validation}}
{{#useBeanValidation}}
{{^vendorExtensions.isPrimitiveArray}}
{{^isNullable}}
{{#required}}
{{^isReadOnly}}
@NotNull{{#vendorExtensions.x-not-null-message}}(message = "{{{.}}}"){{/vendorExtensions.x-not-null-message}}
{{/isReadOnly}}
{{/required}}
{{/isNullable}}
{{/vendorExtensions.isPrimitiveArray}}
{{!Validate all pojos and enums}}
{{^isUuid}}
{{^isContainer}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

{{^vendorExtensions.isPrimitiveArray}}
{{#isNullable}}
@Nullable
{{/isNullable}}
Expand All @@ -12,15 +13,18 @@
@Nullable
{{/required}}
{{/isNullable}}
{{/vendorExtensions.isPrimitiveArray}}
{{!All the validation}}
{{#useBeanValidation}}
{{^vendorExtensions.isPrimitiveArray}}
{{^isNullable}}
{{#required}}
{{^isReadOnly}}
@NotNull{{#vendorExtensions.x-not-null-message}}(message = "{{{.}}}"){{/vendorExtensions.x-not-null-message}}
{{/isReadOnly}}
{{/required}}
{{/isNullable}}
{{/vendorExtensions.isPrimitiveArray}}
{{!Validate all pojos and enums}}
{{^isUuid}}
{{^isContainer}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

{{^vendorExtensions.isPrimitiveArray}}
{{#isNullable}}
@{{{vendorExtensions.fieldAnnPrefix}}}Nullable
{{/isNullable}}
Expand All @@ -12,15 +13,18 @@
@{{{vendorExtensions.fieldAnnPrefix}}}Nullable
{{/required}}
{{/isNullable}}
{{/vendorExtensions.isPrimitiveArray}}
{{!All the validation}}
{{#useBeanValidation}}
{{^vendorExtensions.isPrimitiveArray}}
{{^isNullable}}
{{#required}}
{{^isReadOnly}}
@{{{vendorExtensions.fieldAnnPrefix}}}NotNull{{#vendorExtensions.x-not-null-message}}(message = "{{{.}}}"){{/vendorExtensions.x-not-null-message}}
{{/isReadOnly}}
{{/required}}
{{/isNullable}}
{{/vendorExtensions.isPrimitiveArray}}
{{!Validate all pojos and enums}}
{{^isUuid}}
{{^isContainer}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ Mono<HttpResponse<Void>> myOp(
@Produces("multipart/form-data")
Mono<HttpResponse<Void>> myOp_1(
@Nullable @Valid Coordinates coordinates,
@Nullable byte[] file
byte @Nullable [] file
);
""",
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,7 @@ fun myOp(
@Produces("multipart/form-data")
fun myOp_1(
@Nullable @Valid coordinates: Coordinates? = null,
@Nullable file: ByteArray? = null,
file: ByteArray? = null,
): Mono<HttpResponse<Void>>
""",
"""
Expand Down

0 comments on commit d5457e9

Please sign in to comment.