Skip to content

Commit c6075d4

Browse files
authored
Add support extra annotations for generated code (#1607)
Fixed #1604
1 parent 85ac288 commit c6075d4

File tree

15 files changed

+354
-67
lines changed

15 files changed

+354
-67
lines changed

openapi-generator/src/main/java/io/micronaut/openapi/generator/AbstractMicronautJavaCodegen.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,12 @@
5959
import java.util.stream.Collectors;
6060

6161
import static io.micronaut.openapi.generator.Utils.DEFAULT_BODY_PARAM_NAME;
62+
import static io.micronaut.openapi.generator.Utils.EXT_ANNOTATIONS_CLASS;
63+
import static io.micronaut.openapi.generator.Utils.EXT_ANNOTATIONS_FIELD;
64+
import static io.micronaut.openapi.generator.Utils.EXT_ANNOTATIONS_OPERATION;
65+
import static io.micronaut.openapi.generator.Utils.EXT_ANNOTATIONS_SETTER;
6266
import static io.micronaut.openapi.generator.Utils.addStrValueToEnum;
67+
import static io.micronaut.openapi.generator.Utils.normalizeExtraAnnotations;
6368
import static io.micronaut.openapi.generator.Utils.processGenericAnnotations;
6469
import static org.openapitools.codegen.CodegenConstants.INVOKER_PACKAGE;
6570
import static org.openapitools.codegen.utils.StringUtils.camelize;
@@ -795,6 +800,8 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
795800
|| op.httpMethod.equals("DELETE")
796801
);
797802

803+
normalizeExtraAnnotations(EXT_ANNOTATIONS_OPERATION, false, op.vendorExtensions);
804+
798805
// Set response example
799806
if (op.returnType != null) {
800807
String example;
@@ -1199,6 +1206,7 @@ public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs)
11991206
model.vendorExtensions.put("areRequiredVarsAndReadOnlyVars", !requiredVarsWithoutDiscriminator.isEmpty() && !model.readOnlyVars.isEmpty());
12001207
model.vendorExtensions.put("serialId", random.nextLong());
12011208
model.vendorExtensions.put("withRequiredVars", !model.requiredVars.isEmpty());
1209+
normalizeExtraAnnotations(EXT_ANNOTATIONS_CLASS, false, model.vendorExtensions);
12021210
if (model.discriminator != null) {
12031211
model.vendorExtensions.put("hasMappedModels", !model.discriminator.getMappedModels().isEmpty());
12041212
model.vendorExtensions.put("hasMultipleMappedModels", model.discriminator.getMappedModels().size() > 1);
@@ -1235,6 +1243,9 @@ private void processProperty(CodegenProperty property, boolean isServer, Map<Str
12351243
}
12361244

12371245
processGenericAnnotations(property, useBeanValidation, isGenerateHardNullable(), false, false, false, false);
1246+
1247+
normalizeExtraAnnotations(EXT_ANNOTATIONS_FIELD, false, property.vendorExtensions);
1248+
normalizeExtraAnnotations(EXT_ANNOTATIONS_SETTER, false, property.vendorExtensions);
12381249
}
12391250

12401251
public boolean isGenerateHardNullable() {

openapi-generator/src/main/java/io/micronaut/openapi/generator/AbstractMicronautKotlinCodegen.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,12 @@
6868
import java.util.stream.Collectors;
6969

7070
import static io.micronaut.openapi.generator.Utils.DEFAULT_BODY_PARAM_NAME;
71+
import static io.micronaut.openapi.generator.Utils.EXT_ANNOTATIONS_CLASS;
72+
import static io.micronaut.openapi.generator.Utils.EXT_ANNOTATIONS_FIELD;
73+
import static io.micronaut.openapi.generator.Utils.EXT_ANNOTATIONS_OPERATION;
74+
import static io.micronaut.openapi.generator.Utils.EXT_ANNOTATIONS_SETTER;
7175
import static io.micronaut.openapi.generator.Utils.addStrValueToEnum;
76+
import static io.micronaut.openapi.generator.Utils.normalizeExtraAnnotations;
7277
import static io.micronaut.openapi.generator.Utils.processGenericAnnotations;
7378
import static org.openapitools.codegen.CodegenConstants.INVOKER_PACKAGE;
7479
import static org.openapitools.codegen.languages.KotlinClientCodegen.DATE_LIBRARY;
@@ -790,6 +795,8 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
790795
|| op.httpMethod.equals("DELETE")
791796
);
792797

798+
normalizeExtraAnnotations(EXT_ANNOTATIONS_OPERATION, true, op.vendorExtensions);
799+
793800
// Set response example
794801
if (op.returnType != null) {
795802
String example;
@@ -1300,6 +1307,7 @@ public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs)
13001307
model.vendorExtensions.put("optionalVars", optionalVars);
13011308
model.vendorExtensions.put("serialId", random.nextLong());
13021309
model.vendorExtensions.put("withRequiredVars", !model.requiredVars.isEmpty());
1310+
normalizeExtraAnnotations(EXT_ANNOTATIONS_CLASS, true, model.vendorExtensions);
13031311
if (model.discriminator != null) {
13041312
model.vendorExtensions.put("hasMappedModels", !model.discriminator.getMappedModels().isEmpty());
13051313
model.discriminator.getVendorExtensions().put("hasMappedModels", !model.discriminator.getMappedModels().isEmpty());
@@ -1335,6 +1343,9 @@ private void processProperty(CodegenProperty property, boolean isServer, Codegen
13351343

13361344
processGenericAnnotations(property, useBeanValidation, false, property.isNullable || property.isDiscriminator,
13371345
property.required, property.isReadOnly, true);
1346+
1347+
normalizeExtraAnnotations(EXT_ANNOTATIONS_FIELD, true, property.vendorExtensions);
1348+
normalizeExtraAnnotations(EXT_ANNOTATIONS_SETTER, true, property.vendorExtensions);
13381349
}
13391350

13401351
private void processParentModel(CodegenModel model, List<CodegenProperty> requiredVarsWithoutDiscriminator,

openapi-generator/src/main/java/io/micronaut/openapi/generator/Utils.java

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,16 @@
1515
*/
1616
package io.micronaut.openapi.generator;
1717

18-
import java.util.List;
19-
import java.util.Map;
20-
2118
import org.apache.commons.lang3.StringUtils;
2219
import org.openapitools.codegen.CodegenModel;
2320
import org.openapitools.codegen.CodegenParameter;
2421
import org.openapitools.codegen.CodegenProperty;
2522

23+
import java.util.ArrayList;
24+
import java.util.Collection;
25+
import java.util.List;
26+
import java.util.Map;
27+
2628
/**
2729
* Utilities methods to generators.
2830
*
@@ -31,6 +33,10 @@
3133
public final class Utils {
3234

3335
public static final String DEFAULT_BODY_PARAM_NAME = "requestBody";
36+
public static final String EXT_ANNOTATIONS_OPERATION = "x-operation-extra-annotation";
37+
public static final String EXT_ANNOTATIONS_CLASS = "x-class-extra-annotation";
38+
public static final String EXT_ANNOTATIONS_FIELD = "x-field-extra-annotation";
39+
public static final String EXT_ANNOTATIONS_SETTER = "x-setter-extra-annotation";
3440

3541
private Utils() {
3642
}
@@ -40,15 +46,15 @@ public static void processGenericAnnotations(CodegenParameter parameter, boolean
4046
CodegenProperty items = parameter.isMap ? parameter.additionalProperties : parameter.items;
4147
String datatypeWithEnum = parameter.datatypeWithEnum == null ? parameter.dataType : parameter.datatypeWithEnum;
4248
processGenericAnnotations(parameter.dataType, datatypeWithEnum, parameter.isMap, parameter.containerTypeMapped,
43-
items, parameter.vendorExtensions, useBeanValidation, isGenerateHardNullable, isNullable, isRequired, isReadonly, withNullablePostfix);
49+
items, parameter.vendorExtensions, useBeanValidation, isGenerateHardNullable, isNullable, isRequired, isReadonly, withNullablePostfix);
4450
}
4551

4652
public static void processGenericAnnotations(CodegenProperty property, boolean useBeanValidation, boolean isGenerateHardNullable,
4753
boolean isNullable, boolean isRequired, boolean isReadonly, boolean withNullablePostfix) {
4854
CodegenProperty items = property.isMap ? property.additionalProperties : property.items;
4955
String datatypeWithEnum = property.datatypeWithEnum == null ? property.dataType : property.datatypeWithEnum;
5056
processGenericAnnotations(property.dataType, datatypeWithEnum, property.isMap, property.containerTypeMapped,
51-
items, property.vendorExtensions, useBeanValidation, isGenerateHardNullable, isNullable, isRequired, isReadonly, withNullablePostfix);
57+
items, property.vendorExtensions, useBeanValidation, isGenerateHardNullable, isNullable, isRequired, isReadonly, withNullablePostfix);
5258
}
5359

5460
public static void processGenericAnnotations(String dataType, String dataTypeWithEnum, boolean isMap, String containerType, CodegenProperty itemsProp, Map<String, Object> ext,
@@ -203,8 +209,9 @@ private static boolean isPrimitive(String type) {
203209
return false;
204210
}
205211
return switch (type) {
206-
case "array", "string", "boolean", "byte", "uri", "url", "uuid", "email", "integer", "long", "float", "double",
207-
"number", "partial-time", "date", "date-time", "bigdecimal", "biginteger" -> true;
212+
case "array", "string", "boolean", "byte", "uri", "url", "uuid", "email", "integer", "long", "float",
213+
"double",
214+
"number", "partial-time", "date", "date-time", "bigdecimal", "biginteger" -> true;
208215
default -> false;
209216
};
210217
}
@@ -237,8 +244,8 @@ public static void addStrValueToEnum(List<Object> enumVars, boolean isNumeric) {
237244
}
238245
var upperValue = value.toUpperCase();
239246
if (upperValue.endsWith("F")
240-
|| upperValue.endsWith("L")
241-
|| upperValue.endsWith("D")) {
247+
|| upperValue.endsWith("L")
248+
|| upperValue.endsWith("D")) {
242249
value = value.substring(0, value.length() - 1);
243250
}
244251
if (!value.contains("\"")) {
@@ -255,4 +262,44 @@ public static String toApiName(String name, String prefix, String suffix) {
255262
}
256263
return prefix + name + suffix;
257264
}
265+
266+
public static void normalizeExtraAnnotations(String extName, boolean isKotlin, Map<String, Object> vendorExtensions) {
267+
268+
var ext = vendorExtensions.get(extName);
269+
if (ext == null) {
270+
return;
271+
}
272+
273+
var prefix = "@";
274+
if (isKotlin) {
275+
if (extName.equals(EXT_ANNOTATIONS_FIELD)) {
276+
prefix = "@field:";
277+
} else if (extName.equals(EXT_ANNOTATIONS_SETTER)) {
278+
prefix = "@set:";
279+
}
280+
}
281+
282+
if (ext instanceof Collection<?> annotations) {
283+
ext = normalizeExtraAnnotations(prefix, annotations);
284+
} else if (ext instanceof String annotationStr) {
285+
ext = normalizeExtraAnnotation(prefix, annotationStr);
286+
}
287+
288+
vendorExtensions.put(extName, ext);
289+
}
290+
291+
private static List<String> normalizeExtraAnnotations(String prefix, Collection<?> annotations) {
292+
if (annotations == null || annotations.isEmpty()) {
293+
return null;
294+
}
295+
var result = new ArrayList<String>(annotations.size());
296+
for (var annotation : annotations) {
297+
result.add(normalizeExtraAnnotation(prefix, annotation.toString()));
298+
}
299+
return result;
300+
}
301+
302+
private static String normalizeExtraAnnotation(String prefix, String annotationStr) {
303+
return prefix + (annotationStr.startsWith("@") ? annotationStr.substring(1) : annotationStr);
304+
}
258305
}

openapi-generator/src/main/resources/templates/java-micronaut/client/api.mustache

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ public interface {{classname}} {
7171
{{/authMethods}}
7272
{{/configureAuth}}
7373
{{!the method definition}}
74+
{{#vendorExtensions.x-operation-extra-annotation}}
75+
{{{.}}}
76+
{{/vendorExtensions.x-operation-extra-annotation}}
7477
{{^returnType}}void{{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}} {{nickname}}({{#allParams}}
7578
{{#formatSingleLine}}{{>client/params/queryParams}}{{>client/params/pathParams}}{{>client/params/headerParams}}{{>client/params/bodyParams}}{{>client/params/formParams}}{{>client/params/cookieParams}}{{^-last}},{{/-last}}{{/formatSingleLine}}
7679
{{/allParams}});

openapi-generator/src/main/resources/templates/java-micronaut/common/model/pojo.mustache

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
{{/micronaut_serde_jackson}}
5050
{{/useBeanValidation}}
5151
{{#vendorExtensions.x-class-extra-annotation}}
52-
{{{vendorExtensions.x-class-extra-annotation}}}
52+
{{{.}}}
5353
{{/vendorExtensions.x-class-extra-annotation}}
5454
{{!Declare the class with extends and implements}}
5555
public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#vendorExtensions.x-implements}}{{#-first}}implements {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{#-last}} {{/-last}}{{/vendorExtensions.x-implements}}{
@@ -110,7 +110,7 @@ public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#vendorE
110110
{{/jackson}}
111111
{{/vendorExtensions.x-is-jackson-optional-nullable}}
112112
{{#vendorExtensions.x-field-extra-annotation}}
113-
{{{vendorExtensions.x-field-extra-annotation}}}
113+
{{{.}}}
114114
{{/vendorExtensions.x-field-extra-annotation}}
115115
{{#vendorExtensions.x-is-jackson-optional-nullable}}
116116
{{#isContainer}}
@@ -173,7 +173,7 @@ public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#vendorE
173173
* @return the {{name}} property value
174174
*/
175175
{{#vendorExtensions.x-extra-annotation}}
176-
{{{vendorExtensions.x-extra-annotation}}}
176+
{{{.}}}
177177
{{/vendorExtensions.x-extra-annotation}}
178178
public {{{datatypeWithEnum}}} {{getter}}() {
179179
{{#vendorExtensions.x-is-jackson-optional-nullable}}
@@ -219,7 +219,7 @@ public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#vendorE
219219
* Set the {{name}} property value
220220
*/
221221
{{#vendorExtensions.x-setter-extra-annotation}}
222-
{{{vendorExtensions.x-setter-extra-annotation}}}
222+
{{{.}}}
223223
{{/vendorExtensions.x-setter-extra-annotation}}
224224
public void {{setter}}({{{datatypeWithEnum}}} {{name}}) {
225225
{{#vendorExtensions.x-is-jackson-optional-nullable}}

openapi-generator/src/main/resources/templates/java-micronaut/server/controller-interface.mustache

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ public interface {{classname}} {
7272
@Secured({{#vendorExtensions.x-roles.1}}{{openbrace}}{{/vendorExtensions.x-roles.1}}{{#vendorExtensions.x-roles}}{{{.}}}{{^-last}}, {{/-last}}{{/vendorExtensions.x-roles}}{{#vendorExtensions.x-roles.1}}{{closebrace}}{{/vendorExtensions.x-roles.1}})
7373
{{/useAuth}}
7474
{{!the method definition}}
75+
{{#vendorExtensions.x-operation-extra-annotation}}
76+
{{{.}}}
77+
{{/vendorExtensions.x-operation-extra-annotation}}
7578
{{^returnType}}void{{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}} {{nickname}}({{#allParams}}
7679
{{#formatSingleLine}}{{>server/params/annotations}}{{#indent}}{{>common/params/validation}}{{/indent}}{{>server/params/type}} {{paramName}}{{^-last}},{{/-last}}{{/formatSingleLine}}
7780
{{/allParams}});

openapi-generator/src/main/resources/templates/kotlin-micronaut/client/api.mustache

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ interface {{classname}} {
6363
{{/authMethods}}
6464
{{/configureAuth}}
6565
{{!the method definition}}
66+
{{#vendorExtensions.x-operation-extra-annotation}}
67+
{{{.}}}
68+
{{/vendorExtensions.x-operation-extra-annotation}}
6669
fun {{nickname}}({{#allParams}}
6770
{{#formatSingleLine}}{{>client/params/queryParams}}{{>client/params/pathParams}}{{>client/params/headerParams}}{{>client/params/bodyParams}}{{>client/params/formParams}}{{>client/params/cookieParams}}{{^-last}},{{/-last}}{{/formatSingleLine}}
6871
{{/allParams}}){{#returnType}}: {{{returnType}}}{{/returnType}}

openapi-generator/src/main/resources/templates/kotlin-micronaut/common/model/field_annotations.mustache

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,10 @@
3131
{{#jackson}}
3232
{{>common/model/jackson_annotations}}
3333
{{/jackson}}
34-
{{/vendorExtensions.x-is-jackson-optional-nullable}}
34+
{{/vendorExtensions.x-is-jackson-optional-nullable}}
35+
{{#vendorExtensions.x-field-extra-annotation}}
36+
{{{.}}}
37+
{{/vendorExtensions.x-field-extra-annotation}}
38+
{{#vendorExtensions.x-setter-extra-annotation}}
39+
{{{.}}}
40+
{{/vendorExtensions.x-setter-extra-annotation}}

openapi-generator/src/main/resources/templates/kotlin-micronaut/common/model/pojo.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
{{/micronaut_serde_jackson}}
4444
{{/useBeanValidation}}
4545
{{#vendorExtensions.x-class-extra-annotation}}
46-
{{{vendorExtensions.x-class-extra-annotation}}}
46+
{{{.}}}
4747
{{/vendorExtensions.x-class-extra-annotation}}
4848
{{/formatNoEmptyLines}}
4949
{{!Declare the class with extends and implements}}

openapi-generator/src/main/resources/templates/kotlin-micronaut/server/controller-interface.mustache

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ interface {{classname}} {
6161
@Secured({{#vendorExtensions.x-roles}}{{{.}}}{{^-last}}, {{/-last}}{{/vendorExtensions.x-roles}})
6262
{{/useAuth}}
6363
{{!the method definition}}
64+
{{#vendorExtensions.x-operation-extra-annotation}}
65+
{{{.}}}
66+
{{/vendorExtensions.x-operation-extra-annotation}}
6467
fun {{nickname}}({{#allParams}}
6568
{{#formatSingleLine}}{{>server/params/annotations}}{{#indent}}{{>common/params/validation}}{{/indent}}{{#isDateTime}}{{#dateFormat}}@Format("{{{datetimeFormat}}}"){{/dateFormat}}{{/isDateTime}}{{#isDate}}{{#dateTimeFormat}}@Format("{{{dateFormat}}}"){{/dateTimeFormat}}{{/isDate}} {{{paramName}}}: {{#isEnum}}{{{vendorExtensions.typeWithEnumWithGenericAnnotations}}}{{/isEnum}}{{^isEnum}}{{{vendorExtensions.typeWithGenericAnnotations}}}{{/isEnum}}{{^-last}},{{/-last}}{{/formatSingleLine}}
6669
{{/allParams}}){{#returnType}}: {{{returnType}}}{{/returnType}}

0 commit comments

Comments
 (0)